java - 将多个面板放入 JFrame 时出现问题

标签 java swing

这是关于同一问题的两个问题。我正在开发一个数字时钟项目,完成后将如下所示:

digital clock

一帧中有 9 个面板。 1 个 TitlePanel 类面板、6 个 DigitPanel 类面板和 2 个 ColonPanel 类面板。我遇到的问题是 DigitPanel 类。我现在编写的代码只显示一个面板,但当我运行程序时,数字面板想要占用整个 JFrame。有人可以告诉我问题是什么吗?

主类:

public class DigitalTimeUI extends JFrame {

    public DigitalTimeUI() {
        JFrame clock = new JFrame("Clock");
        clock.setSize(605, 250);

        clock.setDefaultCloseOperation(EXIT_ON_CLOSE);
        clock.setLocationRelativeTo(null);
        clock.setResizable(false);

        clock.add(new TitlePanel(), BorderLayout.NORTH);
        clock.add(new DigitPane(), BorderLayout.SOUTH);

        clock.pack();
        clock.setVisible(true);
    }

    public class DigitPane extends JPanel {

        DigitPanel[] hourDigit = new DigitPanel[]{new DigitPanel(), new DigitPanel()};
        DigitPanel[] minDigit = new DigitPanel[]{new DigitPanel(), new DigitPanel()};
        DigitPanel[] secDigit = new DigitPanel[]{new DigitPanel(), new DigitPanel()};
        private String hour = pad(Calendar.getInstance().get(Calendar.HOUR));
        private String min = pad(Calendar.getInstance().get(Calendar.MINUTE));
        private String sec = pad(Calendar.getInstance().get(Calendar.SECOND));
        private char[] hours = hour.toCharArray();
        private char[] minutes = min.toCharArray();
        private char[] seconds = sec.toCharArray();

        public DigitPane() {
            JLabel label = new JLabel();
            label.setFont(new Font("Tahoma", Font.BOLD, 72));
            label.setForeground(Color.WHITE);

            JPanel digitsPanel = new JPanel(new GridBagLayout());
            digitsPanel.setSize(new Dimension(605, 100));

            digitsPanel.add(new panelPadding());

            label.setText(String.valueOf(hours[0]));
            hourDigit[0].add(label);
            digitsPanel.add(hourDigit[0]);

            digitsPanel.add(new panelPadding());

            label.setText(String.valueOf(hours[1]));
            hourDigit[1].add(label);
            digitsPanel.add(hourDigit[1]);
            digitsPanel.add(new panelPadding());

            digitsPanel.add(new ColonPanel());
            digitsPanel.add(new panelPadding());

            label.setText(String.valueOf(minutes[0]));
            minDigit[0].add(label);
            digitsPanel.add(minDigit[0]);
            digitsPanel.add(new panelPadding());

            label.setText(String.valueOf(minutes[1]));
            minDigit[1].add(label);
            digitsPanel.add(minDigit[1]);
            digitsPanel.add(new panelPadding());

            digitsPanel.add(new ColonPanel());
            digitsPanel.add(new panelPadding());

            label.setText(String.valueOf(seconds[0]));
            secDigit[0].add(label);
            digitsPanel.add(secDigit[0]);
            digitsPanel.add(new panelPadding());

            label.setText(String.valueOf(seconds[1]));
            secDigit[0].add(label);
            digitsPanel.add(secDigit[1]);
            digitsPanel.add(new panelPadding());

            this.add(digitsPanel);
        }
    }

    protected String pad(int value) {
        StringBuilder sb = new StringBuilder(String.valueOf(value));
        while (sb.length() < 2) {
            sb.insert(0, "0");
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        new DigitalTimeUI();
    }

    public class panelPadding extends JPanel {

        public panelPadding() {
            this.setPreferredSize(new Dimension(5, 80));
        }
    }
}

标题面板:

public class TitlePanel extends JPanel {

    JLabel title;

    public TitlePanel() {
        this.setBackground(Color.WHITE);
        this.setPreferredSize(new Dimension(605, 100));
        this.setLayout(new GridBagLayout());
        title = new JLabel("DIGITAL CLOCK");
        title.setFont(new Font("Tahoma", Font.BOLD, 72));
        title.setForeground(Color.BLACK);
        this.add(title);
    }
}

数字面板:

public class DigitPanel extends JPanel {

    public DigitPanel() {
        this.setLayout(new GridBagLayout());
        this.setPreferredSize(new Dimension(80, 80));
        this.setBackground(Color.BLACK);
    }
}

当我调整大小时,标题面板(无论出于何种原因)不会占据整个框架,但数字面板会占据整个框架,我不知道为什么。我尝试了 .setLocation().setLayout().setSize() 和其他一些方法,但似乎没有任何效果。

这里也许可以回答的第二个问题是,创建每个数字面板的最佳方法是什么?之前我一直在尝试使用 while 循环和 switch 语句,但没有取得任何成果,因为我一直遇到我解决的第一个问题。谢谢。

最佳答案

BorderLayout 有 5 个可以添加组件的不同区域。默认情况下,如果您不指定位置,组件将添加到 CENTER 位置。

在您的代码中,您正在执行此操作...

clock.setLayout(new BorderLayout());
clock.add(new TitlePanel())
clock.add(new DigitPanel()).setLocation(5, 125);

这基本上是将 TitlePane 替换为 DigitalPanel,这意味着 TitlePane 将不会显示。

此外,使用 setLocation 不仅毫无意义(因为面板重新验证后该值将被丢弃),而且也不鼓励使用。

我愿意;

  1. TitlePanel 添加到 NORTH 位置 (clock.add(new TitlePane(), BorderLayout.NORTH)))
  2. 创建另一个 JPanel(类似于 digitsPanel)并设置为使用 GridLayout,类似于 (digitsPanel.setLayout(new GridLayout(1, 8)))。
  3. 将每个 DigitalPane 添加到 digitsPanel(包括冒号)
  4. digitsPanel添加到时钟CENTER位置 - clock.add(digitsPanel)

唯一的问题是每个面板(在 digitsPanel 上)的大小相同。

如果这不能满足您的需求,如果您需要对布局进行更多控制,我建议您使用 FlowLayoutGridBagLayout

已更新

DigitPane[] hourDigit = new DigitPane[]{new DigitPane(), new DigitPane()};
DigitPane[] minDigit = new DigitPane[]{new DigitPane(), new DigitPane()};
DigitPane[] secDigit = new DigitPane[]{new DigitPane(), new DigitPane()};

JPanel digitsPanel = new JPanel(new GridBagLayout());
digitsPanel.add(hourDigit[0]);
digitsPanel.add(hourDigit[1]);
digitsPanel.add(new ColonPane());
digitsPanel.add(minDigit[0]);
digitsPanel.add(minDigit[1]);
digitsPanel.add(new ColonPane());
digitsPanel.add(secDigit[0]);
digitsPanel.add(secDigit[1]);

关于java - 将多个面板放入 JFrame 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15351229/

相关文章:

java - Swing 组件支持哪些 HTML 标签?

java - Eclipse WindowBuilder (swing) - 某些组件无法在代码中访问?

java - JButton settext具体位置

java - Swing : Write in a JLabel

java - 尽管从命令提示符下运行完美,但双击后 jar 文件无法打开

java - 如何为 Axiom XPath 设置变量上下文

java - 如何将图像上传到 Android Studio 中的图像 slider ?

java - C libssh 中的 SSH 客户端用 Java jsch 重写

java - 当应用程序被杀死时警报不会响起

java - 如何下载和使用jface