我正在尝试实现一个 Swing 框架。在此,我想在执行所需任务时使用不同的线程在文本面板中显示处理状态。我尝试了以下代码。当然逻辑上是有问题的。请给我正确的方法
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class SampleSwing {
private JFrame frame;
public static JTextField textField;
public static boolean processing=false;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SampleSwing window = new SampleSwing();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public SampleSwing() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
textField = new JTextField();
textField.setBounds(0, 31, 434, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
processing=true;
Processingstatus ps=new Processingstatus();
ps.start();
/*perform the actual task*/
processing=false;
}
});
btnNewButton.setBounds(174, 74, 89, 23);
frame.getContentPane().add(btnNewButton);
}
}
class Processingstatus extends Thread{
public void run() {
try {
while(SampleSwing.processing) {
SampleSwing.textField.setText("Processing");
Thread.sleep(1000);
SampleSwing.textField.setText("Processing..");
Thread.sleep(1000);
SampleSwing.textField.setText("Processing...");
Thread.sleep(1000);
}
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
最佳答案
首先我想,“您应该使用 SwingWorker
,因为它有处理进度和 EDT 更新的方法......”
但是当我仔细观察时,你实际上并不真正关心进程本身,你只是想要一些地方来显示进程正在运行......它们是两个独立的实体,它们只是因为一个( UI 更新)只要另一个在运行,就会运行。
因此,我使用了 javax.swing.Timer
。这允许我安排一个事件每 n
毫秒发生一次,并在 EDT 中触发该事件,干净整洁......
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.Timer;
public class SampleSwing {
private JFrame frame;
public static JTextField textField;
public static boolean processing = false;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SampleSwing window = new SampleSwing();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SampleSwing() {
initialize();
}
private Timer processTimer;
private void initialize() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
textField = new JTextField(25);
frame.add(textField, gbc);
processTimer = new Timer(500, new ActionListener() {
private StringBuilder dots = new StringBuilder(3);
@Override
public void actionPerformed(ActionEvent e) {
dots.append(".");
if (dots.length() > 3) {
dots.delete(0, dots.length());
}
textField.setText("Processing" + dots.toString());
}
});
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (!processing) {
processing = true;
processTimer.start();
} else {
processTimer.stop();
processing = false;
textField.setText(null);
}
}
});
frame.add(btnNewButton, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
}
}
ps 对于您的原始代码不起作用的原因,请参阅上面评论部分中我的评论;)
关于Java Swing 处理状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15803893/