对话框中的 JProgressBar 无法正常工作
JProgressBar in dialog frame not working properly
我有一个 java 程序,它加载一个文本文件作为输入,读取它的内容,修改一些字符串,然后将结果打印到文本区域。由于此操作需要几秒钟,我想在此 activity 期间显示 JProgressBar 以通知用户执行正在进行中,并在 activity 完成后关闭包含 JprogressBar 的对话框并打印结果。
代码如下:
JButton btnCaricaFile = new JButton("Load text file");
panel.add(btnCaricaFile);
btnCaricaFile.setIcon(UIManager.getIcon("FileView.directoryIcon"));
btnCaricaFile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//JFileChooser choice = null;
final JFileChooser choice = new JFileChooser(userDir +"/Desktop");
int option = choice.showOpenDialog(GUI.this);
if (option == JFileChooser.APPROVE_OPTION) {
final JDialog dialog = new JDialog(GUI.this, "In progress", true);
JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setIndeterminate(true);
dialog.getContentPane().add(BorderLayout.CENTER, progressBar);
dialog.getContentPane().add(BorderLayout.NORTH, new JLabel("Elaborating strings..."));
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setSize(300, 75);
dialog.setLocationRelativeTo(GUI.this);
Thread t = new Thread(new Runnable() {
public void run() {
dialog.setVisible(true);
File file = choice.getSelectedFile();
lista.clear();
textArea.setText("");
lista = loadFile.openFile(file);
for(int i=0; i<lista.size(); i++) {
textArea.append(lista.get(i)+"\n");
}
dialog.setVisible(false);
}
});
t.start();
}
}
});
为此,我使用 JDialog 作为由适当线程执行的 JProgressBar 的容器。问题是进度条会无限期显示,并且不会在文本区域打印任何内容。
你能帮我解决这个问题吗?
谢谢
是的,您正在为您的文件读取创建一个后台线程,这很好,但是您也在同一个后台线程中进行 Swing 调用,这不好,这可能不适当地占用了 Swing 事件线程.关键是要使您的线程分离——后台工作在后台线程中进行,而 Swing 工作仅在 Swing 线程中进行。请详细阅读 Lesson: Concurrency in Swing。
我自己会创建并使用 SwingWorker<Void, String>
, and use the worker's publish/process method pair 将字符串安全地发送到 JTextArea。
例如,像...
final JDialog dialog = new JDialog(GUI.this, "In progress", true);
JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setIndeterminate(true);
dialog.getContentPane().add(BorderLayout.CENTER, progressBar);
dialog.getContentPane().add(BorderLayout.NORTH, new JLabel("Elaborating strings..."));
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setSize(300, 75);
dialog.setLocationRelativeTo(GUI.this);
lista.clear();
SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {
@Override
public Void doInBackground() throws Exception {
// all called *off* the event thread
lista = loadFile.openFile(file);
for (int i = 0; i < lista.size(); i++) {
publish(lista.get(i));
}
return null;
}
@Override
protected void process(List<String> chunks) {
// called on the event thread
for (String chunk : chunks) {
textArea.append(chunk + "\n");
}
}
// called on the event thread
public void done() {
dialog.setVisible(false);
// should call get() here to catch and handle
// any exceptions that the worker might have thrown
}
};
worker.execute();
dialog.setVisible(true); // call this last since dialog is modal
注意:代码未经测试和编译
我有一个 java 程序,它加载一个文本文件作为输入,读取它的内容,修改一些字符串,然后将结果打印到文本区域。由于此操作需要几秒钟,我想在此 activity 期间显示 JProgressBar 以通知用户执行正在进行中,并在 activity 完成后关闭包含 JprogressBar 的对话框并打印结果。
代码如下:
JButton btnCaricaFile = new JButton("Load text file");
panel.add(btnCaricaFile);
btnCaricaFile.setIcon(UIManager.getIcon("FileView.directoryIcon"));
btnCaricaFile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//JFileChooser choice = null;
final JFileChooser choice = new JFileChooser(userDir +"/Desktop");
int option = choice.showOpenDialog(GUI.this);
if (option == JFileChooser.APPROVE_OPTION) {
final JDialog dialog = new JDialog(GUI.this, "In progress", true);
JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setIndeterminate(true);
dialog.getContentPane().add(BorderLayout.CENTER, progressBar);
dialog.getContentPane().add(BorderLayout.NORTH, new JLabel("Elaborating strings..."));
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setSize(300, 75);
dialog.setLocationRelativeTo(GUI.this);
Thread t = new Thread(new Runnable() {
public void run() {
dialog.setVisible(true);
File file = choice.getSelectedFile();
lista.clear();
textArea.setText("");
lista = loadFile.openFile(file);
for(int i=0; i<lista.size(); i++) {
textArea.append(lista.get(i)+"\n");
}
dialog.setVisible(false);
}
});
t.start();
}
}
});
为此,我使用 JDialog 作为由适当线程执行的 JProgressBar 的容器。问题是进度条会无限期显示,并且不会在文本区域打印任何内容。
你能帮我解决这个问题吗? 谢谢
是的,您正在为您的文件读取创建一个后台线程,这很好,但是您也在同一个后台线程中进行 Swing 调用,这不好,这可能不适当地占用了 Swing 事件线程.关键是要使您的线程分离——后台工作在后台线程中进行,而 Swing 工作仅在 Swing 线程中进行。请详细阅读 Lesson: Concurrency in Swing。
我自己会创建并使用 SwingWorker<Void, String>
, and use the worker's publish/process method pair 将字符串安全地发送到 JTextArea。
例如,像...
final JDialog dialog = new JDialog(GUI.this, "In progress", true);
JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setIndeterminate(true);
dialog.getContentPane().add(BorderLayout.CENTER, progressBar);
dialog.getContentPane().add(BorderLayout.NORTH, new JLabel("Elaborating strings..."));
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setSize(300, 75);
dialog.setLocationRelativeTo(GUI.this);
lista.clear();
SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {
@Override
public Void doInBackground() throws Exception {
// all called *off* the event thread
lista = loadFile.openFile(file);
for (int i = 0; i < lista.size(); i++) {
publish(lista.get(i));
}
return null;
}
@Override
protected void process(List<String> chunks) {
// called on the event thread
for (String chunk : chunks) {
textArea.append(chunk + "\n");
}
}
// called on the event thread
public void done() {
dialog.setVisible(false);
// should call get() here to catch and handle
// any exceptions that the worker might have thrown
}
};
worker.execute();
dialog.setVisible(true); // call this last since dialog is modal
注意:代码未经测试和编译