2015-05-04 2 views
0

Я пытаюсь создать динамический холст, используя библиотеку Swing с шаблоном State. Мой код может компилироваться, но с красными значками по всей консоли при нажатии кнопок.Почему указатель саморегуляции или это вне сферы действия в кнопке?

Проблема: мой указатель привязки или зарезервированное слово не входит в комплект. Я хочу иметь доступ к классу без статичности.

Ошибка: Исключение в потоке "АВТ-EventQueue-0" java.lang.Error: Нерешенные проблемы компиляции: Метод handlePush (SP) в государстве типа не применяется для аргументов (новый 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; 
    } 
} 

ответ

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 
     } 
    } 
}); 
Смежные вопросы