指定顶级容器的ContentPane是否有好处?

时间:2018-06-30 21:06:23

标签: java swing

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

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

(3年前)在我参与Java的唯一“形式教育”中,我们被教导使用第三种形式DialogBoth()。

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

还是“两种”形式都只是为了使代码读者清楚地知道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);
    }
}

1 个答案:

答案 0 :(得分:1)

除了需要输入的代码量之外,没有“直接”的优势或劣势。由于Java 1.5(我认为)对顶级容器上的addsetLayout之类的调用会自动路由到contentPane,因此这就是为什么您仍然可以看到使用{{ 1}}或getContentPane

要更好地了解正在发生的事情,您需要更好地了解setContentPane的工作原理...

Root pane

JFrame是复合组件,由一系列层组成。最初发布Swing时,必须直接使用JFrame才能向其中添加组件。最终已将其修复(?),以使您可以直接通过框架将组件添加到contentPane

请注意,contentPane不会被路由到removeAll,并且会删除contentPane,这很麻烦。

有些人喜欢“旧的”方式,因为显而易见,它已经完成了,有些人(像我一样,很懒),只是喜欢把事情做完