首页 > 解决方案 > 指定顶级容器的 ContentPane 是否有优势?

问题描述

我试图摆脱使用 NetBeans 创建简单的 Swing GUI,从而试图更好地理解整个容器/布局机制。我一直在内联阅读各种内容,尤其是https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html

在下面的示例代码中,我可以看到第二种形式 DialogJPanel() 的优势。仅举一个例子,JPanel 可以被赋予一个边框。我的理解是 JPanel 实际上被添加到 JDialog 的内容窗格中。

在我参加过的唯一一次涉及 Java 的“正规教育”中(3 年前),我们被教导使用第三种形式,D​​ialogBoth()。

这样做有好处吗?也许在某些情况下需要以某种方式操作内容窗格?如果是这样,这些情况是什么?

还是“两者”形式只是为了让代码的读者清楚 JPanel 真的进入 JDialog 的内容窗格?

然后有可能使用 setContentPane(jPanelOuter)。在实际意义上,这有什么特殊目的吗?

import java.awt.Container;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

public class DialogTest {

    public static void main(String[] args) {
        DialogContentPane dlgC = new DialogContentPane();
        display(dlgC, "ContentPane");
        DialogJPanel dlgP = new DialogJPanel();
        display(dlgP, "JPanel");
        DialogBoth dlgB = new DialogBoth();
        display(dlgB, "Both");
    }

    public static class DialogContentPane extends JDialog {

        public DialogContentPane() {
            Container contentPane = this.getContentPane();
            contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
            JRadioButton jRadioButton1 = new JRadioButton("My Radio Button, which does nothing");
            jRadioButton1.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            contentPane.add(jRadioButton1);
            JCheckBox jCheckBox1 = new JCheckBox("My Check Box, which does nothing either");
            jCheckBox1.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            contentPane.add(jCheckBox1);
        }
    }

    public static class DialogJPanel extends JDialog {

        public DialogJPanel() {
            JPanel jPanelOuter = new JPanel();
            jPanelOuter.setLayout(new BoxLayout(jPanelOuter, BoxLayout.Y_AXIS));
            JRadioButton jRadioButton1 = new JRadioButton("My Radio Button, which does nothing");
            jRadioButton1.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            jPanelOuter.add(jRadioButton1);
            JCheckBox jCheckBox1 = new JCheckBox("My Check Box, which does nothing either");
            jCheckBox1.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            jPanelOuter.add(jCheckBox1);
            this.add(jPanelOuter);
        }
    }

    public static class DialogBoth extends JDialog {

        public DialogBoth() {
            Container contentPane = this.getContentPane();
            contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
            JPanel jPanelOuter = new JPanel();
            jPanelOuter.setLayout(new BoxLayout(jPanelOuter, BoxLayout.Y_AXIS));
            JRadioButton jRadioButton1 = new JRadioButton("My Radio Button, which does nothing");
            jRadioButton1.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            jPanelOuter.add(jRadioButton1);
            JCheckBox jCheckBox1 = new JCheckBox("My Check Box, which does nothing either");
            jCheckBox1.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            jPanelOuter.add(jCheckBox1);
            contentPane.add(jPanelOuter);
        }
    }

    public static void display(JDialog dlg, String title) {
        Toolkit tk;
        Dimension screenDims;
        dlg.setTitle(title);
        tk = Toolkit.getDefaultToolkit();
        screenDims = tk.getScreenSize();
        dlg.setLocation((screenDims.width - dlg.getWidth()) / 2, (screenDims.height - dlg.getHeight()) / 2);
        dlg.pack();
        dlg.setModalityType(JDialog.DEFAULT_MODALITY_TYPE);
        dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dlg.setVisible(true);
    }
}

标签: javaswing

解决方案


除了您需要输入的代码量之外,没有“直接”的优势或劣势。由于 Java 1.5(我认为)对顶级容器之类的调用会add自动路由到setLayoutcontentPanegetContentPanesetContentPane

为了更好地了解正在发生的事情,您需要更好地了解如何JFrame工作......

根窗格

AJFrame是复合组件,由一系列层组成。当 Swing 首次发布时,需要contentPane直接使用 才能向其添加组件。这最终得到修复 (?) 以允许您contentPane直接向框架添加/删除组件。

请注意,removeAll, 不会路由到contentPane并且会删除JRootPane,这是混乱的。

有些人更喜欢“旧”的方式,因为很明显已经做了什么,有些人(像我一样,很懒),只是更喜欢把事情做好


推荐阅读