gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 08:40:20 25 4
gpt4 key购买 nike

我有一个名为 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com