在JFrame和JDialog之间传递容器导致缺少面板?

时间:2016-11-24 15:02:56

标签: java swing jframe restart jdialog

至于测试原因,我尝试使用面板及其主应用程序框架的内容打开JDialog窗口。因为我已经在那里有任何东西,我想看看我是否可以简单地将JDialogs contentPane设置为我传递的那个。因此,以简单的形式,这就聚集在一起:

testsforSO.java:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class testsforSO extends JFrame {

    private static final long serialVersionUID = -3890178393751567629L;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    testsforSO frame = new testsforSO();
                    frame.setSize(300, 300);
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public testsforSO() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("I am the Frame");
        getContentPane().setLayout(new BorderLayout(0, 0));

        JPanel panel = new JPanel();
        panel.setLayout(null);

        JButton btnRestart = new JButton("Restart");
        btnRestart.setBounds(10, 10, 50, 50);
        btnRestart.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                testsforSO.main(null);
                dispose();
            }
        });
        panel.add(btnRestart);
        getContentPane().add(panel);
        repaint();

// -----------DELETE These comments-------------
//      JDialog myDialg = new JDialog(this);
//      myDialg.setContentPane(panel);
//      myDialg.setVisible(true);
//      myDialg.setSize(300,300);
//      myDialg.setLocation(new Point(250, 250));
//      myDialg.setTitle("I am Dialog from within the script");

        myDialog.main(panel);
    }
}

和myDialog.java:

import java.awt.Container;
import java.awt.EventQueue;

import javax.swing.JDialog;

public class myDialog extends JDialog {

    private static final long serialVersionUID = 7079322237622743228L;

    public static void main(Container myContainer) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    myDialog frame = new myDialog(myContainer);
                    frame.setVisible(true);
                    frame.setContentPane(myContainer);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public myDialog(Container myContainer) {
        setContentPane(myContainer);

        getContentPane().setLayout(null);

        setBounds(200,200,200,200);

    }

}

当启动主框架时,我认为它将包含重启按钮以及对话框。但有趣的是,这只是带按钮的对话框 然而,当它击中时,主框架正确重新启动,设置了第二个对话框,它再次包含按钮。但是这次主框架也有按钮,没有任何功能。点击它绝对没有。

然后我进一步尝试并检查如果我将对话框直接添加到主应用程序代码中(参见注释行),是否会改变该行为,并再次启动应用程序,只有其自己的类中的对话框显示按钮。即使点击这一个现在正确地重新启动,但按钮不会出现在任何其他窗口,除了孤独的声明对话框。

我在这里缺少什么,如果以这种方式完成任务,我怎么能重构我的代码才能正常工作?

1 个答案:

答案 0 :(得分:3)

了解Swing组件只能存在于一个容器中,虽然您可能会看到容器中组件的视觉残留,但实际组件仅出现在添加到的最后一个容器中。

我自己,如果我希望对话框和jframe具有相同的内容窗格组件,我创建一个工厂方法来创建contentPane,然后使用它创建两个唯一但相同的contentPanes。

另外,如果我没有提到你使用null布局的话,我会失职。虽然null布局和setBounds()似乎是Swing新手,比如创建复杂GUI的最简单和最好的方法,但是你创建的Swing GUI越多,你在使用它们时会遇到更严重的困难。 。当GUI调整大小时,他们不会调整组件的大小,他们是增强或维护的皇室女巫,当他们放置在滚动窗格中时,他们完全失败,当他们在所有平台或屏幕分辨率不同时看起来很糟糕原来的。

例如,当我运行你的代码时,这是我看到的对话框:

enter image description here

您将按钮的大小硬编码为太小,无法在我的平台上显示其文字。如果您已使用布局管理器,并在顶级窗口调用pack(),则该按钮将正确显示。