Подтвердить что ты не робот

Как добавить прослушиватель действий, который прослушивает несколько кнопок

Я пытаюсь понять, что я делаю неправильно с прослушивателями действий. Я следую нескольким учебникам, и все же netbeans и eclipse дают мне ошибки, когда я пытаюсь использовать прослушиватель действий.

Ниже приведена простая программа, в которой я пытаюсь заставить кнопку работать.

Что я делаю неправильно?

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;


public class calc extends JFrame implements ActionListener {



    public static void main(String[] args) {

        JFrame calcFrame = new JFrame();

        calcFrame.setSize(100, 100);
        calcFrame.setVisible(true);

        JButton button1 = new JButton("1");
        button1.addActionListener(this);

        calcFrame.add(button1);
    }

    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == button1)
    }  

}

прослушиватель действий никогда не регистрируется, потому что с if(e.getSource() == button1) он не может видеть button1, ошибки говорят, что не могут найти символ.

4b9b3361

Ответ 1

В статическом методе нет указателя this. (Я не верю, что этот код даже скомпилируется.)

Вы не должны делать это в статическом методе, таком как main(); задайте вещи в конструкторе. Я не компилировал или не запускал это, чтобы проверить, действительно ли он работает, но попробуйте.

public class Calc extends JFrame implements ActionListener {

    private Button button1;

    public Calc()
    {
        super();
        this.setSize(100, 100);
        this.setVisible(true);

        this.button1 = new JButton("1");
        this.button1.addActionListener(this);
        this.add(button1);
    }


    public static void main(String[] args) {

        Calc calc = new Calc();
        calc.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == button1)
    }  

}

Ответ 2

Я поражен тем, что никто не упомянул об использовании команды action. Это довольно стандартный способ связывания источников и слушателей. Его действительно полезно, если:

  • у вас есть несколько источников событий, которые должны делать то же самое (например, если вы хотите, чтобы использование могло нажимать клавишу ввода в текстовом поле в качестве альтернативы нажатию кнопки рядом с ней)
  • у вас нет ссылки на компонент, генерирующий событие

см;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;    
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class DontExtendJFrame implements ActionListener {

  private enum Actions {
    HELLO,
    GOODBYE
  }

  public static void main(String[] args) {

    DontExtendJFrame instance = new DontExtendJFrame();

    JFrame frame = new JFrame("Test");
    frame.setLayout(new FlowLayout());
    frame.setSize(200, 100);

    JButton hello = new JButton("Hello");
    hello.setActionCommand(Actions.HELLO.name());
    hello.addActionListener(instance);
    frame.add(hello);

    JButton goodbye = new JButton("Goodbye");
    goodbye.setActionCommand(Actions.GOODBYE.name());
    goodbye.addActionListener(instance);
    frame.add(goodbye);

    frame.setVisible(true);
  }

  @Override
  public void actionPerformed(ActionEvent evt) {
    if (evt.getActionCommand() == Actions.HELLO.name()) {
      JOptionPane.showMessageDialog(null, "Hello");
    } else if (evt.getActionCommand() == Actions.GOODBYE.name()) {
      JOptionPane.showMessageDialog(null, "Goodbye");
    }
  }
}

Ответ 3

Вот модифицированная форма источника, основанная на моем комментарии. Обратите внимание, что графические интерфейсы должны быть построены и обновлены на EDT, хотя я не зашел так далеко.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JFrame;

public class Calc {

    public static void main(String[] args) {

        JFrame calcFrame = new JFrame();

        // usually a good idea.
        calcFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        final JButton button1 = new JButton("1");
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                JOptionPane.showMessageDialog(
                    button1, "..is the loneliest number");
            }
        });

        calcFrame.add(button1);

        // don't do this..
        // calcFrame.setSize(100, 100);

        // important!
        calcFrame.pack();

        calcFrame.setVisible(true);
    }
}

Ответ 4

Вам рассказали, как сортировать вашу ближайшую проблему, но я думаю, что здесь есть более важные проблемы.

  • придерживаться условных обозначений. Даже для кода выброса. Это означает начальные случаи для имен классов.

  • Не расширяйте классы, которые вам не нужны. JFrame редко следует расширять. Фактически, вы не создаете экземпляр вашего производного класса!!!

  • Не связывайте кучу вещей в один класс. В частности, вы должны обычно только подтип не более одного основного класса или интерфейса за один раз (такие вещи, как Comparable не включены).

  • Всегда взаимодействуйте, включая конструкцию, Swing/AWT GUI на AWT Event Dispatch Thread (EDT). Это уродливое и многословное, но для вас Java.

  • Проверка источника события - это взломать. Слушатели невелики, поэтому вы не можете даже претендовать на изнурительное оправдание.

Итак:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;


public class Calc {
    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
            runEDT();
        }});
    }
    private static void runEDT() {
        assert java.awt.EventQueue.isDispatchThread();

        JFrame frame = new JFrame();

        frame.setSize(100, 100);

        JButton button1 = new JButton("1");
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                ...
            }
        });

        frame.add(button1);

        frame.setVisible(true);
    }
}

Если вам нужно получить доступ к любой из переменных из входящего метода в слушателе, сделайте их final.

Ответ 5

Проблема в том, что button1 является локальной переменной. Вы можете сделать это, просто изменив способ добавления actionListener.

button.addActionListener(new ActionListener() {  
            public void actionPerformed(ActionEvent e)
            {
                //button is pressed
                System.out.println("You clicked the button");
            }});

Или вы делаете button1 глобальную переменную.

Ответ 6

Первая проблема заключается в том, что button1 является локальной переменной метода main, поэтому метод actionPerformed не имеет к ней доступа.

Вторая проблема заключается в том, что интерфейс ActionListener реализуется классом calc, но экземпляр этого класса не создается в методе main.

Обычный способ сделать то, что вам нужно, - создать экземпляр calc и сделать button1 поле класса calc.

Ответ 7

Вы объявляете button1 в основном методе, поэтому вы не можете получить к нему доступ в actionPerform. Вы должны сделать его глобальным в классе.

 JButton button1;
 public static void main(String[] args) {

    JFrame calcFrame = new JFrame();

    calcFrame.setSize(100, 100);
    calcFrame.setVisible(true);

    button1 = new JButton("1");
    button1.addActionListener(this);

    calcFrame.add(button1);
}

public void actionPerformed(ActionEvent e) {
    if(e.getSource() == button1)
}

Ответ 8

Во-первых, правильно запустите JFrame с помощью super() и конструктора затем добавьте исполнители действий в рамку и добавьте кнопки.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;


public class Calc extends JFrame implements ActionListener {
    JButton button1 = new JButton("1");
    JButton button2 = new JButton("2");

    public Calc()
    {
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         setSize(100, 100);
         button1.addActionListener(this);
         button2.addActionListener(this);
         calcFrame.add(button1);
         calcFrame.add(button2);
    }
    public void actionPerformed(ActionEvent e)
    {
        Object source = e.getSource();
        if(source == button1)
        {
            \\button1 code here
        } else if(source == button2)
        {
            \\button2 code here
        }
    } 
    public static void main(String[] args)
    {

        JFrame calcFrame = new JFrame();
        calcFrame.setVisible(true);
    }
}

Ответ 9

Я использую "e.getActionCommand(). содержит (CharSecuence s)", так как я исхожу из контекста MVC, и Button объявлен в классе View, но вызов actionPerformed происходит в контроллере.

public View() {
    ....
    buttonPlus = new Button("+");
    buttonMinus = new Button("-");
    ....
}

public void addController(ActionListener controller) {
    buttonPlus.addActionListener(controller);
    buttonMinus.addActionListener(controller);
}

Мой класс контроллера реализует ActionListener, и поэтому при переопределении actionPerformed:

public void actionPerformed(ActionEvent e) {
    if(e.getActionCommand().contains("+")) {
        //do some action on the model
    } else if (e.getActionCommand().contains("-")) {
       //do some other action on the model
    }
}

Я надеюсь, что этот другой ответ также будет полезен.

Ответ 10

Здесь есть хорошие ответы, но позвольте мне обратиться к более глобальному моменту добавления слушателя действия, который слушает несколько кнопок.

Есть два популярных подхода.

Использование прослушивателя общего действия

Вы можете получить источник действия в своей реализации actionPerformed(ActionEvent e):

JButton button1, button2; //your button

@Override
public void actionPerformed(ActionEvent e) {

    JButton actionSource = (JButton) e.getSource();

    if(actionSource.equals(button1)){
        // YOU BUTTON 1 CODE HERE
    } else if (actionSource.equals(button2)) {
        // YOU BUTTON 2 CODE HERE
    }
}

Использование ActionCommand

При таком подходе вы устанавливаете поле actionCommand своей кнопки, которое позже позволит вам использовать switch:

button1.setActionCommand("actionName1");
button2.setActionCommand("actionName2");

И позже:

@Override
public void actionPerformed(ActionEvent e) {
    String actionCommand = ((JButton) e.getSource()).getActionCommand();

    switch (actionCommand) {
        case "actionName1": 
            // YOU BUTTON 1 CODE HERE
        break;
        case "actionName2": 
            // YOU BUTTON 2 CODE HERE
        break;
    }
}

Проверьте, чтобы узнать больше о кнопках JFrame, слушателях и полях.