2

我正在开发的这个组件有视觉问题。它JPanel带有 2 个 JTextField 和 2 个 JLabels。我无法制作坚实的背景。我尝试了几种不透明/背景颜色组合,但没有成功。

我不允许附加图片,所以示例图片在这里!:

请问有什么帮助吗?

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

}

4

2 回答 2

5

您不能只设置 JLabel 的背景,因为默认情况下它是不透明的。因此,您需要执行以下操作:

label.setOpaque(true); 
label.setBackground(Color.WHITE);
于 2013-02-02T23:48:54.177 回答
4
  1. 要在 a 上拥有扎实的背景JPanel,您所需要的只是调用setBackground()它。例如在您的init(), 调用中setBackground(Color.WHITE);(默认情况下所有JPanel都是不透明的)
  2. 不要使用null布局。
  3. 不要setPreferredSize()在任何地方打电话
  4. 如果LayoutManager在方法中实现 a ,preferredLayoutSize()则无法返回,parent.getPreferredSize();因为它正是需要计算的(它会创建一个无限循环)。
  5. 您可以使用 aJFormattedTextField来实现完全相同的行为并且减少 100 行。
  6. 始终在 EDT 中启动您的 UI(使用SwingUtilities.invokeLater

无论如何,这是您的代码的固定版本:

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

    }
}
于 2013-02-02T22:27:12.530 回答