Reputation: 39
I have visual problems with this component I'm developing. It is JPanel
with 2 JTextFields and 2 JLabels. I cannot make solid background. I've tried several opaque/background color combinations but without success.
I'm not allowed to attach images so sample image is here!:
Any help please?
package javaapplication1;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
public class JavaApplication1 {
public static void main(String[] args) {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
}
JFrame testFrame = new JFrame("Test Frame");
testFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JDecimal decimal = new JDecimal();
decimal.setPreferredSize(new Dimension(300, 100));
testFrame.setLayout(null);
testFrame.getContentPane().add(decimal);
decimal.setSize(80, 25);
testFrame.setLocationRelativeTo(null);
testFrame.setSize(300, 200);
testFrame.setVisible(true);
}
public static class JDecimal extends JPanel {
private String currencyString = "00";
private java.text.DecimalFormat format = (java.text.DecimalFormat) java.text.DecimalFormat.getInstance();
JTextField integerField = new JTextField();
JLabel comaLabel = new JLabel();
JTextField fractionField = new JTextField();
JLabel plusMinusLabel = new JLabel();
JDecimalLayout JDecimalLayout = new JDecimalLayout();
public JDecimal() {
init();
}
public String getText() {
return integerField.getText() + "." + fractionField.getText();
}
private void init() {
this.setLayout(JDecimalLayout);
this.add(integerField);
this.add(fractionField);
this.add(comaLabel);
this.add(plusMinusLabel);
integerField.setText("0");
integerField.setHorizontalAlignment(JTextField.RIGHT);
comaLabel.setText(format.getDecimalFormatSymbols().getDecimalSeparator() + "");
fractionField.setText(currencyString);
plusMinusLabel.setText("");
format.setDecimalSeparatorAlwaysShown(true);
// borders
javax.swing.border.Border b = integerField.getBorder();
integerField.setBorder(null);
fractionField.setBorder(null);
comaLabel.setBorder(null);
plusMinusLabel.setBorder(null);
this.setBorder(b);
}
public void reshape() {
invalidate();
validate();
}
private class JDecimalLayout implements java.awt.LayoutManager {
public void addLayoutComponent(String name, Component comp) {
}
public void layoutContainer(Container parent) {
Rectangle r = parent.getBounds();
FontMetrics fm = parent.getFontMetrics(integerField.getFont());
int sirinaSlova = fm.stringWidth("0");
plusMinusLabel.setBounds(new Rectangle(r.width - sirinaSlova - 2, 2, sirinaSlova, r.height - 4));
fractionField.setBounds(new Rectangle(r.width - sirinaSlova - 2 - sirinaSlova * 2, 2, sirinaSlova * 2 + 1, r.height - 4));
comaLabel.setBounds(new Rectangle(r.width - 2 - sirinaSlova - sirinaSlova * 2 - sirinaSlova, 0, sirinaSlova, r.height));
integerField.setBounds(new Rectangle(2, 2, comaLabel.getBounds().x - 2, r.height - 4));
}
public Dimension minimumLayoutSize(Container parent) {
return parent.getPreferredSize();
}
public Dimension preferredLayoutSize(Container parent) {
return parent.getPreferredSize();
}
public void removeLayoutComponent(Component comp) {
}
}
}
}
Upvotes: 2
Views: 337
Reputation: 324147
You can't just set the background of a JLabel because by default it is non-opaque. So you need to do something like:
label.setOpaque(true);
label.setBackground(Color.WHITE);
Upvotes: 5
Reputation: 47607
JPanel
, all you need is to call setBackground()
on it. For example in your init()
, call setBackground(Color.WHITE);
(All JPanel
's are opaque by default)null
layout.setPreferredSize()
anywhereLayoutManager
, in the method preferredLayoutSize()
, you cannot return parent.getPreferredSize();
since it is precisely what needs to be computed (it creates an infinite loop).JFormattedTextField
to achieve the exact same behaviour and with 100 lines less.SwingUtilities.invokeLater
)Anyway, here is a fixed version of your code:
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
public class JavaApplication1 {
public static void main(String[] args) {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame testFrame = new JFrame("Test Frame");
testFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JDecimal decimal = new JDecimal();
testFrame.setLayout(new GridBagLayout());
testFrame.getContentPane().add(decimal, new GridBagConstraints());
testFrame.pack();
testFrame.setLocationRelativeTo(null);
testFrame.setVisible(true);
}
});
}
public static class JDecimal extends JPanel {
private String currencyString = "00";
private java.text.DecimalFormat format = (java.text.DecimalFormat) java.text.DecimalFormat.getInstance();
JTextField integerField = new JTextField();
JLabel comaLabel = new JLabel();
JTextField fractionField = new JTextField();
JLabel plusMinusLabel = new JLabel();
public JDecimal() {
init();
}
public String getText() {
return integerField.getText() + "." + fractionField.getText();
}
private void init() {
this.setLayout(new GridBagLayout());
integerField.setColumns(10);
fractionField.setColumns(2);
this.add(plusMinusLabel, new GridBagConstraints());
this.add(integerField, new GridBagConstraints());
this.add(comaLabel, new GridBagConstraints());
this.add(fractionField, new GridBagConstraints());
integerField.setText("0");
integerField.setHorizontalAlignment(JTextField.RIGHT);
comaLabel.setText(String.valueOf(format.getDecimalFormatSymbols().getDecimalSeparator()));
fractionField.setText(currencyString);
plusMinusLabel.setText(" ");
format.setDecimalSeparatorAlwaysShown(true);
// borders
javax.swing.border.Border b = integerField.getBorder();
integerField.setBorder(null);
fractionField.setBorder(null);
comaLabel.setBorder(null);
plusMinusLabel.setBorder(null);
this.setBorder(b);
setBackground(Color.WHITE);
}
}
}
Upvotes: 4