此代码从开始按钮开始,但是如果选择了单选按钮倒数,则使用此代码,当倒数为0时,第二个帧出现,并应以用户输入的速度更改颜色,称为“ brzinaTreperenja2”(即转换为int,然后乘以1000(我的颜色是红色)。当我没有第二个actionListener时,会发生闪烁,并且闪烁的速度为1秒,但是当我这样做时,程序将冻结。你能帮我吗?
start.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if(countdown.isSelected()){
final Timer p = new Timer();
display.setFont(new Font("Ariel", Font.BOLD,25));
display.setBounds(150,75,120,20);
p.scheduleAtFixedRate(new TimerTask(){
int i = Integer.parseInt(odbrojavanje.getText());
@Override
public void run(){
display.setText(""+(i--));
if(i<0){
p.cancel();
drugi.setVisible(true);
Thread t = new Thread();
while(true){
ActionListener al3 = new ActionListener(){
public void actionPerformed(ActionEvent h){
drugi.getContentPane().setBackground(boja.getBackground());
try {
t.sleep(brzinaTreperenja2);
} catch (InterruptedException ex) {
Logger.getLogger(PrviProzor.class.getName()).log(Level.SEVERE, null, ex);
}
drugi.getContentPane().setBackground(Color.red);
try {
t.sleep(brzinaTreperenja2);
} catch (InterruptedException ex) {
Logger.getLogger(PrviProzor.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
javax.swing.Timer p = new javax.swing.Timer(1000, al3);
p.start();
}
}
}
},0,1000);
}
}
});`
答案 0 :(得分:0)
您的代码无视Swing线程规则:
java.uti.Timer
,并且应该使用javax.swing.Timer
,因为后者的重复代码在Swing事件线程上运行。while (true)
个不属于您的循环。计时器负责循环功能。例如,以下代码使用JSlider设置闪烁频率,并使用一个复选框启动/停止Swing计时器,该计时器使主JPanel的背景颜色闪烁:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class BlinkEg extends JPanel {
public static final Color COLOR = Color.RED;
private JSlider slider = new JSlider(100, 1000, 500);
private JCheckBox blinkBox = new JCheckBox("Blink");
private Timer timer = new Timer(slider.getValue(), new TimerListener());
public BlinkEg() {
slider.setOpaque(false);
slider.setMajorTickSpacing(200);
slider.setMinorTickSpacing(10);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
setPreferredSize(new Dimension(400, 200));
JPanel bottomPanel = new JPanel();
bottomPanel.add(blinkBox);
bottomPanel.setOpaque(false);
blinkBox.setOpaque(false);
blinkBox.addItemListener(evt -> {
if (evt.getStateChange() == ItemEvent.SELECTED) {
timer.start();
} else {
timer.stop();
setBackground(null);
}
});
slider.addChangeListener(evt -> {
int value = slider.getValue();
timer.setDelay(value);
});
setLayout(new BorderLayout());
add(slider);
add(bottomPanel, BorderLayout.PAGE_END);
}
private class TimerListener implements ActionListener {
private boolean drawColor = false;
@Override
public void actionPerformed(ActionEvent e) {
Color color = drawColor ? null : COLOR;
BlinkEg.this.setBackground(color);
drawColor = !drawColor;
}
}
private static void createAndShowGui() {
BlinkEg mainPanel = new BlinkEg();
JFrame frame = new JFrame("BlinkEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
请注意,要更改Swing计时器的计时,只需调用其setDelay(...)
方法:
// timer changed to rate set by JSlider:
slider.addChangeListener(evt -> {
int value = slider.getValue();
timer.setDelay(value);
});
要启动和停止闪烁,只需启动和停止计时器:
// timer start and stopped based on JCheckBox state
blinkBox.addItemListener(evt -> {
if (evt.getStateChange() == ItemEvent.SELECTED) {
timer.start();
} else {
timer.stop();
setBackground(null); // so always stops with baseline color
}
});
Swing Timer使用一个ActionListener,它使用一个布尔值来决定将背景设置为哪种颜色,然后交换布尔值
private class TimerListener implements ActionListener {
private boolean drawColor = false;
@Override
public void actionPerformed(ActionEvent e) {
// choose color based on the state of drawColor
Color color = drawColor ? null : COLOR;
BlinkEg.this.setBackground(color);
drawColor = !drawColor; // now toggle drawColor's boolean value
}
}