我尝试使用带有State模式的Swing库生成动态画布。我的代码可以编译,但是当按下按钮时,控制台上会出现红色标记。
问题:我的自引用指针或保留字此超出了按钮的范围。我希望能够在没有任何静态的情况下访问该类。
错误:线程中的异常" AWT-EventQueue-0" java.lang.Error:未解决的编译问题: 类型State中的方法handlePush(SP)不适用于参数(new ActionListener(){})
这是画布类。
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;
}
}
答案 0 :(得分:5)
您对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
}
}
});