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

Я пытаюсь понять, что я делаю неправильно с помощью слушателей. Я следую нескольким учебникам, и все же 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 , ошибки говорят, что не могут найти символ.

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) } } 

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

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

видеть;

 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"); } } } 

Вот измененная форма источника, основанная на моем комментарии. Обратите внимание, что графические интерфейсы должны быть построены и обновлены на 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); } } 

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

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

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

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

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

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

  • Не связывайте кучу вещей в один class. В частности, вы должны, как правило, только подтип не более одного основного classа или интерфейса за один раз (такие вещи, как 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 .

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

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

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

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

  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) } 

Во-первых, правильно запустите 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); } } 

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

 public View() { .... buttonPlus = new Button("+"); buttonMinus = new Button("-"); .... } public void addController(ActionListener controller) { buttonPlus.addActionListener(controller); buttonMinus.addActionListener(controller); } 

Мой class 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 } } 

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

  • Как закрыть приложение Java Swing из кода
  • Получение значения RGB из-под курсора мыши
  • Рисование прямоугольника, который не исчезнет в следующей краске
  • Граница с закругленными углами и прозрачностью
  • Как сделать редактор таблиц JComboBox иметь дизайн обычного JComboBox?
  • Передача значений между JFrames
  • Текст центра Java в прямоугольнике
  • Лучшая практика настройки местоположений JFrame
  • Нарисуйте строку в JPanel с нажатием кнопки на Java
  • Слайд JPanel Содержимое в JForm на Java
  • Как добавить кнопку в строке JTable в Swing java
  • Interesting Posts

    Как отредактировать частичный формат в Rails?

    Вывод строк Excel в ряд текстовых файлов

    USB 3.0 поддерживает обратную совместимость с устройствами 2.0?

    Должен ли я использовать одиночные двоеточия (:) или двойные двоеточия (: :) для псевдо-элементов до, после, первой буквы и первой строки?

    Как подключить общий ресурс NFS в Windows 8?

    Какой редактор файлов субтитров для файлов .srt поддерживает синхронизацию?

    Программно добавить один вид ниже другого в относительной компоновке

    Способы определения, является ли Internet-выход маршрутизатором или интернет-провайдером?

    Ansible – запись нескольких строк в файл

    Метод перегрузки web api на основе типа параметра

    Расчет полосы пропускания

    получить тип NSNumber

    Какой IP-адрес возвращается службе DNS?

    Есть ли уловка для подключения и использования Windows 8 / 8.1 с Samba 4 (4.1.6)?

    Как получить размер фонового изображения в jQuery?

    Давайте будем гением компьютера.