我正在开发一个执行某些长时间运行的功能的应用程序。为了让用户知道正在处理,我需要一个标签来显示一些可以代表它的标签。所以,我为这样的标签创建了一个小部件。
下面的程序运行 find ,我得到了我想要的输出。
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* This is an extension to a JLabel that can be used to display an ongoing progress.
* @author Ankit Gupta
*/
public class ProgressLabel extends JLabel {
/**
* The prefix label to which periods are added.
*/
private String startLabel;
/**
* The label to display end of an operation.
*/
private String endLabel;
/**
* Flag to indicate whether the animation is running or not.
*/
private boolean running = false;
//list to hold intermediate labels
List<String> intermediateLabels;
public ProgressLabel(String slbl, String elbl) {
this.startLabel = slbl;
this.endLabel = elbl;
//initialize all the labels to be used once as creating them again and again is expensive
intermediateLabels = new ArrayList<String>();
intermediateLabels.add(startLabel+".");
intermediateLabels.add(startLabel+"..");
intermediateLabels.add(startLabel+"...");
intermediateLabels.add(startLabel+"....");
}
public void done(){
running = false;
}
public void start(){
running = true;
new LabelUpdateThread().start();
}
private class LabelUpdateThread extends Thread{
int i;
public LabelUpdateThread(){
i=0;
}
@Override
public void run(){
while(running){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
setText(intermediateLabels.get((i++)%3));
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
setText(endLabel);
}
}
public static void main(String []args) throws InterruptedException{
final JFrame frame = new JFrame("Testing ProgressLabel");
JPanel panel = new JPanel();
ProgressLabel progressLabel = new CZProgressLabel("Searching", "Done");
panel.add(progressLabel);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(500,500));
frame.pack();
progressLabel.start();
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
frame.setVisible(true);
}
});
Thread.sleep(5000);
progressLabel.done();
}
}
但是,当我尝试将其包含在应用程序中时,它并没有按预期工作。我创建了一个带有按钮的小面板,在按钮的代码actionPerfomed()
中我像以前一样使用了start()和done()方法,但是这一次,标签直到长度过程完成才更新为Done 。这是另一段使用with的代码:ProgressLabel
ProgressLabel
actionPerformed()
public class SearchPanel extends JPanel {
private JTextArea queryBox;
private JButton searchBtn;
private ProgressLabel progressLabel;
private JSeparator queryAreaSeparator;
public SearchPanel() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
//First Row
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.gridx = 0;
queryBox = new JTextArea();
queryBox.setRows(25);
queryBox.setColumns(25);
this.add(queryBox, gbc);
//Second Row
gbc.gridy = 1;
gbc.gridwidth = 1;
progressLabel = new ProgressLabel("Searching", "Done");
this.add(progressLabel, gbc);
gbc.gridx = 1;
searchBtn = new JButton("Search");
this.add(searchBtn, gbc);
searchBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
progressLabel.start();
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
}
//the above sleep() call will be replace by some time-consuming process. It is there just for testing now
progressLabel.done();
}
});
gbc.gridx = 0;
}
/**
* function to test CZSemanticSearchLabel
*/
public static void main(String[] args) throws InterruptedException {
final JFrame frame = new JFrame();
CZSemanticSearchPanel panel = new CZSemanticSearchPanel();
frame.add(panel);
frame.setPreferredSize(new Dimension(500, 500));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Thread.sleep(10000);
frame.dispose();
final JFrame frame1 = new JFrame("Testing ProgressLabel");
JPanel panel1 = new JPanel();
CZProgressLabel progressLabel = new CZProgressLabel("Searching", "Done");
panel1.add(progressLabel);
frame1.add(panel1);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setPreferredSize(new Dimension(500, 500));
frame1.pack();
progressLabel.start();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame1.setVisible(true);
}
});
Thread.sleep(5000);
progressLabel.done();
}
}
我相信我已经用 Swing 的事件调度模型搞砸了。但是,我想不通是什么?有人能告诉我这段代码有什么问题吗?我该如何纠正?