为 addActionListener 找到正确的参数

Finding the right argument for addActionListener

我正在尝试制作一个按钮,在按下时切换按钮的状态(更改颜色和文本)。但是我无法让 addActionListener 工作,而且我无法从我的主 class 中找到 ToggleState 方法。我是 java 的新手,非常感谢您的帮助。

我收到错误 - “AbstractButton 类型中的方法 addActionListener(ActionListener) 不适用于参数” - "ActionListener cannot be resolved to a type"

package Grafiktest;

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

public class coolgrafik extends JFrame implements ActionListener {

private static final long serialVersionUID = 1L;
private JPanel panel;
private JLabel label;

public coolgrafik(){

    //super(title);
    setSize(400,60);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    panel = new JPanel();
    panel.setBackground(Color.GRAY);
    label = new JLabel("test");
    panel.add(label);

    MyButton button = new MyButton(Color.green, Color.red, "RUN","STOP");
    panel.add(button);
    button.addActionListener(this);

    add(panel);
}

public static void main(String[] args){
    new coolgrafik().setVisible(true);
    //toggleState(Color.green, Color.red, "RUN","STOP");
}

public void actionPerformed(ActionEvent e) {
    toggleState(Color.green, Color.red, "RUN","STOP");
}
}

这是按钮 class

package Grafiktest;

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

public class MyButton extends JButton{

private static final long serialVersionUID = 1L;

public MyButton(Color c1, Color c2, String s1, String s2){

    setText(s1);
    setForeground(c1);
    setBackground(c1);
    setOpaque(true);

}

public void toggleState(Color c1, Color c2, String s1, String s2){

    setText(s2);
    setForeground(c2);
    setBackground(c2);
    setOpaque(true);

}

}

完成@Japu_D_Cret 的评论:

您要么需要将 toggleState 方法设为静态,以便像在 actionPerformed 方法中那样调用它,要么使用您的按钮来调用它:

button.toggleState(Color.green, Color.red, "RUN","STOP");

因为它是在您的 MyButton class 中定义的方法,而不是在您的 coolgrafik class.

中定义的方法

"The method addActionListener(ActionListener) in the type AbstractButton is not applicable for the arguments” - "ActionListener cannot be resolved to a type"

您没有导入 class ActionListener,因为它不在 java.awt.* 中,而是在 java.awt.event.ActionListener - 供参考 https://docs.oracle.com/javase/7/docs/api/java/awt/event/ActionListener.html

But I still can't use my toggleState method from the actionperformer. How come?

在你的 void actionPerformed(ActionEvent) 中,你尝试调用一个名为 void toggleState(Color,Color,String,String) 的方法 - 但它没有在同一个 class 中声明,也不是静态导入的。

您显然想调用 class MyButton 对象 button 上的 toggleState 方法,为此您必须调用该对象上的方法,例如button.toggeState(...) 这也不会直接工作,因为你的对象 button 只在你的构造函数中已知,你必须向你的 coolgrafik class 添加一个对象属性,就像你对面板所做的那样 - 然后它应该工作很好

这是您需要在您的 coolgrafik 中更改的代码片段 class

属性:

private JPanel panel;
private JLabel label;
private MyButton button;

在你的 coolgrafik 构造函数中

//...
this.button = new MyButton(Color.green, Color.red, "RUN","STOP");
this.panel.add(this.button);
this.button.addActionListener(this);
//...

和您的 actionPerformed 方法

public void actionPerformed(ActionEvent e) {
    button.toggleState(Color.green, Color.red, "RUN","STOP");
}

让我们停下来想想你想做什么。您想在按下按钮时更改按钮的状态。

真正的问题是,谁真正负责这样做?任何监控按钮的 ActionListener 都应该专注于执行他们需要做的工作,而不是管理按钮,当按钮上有多个 ActionListener 时会发生什么?那么谁来负责呢?

如果我们让按钮自我管理呢?也就是说,按钮会监控自身并相应地更新其状态

因为无论如何您都需要管理所选状态,所以我使用了 JToggleButton,因为它在内部具有 "selected"/"unselected" 状态。

public class MyButton extends JToggleButton {

    private static final long serialVersionUID = 1L;

    public class State {
        public Color color;
        public String text;

        public State(Color color, String text) {
            this.color = color;
            this.text = text;
        }

    }

    private final State unselectedState;
    private final State selectedState;

    public MyButton(Color c1, Color c2, String s1, String s2) {

        selectedState = new State(c1, s1);
        unselectedState = new State(c2, s2);

        setContentAreaFilled(false);
        setBorderPainted(false);
        setFocusPainted(false);
        setOpaque(true);

        toggleState();

        getModel().addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                toggleState();
            }
        });

    }

    public void toggleState() {

        State state = !getModel().isSelected() ? selectedState : unselectedState;

        setText(state.text);
        setForeground(Color.WHITE);
        setBackground(state.color);

    }
}

基本上所有这些都会根据 ButtonModelselected 状态配置按钮。

您可以使用 ActionListener 并以类似的方式将其直接注册到按钮本身,但您需要管理它使用的状态