gpt4 book ai didi

java - 两个 JButtons 使用相同的 actionListener 来启动/停止定时器

转载 作者:行者123 更新时间:2023-11-29 07:44:41 28 4
gpt4 key购买 nike

我是 Java 的新手,需要一些帮助。我试图让计时器从设定时间倒计时到 0。我的这个功能运行良好,但我想添加功能以允许我在倒计时时停止计时器。

这是我的代码(我正在尝试使用 MVC 实现此目的)

这是控制部分:

import java.awt.event.*;
import javax.swing.*;

public class StartButton extends JButton implements ActionListener
{
private TimerModel model;
private Timer timer;
private boolean isStarted;

public StartButton(String buttonText, TimerModel model)
{
super(buttonText);
addActionListener(this);
this.model = model;
isStarted = false;
}

public void actionPerformed(ActionEvent evt)
{
if(!isStarted)
{
timer = new Timer(1000, this);
timer.start();
isStarted = true;
}

model.timerCountdown();
}

public void stopTimer()
{
timer.stop();
}
}

我在网上看了一些其他类似的问题,并在构造函数中尝试了这个(注意:我没有使用 implements ActionListener,并删除了上面的 actionPerformed 方法):

if(buttonText.equals("Start"))
{
addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(!isStarted)
{
timer = new Timer(1000, this);
timer.start();
isStarted = true;
}

model.timerCountdown();
}
});
}

if(buttonText.equals("Stop"))
{
addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
timer.stop();
}
});
}

现在这部分可以正常处理倒计时,但是当我单击停止按钮时它显示异常(See stack trace here),并且它继续倒计时。

我的知识有限,但我想这与我尝试停止计时器的方式有关。

如果有人能指出正确的方向,或者至少向我解释为什么会这样,我将不胜感激。

最佳答案

同样,如果您不更改 JButton 本身的基本行为,例如它的绘制方式,而只是更改按钮的标题和按下时的行为,则不要扩展 JButton。而是为每个按钮赋予其自己的 Action,一个来自从 AbstractAction 扩展的类的对象。将这些人视为类似于类固醇的 ActionListeners。它们具有与 ActionListeners 相同的功能,还有一些功能,因为它们可以轻松更改按钮的标题(无论是否启用)、它的助记符、图标……

例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.*;

import javax.swing.*;

@SuppressWarnings("serial")
public class MyTimerGui {
private static final String TITLE = "Flashing Label";
private static final int TIMER_DELAY = 200;
private static final int GAP = 3;
private static final float LABEL_POINTS = 32F;
private JPanel mainPanel = new JPanel();
private JLabel flashyLabel = new JLabel(TITLE, SwingConstants.CENTER);
private Timer timer = new Timer(TIMER_DELAY, new TimerListener());

public MyTimerGui() {
Font font = flashyLabel.getFont();
font = font.deriveFont(LABEL_POINTS);
flashyLabel.setFont(font);
flashyLabel.setOpaque(true);

JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, 0));
buttonPanel.add(new JButton(new StartAction(this, "Start", KeyEvent.VK_S)));
buttonPanel.add(new JButton(new StopAction(this, "Stop", KeyEvent.VK_T)));
buttonPanel.add(new JButton(new ExitAction(this, "Exit", KeyEvent.VK_X)));

mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.setLayout(new BorderLayout());
mainPanel.add(flashyLabel, BorderLayout.CENTER);
mainPanel.add(buttonPanel, BorderLayout.PAGE_END);
}

public JComponent getMainComponent() {
return mainPanel;
}

public void start() {
timer.start();
}

public void stop() {
timer.stop();
flashyLabel.setForeground(null);
flashyLabel.setBackground(null);
}

public void exit() {
timer.stop();
Window win = SwingUtilities.getWindowAncestor(mainPanel);
win.dispose();
}

private class TimerListener implements ActionListener {
private final Color foreground1 = Color.green;
private final Color background1 = Color.red;

@Override
public void actionPerformed(ActionEvent aEvt) {
Color fg = flashyLabel.getForeground();
if (foreground1.equals(fg)) {
flashyLabel.setForeground(null);
flashyLabel.setBackground(null);
} else {
flashyLabel.setForeground(foreground1);
flashyLabel.setBackground(background1);
}
}
}

private class StartAction extends AbstractAction {
private MyTimerGui myTimerGui;

public StartAction(MyTimerGui myTimerGui, String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.myTimerGui = myTimerGui;
}

@Override
public void actionPerformed(ActionEvent e) {
myTimerGui.start();
}
}

private class StopAction extends AbstractAction {
private MyTimerGui myTimerGui;

public StopAction(MyTimerGui myTimerGui, String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.myTimerGui = myTimerGui;
}

@Override
public void actionPerformed(ActionEvent e) {
myTimerGui.stop();
}
}

private class ExitAction extends AbstractAction {
private MyTimerGui myTimerGui;

public ExitAction(MyTimerGui myTimerGui, String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.myTimerGui = myTimerGui;
}

@Override
public void actionPerformed(ActionEvent e) {
myTimerGui.exit();
}
}

private static void createAndShowGui() {
MyTimerGui myTimerGui = new MyTimerGui();

JFrame frame = new JFrame("MyTimer");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(myTimerGui.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

关于java - 两个 JButtons 使用相同的 actionListener 来启动/停止定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26820922/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com