java - 按下 JButton 后多次生成 JPanel "blink"

标签 java swing jframe jpanel jbutton

我在 JFrame 中有一个简单的 JPanel 和 JButton。我希望按下按钮时它会闪烁几次。主要问题是我尝试了几种不同的方法来让它这样做,使用 Thread.sleep(200) 和 numBlinks 的 for 循环。但是,这只是在切换颜色时“暂停”面板,并且仅显示最终结果。

谢谢。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BlinkingJPanel implements ActionListener{

    private JFrame window;
    private JPanel panel;
    private JButton button;

    private final Color BACKGROUND1 = Color.GRAY;
    private final Color BACKGROUND2 = Color.WHITE;
    private final Color BORDER_COLOR = Color.BLACK;
    private final int BORDER_SIZE = 1;

    private final int WINDOW_SIZE = 200;
    private final int PANEL_SIZE = 100;
    private final int BUTTON_SIZE = 100;

    public static void main(String[] args) {
        BlinkingJPanel main = new BlinkingJPanel();
    }

    public BlinkingJPanel() {
        setUpWindow();
        setUpPanel();
        setUpButton();

        window.add(panel, BorderLayout.CENTER);
        window.add(button, BorderLayout.NORTH);
    }

    private void setUpWindow() {
        window = new JFrame("Blinking JPanel");

        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setBackground(BACKGROUND1);
        window.setSize(WINDOW_SIZE, WINDOW_SIZE);
        window.setVisible(true);
    }

    private void setUpPanel() {
        panel = new JPanel();

        panel.setSize(PANEL_SIZE, PANEL_SIZE);
        panel.setBorder(BorderFactory.createLineBorder(BORDER_COLOR, BORDER_SIZE));
        panel.setBackground(BACKGROUND1);
        panel.setVisible(true);
    }

    private void setUpButton() {
        button = new JButton("Blink");

        button.setSize(BUTTON_SIZE, BUTTON_SIZE / 2);
        button.setActionCommand("Button1");
        button.addActionListener(this);
        button.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {

        switch(e.getActionCommand()) {
        case "Button1": blink(1);
            break;
        default: System.out.println("Default Case");
            break;
        }

    }

    private void blink(int numBlinks) {
        // TODO: make panel blink on it's own

        if(panel.getBackground() == BACKGROUND1) {
            panel.setBackground(BACKGROUND2);
        } else {
            panel.setBackground(BACKGROUND1);
        }

    }


}

最佳答案

我使用计时器创建了一个解决方案。我试图保持简单。我所做的就是添加一个计时器,它需要你启动它时希望它弹出的时间(它们每隔几毫秒就会弹出一次,我将其设置为 300 毫秒)和一个我刚刚使用类本身的 Action 监听器。当计时器弹出时,它会触发 Action 监听器,使其闪烁,直到达到顶部 BLINK_AMOUNT 中的金额。然后停止计时器并将闪烁计数重置为 0。计时器仅在您按下按钮时启动。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class BlinkingJPanel implements ActionListener{

private JFrame window;
private JPanel panel;
private JButton button;

private final Color BACKGROUND1 = Color.GRAY;
private final Color BACKGROUND2 = Color.WHITE;
private final Color BORDER_COLOR = Color.BLACK;
private final int BORDER_SIZE = 1;

private final int WINDOW_SIZE = 200;
private final int PANEL_SIZE = 100;
private final int BUTTON_SIZE = 100;

private final int BLINK_AMOUNT = 1;
private Timer blinkTimer;
private int blinkCount;

public static void main(String[] args) {
    BlinkingJPanel main = new BlinkingJPanel();
}

public BlinkingJPanel() {
    setUpWindow();
    setUpPanel();
    setUpButton();

    window.add(panel, BorderLayout.CENTER);
    window.add(button, BorderLayout.NORTH);

    //Timer constructor takes pop time and action listener
    blinkTimer = new Timer(300, this);
    blinkCount = 0;

    window.setVisible(true);
}

private void setUpWindow() {
    window = new JFrame("Blinking JPanel");

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setBackground(BACKGROUND1);
    window.setSize(WINDOW_SIZE, WINDOW_SIZE);
}

private void setUpPanel() {
    panel = new JPanel();

    panel.setSize(PANEL_SIZE, PANEL_SIZE);
    panel.setBorder(BorderFactory.createLineBorder(BORDER_COLOR, BORDER_SIZE));
    panel.setBackground(BACKGROUND1);
    panel.setVisible(true);
}

private void setUpButton() {
    button = new JButton("Blink");

    button.setSize(BUTTON_SIZE, BUTTON_SIZE / 2);
    button.setActionCommand("Button1");
    button.addActionListener(this);
    button.setVisible(true);
}

public void actionPerformed(ActionEvent e) {
    if(e.getSource().equals(button)){
        blinkTimer.start();
    }
    else if(e.getSource() instanceof Timer){
        if(blinkCount == BLINK_AMOUNT){
            blinkCount = 0;
            blinkTimer.stop();
        }
        blink();
        blinkCount++;
    }else{
        System.out.println("Default");
    }
}

private void blink() {
    if(panel.getBackground() == BACKGROUND1) {
        panel.setBackground(BACKGROUND2);
    } else {
        panel.setBackground(BACKGROUND1);
    }

}
}

如果其中任何内容令人困惑,请随时询问。

正如您所说,thread.sleep() 不会工作,因为所有 swing 都在一个线程上运行,因此调用该函数将使整个线程停止运行(执行代码),然后运行代码的下一部分。

希望这有帮助。

关于java - 按下 JButton 后多次生成 JPanel "blink",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40182458/

相关文章:

java - 如何在 JPanel 中添加 JButton?

java - 想要在同一个类中创建 JFrame 和 JPanel 并拥有自己的 PaintComponent?

java - 在 Java 中捕获错误时要做什么)

java - 在 arrayList 的某个索引处插入元素的运行时间是多少?

Java - Jackcess API,采用 .accde(MS Access) 格式

java - Android - 将 XML 架构发布到 PHP 服务器 API

java - KeyListener 无法与 PaintComponent 一起使用

java - 从 jframe 打开网页

java - 限制 JTextField 中的字符数

java - (Java) 类里面的困难