Java,Swing - JPanel并没有像预期的那样出现在JFrame中

时间:2016-11-20 00:10:02

标签: java swing

我有一个名为PleaseWait的java类,想要在繁重的任务正在进行时调用它。当我的程序执行繁重的任务时,在actionListener的第一行中,我设置了此类setVisible(true)的变量,然后在setVisible(true)的末尾设置actionListener

当我调用它时,不会显示此类中的JPanel,它只是一个标题为set和白色空白内容的窗口。这是我的代码:

public class PleaseWait extends JFrame{

public PleaseWait(){

    Toolkit toolkit = Toolkit.getDefaultToolkit();

    Dimension screenDimensions = toolkit.getScreenSize();
    setSize(300,100); //set size based on screen size
    setTitle("Please wait");
    Container container = getContentPane();
    setLocation(new Point(screenDimensions.width*1/4+200, screenDimensions.height*1/4+200)); //set location based on screen size

    JPanel panel = new JPanel();
    JLabel wait = new JLabel("Please wait");
    Dimension buttonsSize = new Dimension(300,100);
    panel.setPreferredSize(buttonsSize);
    wait.setPreferredSize(buttonsSize);
    panel.setLayout(new BorderLayout());
    panel.add(wait, BorderLayout.CENTER);
    container.add(panel);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false); //unresizable
}

1 个答案:

答案 0 :(得分:4)

密钥不在您发布的代码中,但在此行中:

  

并且想要在繁重的任务正在进行时调用它

你正在运行一个“繁重”的任务,当你运行它时,Swing没有绘制这个GUI,因为你可能在Swing事件线程上运行那个任务,并且这样做会冻结线程,< strong>和您的GUI 。

解决方案:使用可通过SwingWorker获取的后台线程来运行“繁重”任务。

其他方面问题:

  • 这似乎是主应用程序的“依赖”或“子”窗口。如果是这样,它不应该是JFrame,因为应用程序应该只有一个主应用程序窗口,而应该是一个JDialog。
  • 您正在使用setPreferredSize(...)并对组件大小进行硬编码,这些问题充满了问题。

如,

import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class TestPleaseWait {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            MainPanel mainPanel = new MainPanel();
            JFrame frame = new JFrame("Application");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

@SuppressWarnings("serial")
class MainPanel extends JPanel {
    private static final int PREF_W = 600;
    private static final int PREF_H = 450;

    public MainPanel() {
        add(new JButton(new AbstractAction("Without Background Thread") {
            {
                putValue(MNEMONIC_KEY, KeyEvent.VK_O);
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                final PleaseWait wait = new PleaseWait();
                wait.setVisible(true);
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e1) {
                }
                wait.setVisible(false);
            }
        }));
        add(new JButton(new AbstractAction("With Background Thread") {
            private JDialog waitDialog = null;
            private MyWaitPanel myWaitPanel = new MyWaitPanel();

            {
                putValue(MNEMONIC_KEY, KeyEvent.VK_W);
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                if (waitDialog == null) {
                    Component component = MainPanel.this;
                    Window win = SwingUtilities.getWindowAncestor(component);
                    waitDialog = new JDialog(win, "Please Wait", ModalityType.APPLICATION_MODAL);
                    waitDialog.add(myWaitPanel);
                    waitDialog.pack();
                    waitDialog.setLocationRelativeTo(win);
                }

                new Thread(() -> {
                    try {
                        Thread.sleep(4000);
                    } catch (InterruptedException e1) {
                    }
                    SwingUtilities.invokeLater(() -> {
                        waitDialog.setVisible(false);
                    });

                }).start();
                waitDialog.setVisible(true);
            }
        }));
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }
}

@SuppressWarnings("serial")
class MyWaitPanel extends JPanel {
    private JProgressBar progressBar = new JProgressBar();

    public MyWaitPanel() {
        progressBar.setIndeterminate(true);

        JLabel waitLabel = new JLabel("Please Wait", SwingConstants.CENTER);
        waitLabel.setFont(waitLabel.getFont().deriveFont(Font.BOLD, 40));

        int ebGap = 10;
        setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
        setLayout(new BorderLayout(ebGap, ebGap));
        add(waitLabel, BorderLayout.PAGE_START);
        add(progressBar);
    }
}

@SuppressWarnings("serial")
class PleaseWait extends JFrame {

    public PleaseWait() {

        Toolkit toolkit = Toolkit.getDefaultToolkit();

        Dimension screenDimensions = toolkit.getScreenSize();
        setSize(300, 100); // set size based on screen size
        setTitle("Please wait");
        Container container = getContentPane();
        setLocation(new Point(screenDimensions.width * 1 / 4 + 200,
                screenDimensions.height * 1 / 4 + 200));

        JPanel panel = new JPanel();
        JLabel wait = new JLabel("Please wait");
        Dimension buttonsSize = new Dimension(300, 100);
        panel.setPreferredSize(buttonsSize);
        wait.setPreferredSize(buttonsSize);
        panel.setLayout(new BorderLayout());
        panel.add(wait, BorderLayout.CENTER);
        container.add(panel);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false); // unresizable
    }
}