我正在尝试使用 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/