嘿,我正在尝试使用swing构建一个程序。我已经创建了一个按钮,我想计算它在一分钟内被点击的次数。但问题是,一旦我按下按钮它就不会被释放,并且计数器继续自行增加。 代码:
while ((System.currentTimeMillis()-startTime)< 1*60*1000)
{
if(eee.getSource()==b)
{
counter++;
}
System.out.println(counter);
}
答案 0 :(得分:2)
让我们从基础开始......
Swing是一个单线程环境,任何阻止Event Dispatching Thread运行的东西都会阻止它更新UI或响应其他事件。同样,您应该只在Event Dispatching Thread的上下文中修改UI组件的状态。
有关详细信息,请查看Concurrency in Swing。
举一个简单的例子,这只是让你点击按钮,每次点击它确定是否已经过了一分钟,如果它还没有更新按钮的状态
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SmackMe {
public static void main(String[] args) {
new SmackMe();
}
public static final long ONE_MINUTE = 1000 * 60;
private long startTime = -1;
private int count = 0;
public SmackMe() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JButton button = new JButton("Smack me");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime < 0) {
startTime = System.currentTimeMillis();
}
long diff = System.currentTimeMillis() - startTime;
System.out.println((diff / 1000));
if (diff >= ONE_MINUTE) {
startTime = -1;
button.setEnabled(false);
} else {
count++;
}
button.setText(Integer.toString(count));
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
问题在于,它是响应式的,它需要点击按钮才能执行时间检查,更好的解决方案会有某种后台进程,可以在一分钟后禁用按钮... < / p>
这是javax.swing.Timer
...
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SmackMe {
public static void main(String[] args) {
new SmackMe();
}
public static final int ONE_MINUTE = 1000 * 60;
private int count = 0;
private Timer timer;
private JButton button;
public SmackMe() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
button = new JButton("Smack me");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!timer.isRunning()) {
timer.start();
}
count++;
button.setText(Integer.toString(count));
}
});
timer = new Timer(ONE_MINUTE, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(false);
}
});
timer.setRepeats(false);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
请查看How to use Swing Timers了解更多详情......