复合组件背景/透明度

时间:2013-02-02 22:05:39

标签: java swing

我正在开发这个组件的视觉问题。它是JPanel,有2个JTextFields和2个JLabel。我无法建立坚实的背景。我尝试了几种不透明/背景色组合但没有成功。

我不允许附加图片,因此示例图片为here!:

请帮忙吗?

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) {
        }
    }
}

}

2 个答案:

答案 0 :(得分:5)

您不能只设置JLabel的背景,因为默认情况下它是非透明的。所以你需要做一些事情:

label.setOpaque(true); 
label.setBackground(Color.WHITE);

答案 1 :(得分:4)

  1. 要在JPanel上拥有扎实的背景,您只需要在其上调用setBackground()即可。例如,在init()中,请致电setBackground(Color.WHITE);(默认情况下,所有JPanel都是不透明的)
  2. 请勿使用null布局。
  3. 请勿随时致电setPreferredSize()
  4. 如果在方法LayoutManager中实现preferredLayoutSize(),则无法返回parent.getPreferredSize();,因为它正是需要计算的内容(它会创建无限循环)。
  5. 您可以使用JFormattedTextField来实现完全相同的行为,并减少100行。
  6. 始终在EDT中启动您的用户界面(使用SwingUtilities.invokeLater
  7. 无论如何,这是您的代码的固定版本:

    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);
            }
    
        }
    }