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

Why is self-referencing pointer or this out of scope in button?

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

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

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

这是canvasclass。

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 分配给匿名 class 外部的最终变量,然后从内部引用该变量

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
        }
    }
});