gpt4 book ai didi

Java - 全局、可重用的加载对话框

转载 作者:行者123 更新时间:2023-12-01 06:35:45 29 4
gpt4 key购买 nike

我正在尝试实现一个全局加载对话框...我想调用一些静态函数来显示对话框和一些静态函数来关闭它。与此同时,我正在主线程或子线程中做一些工作......

我尝试了以下操作,但对话框没有更新...最后一次,在再次隐藏之前,它会更新...

    private static Runnable getLoadingRunable()
{
if (loadingRunnable != null)
{
loadingFrame.setLocationRelativeTo(null);
loadingFrame.setVisible(true);
return loadingRunnable;
}

loadingFrame = new JFrame("Updating...");
final JProgressBar progressBar = new JProgressBar();
progressBar.setIndeterminate(true);
final JPanel contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
contentPane.setLayout(new BorderLayout());
contentPane.add(new JLabel("Updating..."), BorderLayout.NORTH);
contentPane.add(progressBar, BorderLayout.CENTER);
loadingFrame.setContentPane(contentPane);
loadingFrame.pack();
loadingFrame.setLocationRelativeTo(null);
loadingFrame.setVisible(true);

loadingRunnable = new Runnable() {
public void run() {

try {
while (running) {
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}

SwingUtilities.invokeLater(new Runnable() {
public void run() {
loadingFrame.setVisible(false);
}
});
}
};
return loadingRunnable;
}

public static void showLoadingBar() {
System.out.println("showLoadingBar");
running = true;

threadLoadingBar = new Thread(getLoadingRunable());
threadLoadingBar.start();
}

public static void hideLoadingBar() {
System.out.println("hideLoadingBar");
running = false;
threadLoadingBar = null;
}

最佳答案

Swing 使用单线程模型进行事件分派(dispatch)(包括绘制更新),因此,您永远不应该在事件分派(dispatch)线程 (EDT) 内执行任何长时间运行或阻塞操作。

Swing 也不是线程安全的,这意味着您永远不应该从 EDT 外部创建或修改任何 UI 组件。

全局进度对话框的基本概念是提供一个不依赖于需要执行的工作的框架,这将责任区域分开,进度对话框负责显示进度和工作人员/引擎负责做好实际工作。

最简单的解决方案是使用 SwingWorker。这提供了在单独的线程中执行长时间运行的任务、状态更改和进度通知的机制。

enter image description here

public class TestProgressDialog {

public static void main(String[] args) {
new TestProgressDialog();
}

public TestProgressDialog() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}

SwingWorker worker = new SwingWorker() {
@Override
protected Object doInBackground() throws Exception {
for (int index = 0; index < 100; index++) {
Thread.sleep(50);
setProgress(index);
}
return null;
}

};

ProgressDialog.showProgress(null, worker);

System.exit(0);

}

});
}

public static class ProgressDialog extends JDialog {

private JLabel message;
private JLabel subMessage;
private JProgressBar progressBar;

public ProgressDialog(Component parent, SwingWorker worker) {

super(parent == null ? null : SwingUtilities.getWindowAncestor(parent));
setModal(true);

((JComponent)getContentPane()).setBorder(new EmptyBorder(8, 8, 8, 8));

message = new JLabel("Doing important stuff");
subMessage = new JLabel("Go make you're self a cup of coffee...");
progressBar = new JProgressBar();

setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
add(message, gbc);

gbc.gridy++;
add(subMessage, gbc);

gbc.gridy++;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(progressBar, gbc);

pack();

worker.addPropertyChangeListener(new PropertyChangeHandler());
switch (worker.getState()) {
case PENDING:
worker.execute();
break;
}

}

public static void showProgress(Component parent, SwingWorker worker) {

ProgressDialog dialog = new ProgressDialog(parent, worker);
dialog.setLocationRelativeTo(parent);
dialog.setVisible(true);

}

public class PropertyChangeHandler implements PropertyChangeListener {

@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("state")) {
SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
switch (state) {
case DONE:
dispose();
break;
}
} else if (evt.getPropertyName().equals("progress")) {
progressBar.setValue((int)evt.getNewValue());
}
}

}

}

}

关于Java - 全局、可重用的加载对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14113644/

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