java - 为什么自引用指针或 this 超出了按钮的范围?

标签 java swing this self-reference state-pattern

我正在尝试使用 Swing 库和状态模式来生成动态 Canvas 。我的代码可以编译,但当按下按钮时,控制台上到处都是红色标记。

问题:我的自引用指针或保留字this超出了按钮的范围。我希望能够在没有任何静态的情况下访问该类。

错误:线程“AWT-EventQueue-0”中出现异常 java.lang.Error: Unresolved 编译问题: State 类型中的方法 handlePush(SP) 不适用于参数 (new ActionListener(){})

这是 Canvas 类。

public class SP extends JPanel{
private static final long serialVersionUID = 1L;

private State state = null; 

public static void main(String[] args){
    SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            createAndShowCanvasGUI();
        }
    });
}
public SP(State state ){
    this.state = state;
    init();
}
public SP(){
    this(new BlackState());
}
public static void createAndShowCanvasGUI(){
    JFrame frm = new JFrame("State Pattern");
    frm.setVisible(true);
    frm.setSize(400, 400);
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frm.setContentPane(new SP());
}
public void paintComponent(Graphics g){
    super.paintComponent(g);

    g.setColor(state.getColor());
    g.fillRect(0, 0, getWidth(), getHeight());
    repaint();
}
public void init(){
    JButton push = new JButton("Push");
    JButton pull = new JButton("Pull");

    push.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent ae){
            if(ae.getActionCommand().equals("Push")){
                state.handlePush(this);
            }
        }
    });
    pull.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent ae){
            if(ae.getActionCommand().equals("Pull")){
                state.handlePull(this);
            }
        }
    });

    add(push);
    add(pull);
}
public State setState(State newState){
    State oldState = state; 
    state = newState;
    return oldState;
}
public State getState(){
    return state; 
    }
}

这是逻辑状态设计

public abstract class State {

public abstract void handlePull(SP p);
public abstract void handlePush(SP p);
public abstract Color getColor(); 
}

这是状态的一种变体

public class GreenState extends State{
@Override
public void handlePull(SP c) {
    c.setState(new BlackState());
}
@Override
public void handlePush(SP c) {
    // TODO Auto-generated method stub
    c.setState(new RedState());
}
@Override
public Color getColor() {
    return Color.GREEN;
    }
}

最佳答案

您使用的 this 并不引用 SP 对象,而是引用 ActionListener 对象。

push.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent ae){
        if(ae.getActionCommand().equals("Push")){
            state.handlePush(this);  // *this* refers to anonymous inner-class ActionListener 
        }
    }
});

相反,您需要限定您的this引用

push.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent ae){
        if(ae.getActionCommand().equals("Push")){
            state.handlePush(SP.this);  // *this* now refers to SP
        }
    }
});

此处的更改是 SP.this 而不是 this

或者,您也可以将 this 分配给匿名类外部的最终变量,然后从内部引用该变量

final SP thisSp = this;
push.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent ae){
        if(ae.getActionCommand().equals("Push")){
            state.handlePush(thisSp);  // same as using SP.this
        }
    }
});

关于java - 为什么自引用指针或 this 超出了按钮的范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30041541/

相关文章:

c++ - Lambda`s internal this in c++

java - 错误 : "Uncompilable source code"

javascript - 去抖动和 react 窗口调整这个引用问题

java - 如何将缓冲图像中的 IndexColorModel 设置为具有某些颜色和一种透明?

java - 松开鼠标时线条在绘图程序中消失

java - 更改 JSpinner 的文本字段位置

java - Java 中的事件和监听器

java - 在非实体 java bean 中映射多个 hibernate 实体

java - 如何从 Google Cloud Platform Java Flexible Environment 下载应用程序

java - 无法从 Hashmap 获取对象的值,即使它返回相同的哈希码