首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我可以在计时器中使用线程吗?

我可以在计时器中使用线程吗?
EN

Stack Overflow用户
提问于 2019-05-28 02:00:49
回答 1查看 32关注 0票数 -2

此代码以开始按钮开始,但此代码用于选择单选按钮倒计时,当倒计时为0时,第二个帧出现,并应根据用户输入的称为“brzinaTreperenja2”(转换为整数,然后乘以1000以毫秒为单位)的速度更改颜色,颜色为红色。当我没有第二个actionListener时,闪烁确实会发生,并且闪烁的速度是1秒,但是当我有了它,程序就会死机。你能帮我做这个吗?

代码语言:javascript
复制
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);
    }
    }
});`
EN

回答 1

Stack Overflow用户

发布于 2019-05-28 02:08:42

你的代码轻视了Swing线程规则:

  • 您正在从后台线程进行Swing调用,这样做很危险,并且可能导致使用java.uti.Timer引发异常,并且应该使用javax.swing.Timer,因为后者的重复代码在Swing事件线程上运行。
  • 您有不属于的while (true)循环。定时器接管了循环的功能。
  • 您正在从while循环中重复创建和启动Swing定时器--为什么?

例如,下面的代码使用JSlider设置闪烁频率,使用复选框启动/停止闪烁主JPanel背景颜色的Swing计时器:

代码语言:javascript
复制
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(...)方法:

代码语言:javascript
复制
// timer changed to rate set by JSlider:
slider.addChangeListener(evt -> {
    int value = slider.getValue();
    timer.setDelay(value);
});

要启动和停止闪烁,只需启动和停止计时器:

代码语言:javascript
复制
// 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计时器使用一个ActionListener来确定要将背景设置为什么颜色,然后交换布尔值

代码语言:javascript
复制
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
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56330597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档