Java、Swing - JPanel 没有按预期出现在 JFrame 中

标签 java swing

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

不知何故,当我调用它时,此类中的 JPanel 没有出现,它只是一个设置了标题和白色空白内容的窗口。这是我的代码:

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
}

最佳答案

关键不在您发布的代码中,而在这一行中:

and want to call it whenever a heavy task is in progress

你正在运行一个“繁重”的任务,当你运行它时,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
    }
}

关于Java、Swing - JPanel 没有按预期出现在 JFrame 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40699320/

相关文章:

java - SQL语句语法错误 "CREATE EXTENSION[*] IF NOT EXISTS UUID_OSSP "

java - 子类型 SwingWorker : where would I place my statements that would not run in the GUI thread

java - 通过 BufferedReader 检索数据后 List 中的值重复

javascript - 如何从 node.js 调用 java 程序?

java - FocusListener 行为

java - 如何为多个组件创建一个单一的 actionlistener 函数

java - 添加 Action 监听器的语法

java - JCheckBox组件可以添加到JComboBoxes中吗?

java - 为什么 socket.close() 不释放绑定(bind)端口?

java - 使用 Java 查询从数据库中选择值并将它们用作变量并将其插入另一个表中