GUI в Java, частные классы для слушателя не работают - PullRequest
1 голос
/ 13 сентября 2010

Я пытаюсь создать графический интерфейс на Java, используя что-то вроде этого:

public class GUIApp
{
    DrawingPanel dp;
    buttonPanel bp;
    ova = Oval;
 public GUIApp()
    {
        JFrame win = new JFrame("Drawing App");
        dp = new DrawingPanel();
        bp = new buttonPanel(this);

    //Settings for panels and frame

        ova = new Oval(100,100,100,100);

      }
      public void setOval(int c){
        //Change color of oval
      }
  }

Тогда в моем классе buttonPanel у меня есть это:

public class ButtonPanel extends JPanel
{

    private JButton btnRed, btnGreen, btnBlue;

    public ButtonPanel(GUIApp d)
    {

        ButtonListener listener = new ButtonListener();
        btnRed = new JButton("Red");
        btnGreen = new JButton("Green");
        btnBlue = new JButton("Blue");

        btnRed.addActionListener(listener);
        btnGreen.addActionListener(listener);
        btnBlue.addActionListener(listener);

        setBackground(Color.lightGray);
        GridLayout grid = new GridLayout(3,1);
        add(btnRed,grid);
        add(btnGreen,grid);
        add(btnBlue,grid);
    }

    private class ButtonListener implements ActionListener{

        public void clickButton(ActionEvent event) {
            Object location = event.getSource();
            if (location == btnRed){
                d.setOval(1);
            }
            else if(location == btnGreen){
                d.setOval(2);
            }
            else if(location == btnBlue){
                d.setOval(3);
        }
        }

}
}

Но netbeans выдает ошибку для внутреннего класса ButtonListener, и я не знаю почему. Я также не знаю, как правильно вызвать setOval из этого класса в класс GUIApp. Что я делаю не так?

1 Ответ

3 голосов
/ 13 сентября 2010

Проблема в том, что при реализации ActionListener вы должны определить метод actionPerformed(ActionEvent e);Вы не сделали этого в вашем ButtonListener классе.Вы не можете присвоить методу имя, которое хотите (как вы сделали с clickButton), поэтому вы должны просто переименовать ваш clickButton метод в actionPerformed (и продолжить и добавить аннотацию @Override тоже),

Теперь, чтобы вызвать d.setOval из своего внутреннего класса, d должен находиться в области видимости при вызове метода actionPerformed.Есть несколько способов добиться этого: вы можете сделать d переменной-членом вашего класса, или вы можете определить свой ButtonListener как анонимный класс.

Например, если вы сохранили dв качестве переменной-члена ваш код будет выглядеть следующим образом:

public class ButtonPanel {
 private GUIApp d;

 public ButtonPanel(GUIApp d) {
  this.d = d;
  // The rest of your code here...
 }
}

Или вы можете использовать анонимный класс, например:

public ButtonPanel(GUIApp d) {
 ActionListener listener = new ActionListener(){
  @Override
  public void actionPerformed(ActionEvent event) {
   Object location = event.getSource();
   if (btnRed.equals(location)) {
    d.setOval(1);
   } else if (btnGreen.equals(location)) {
    d.setOval(2);
   } else if (btnBlue.equals(location)) {
    d.setOval(3);
   }
  }
 };
 // The rest of your constructor code here ...
}

Примечание: Примечаниекак я также изменил использование == на equals() для равенства объектов.

...