вернуть значение переменной в main при нажатии кнопки

Я хочу, чтобы main печатал приветствие (во всплывающем диалоговом окне) каждый раз, когда нажимается кнопка. Поэтому я разработал следующую программу, но, похоже, она не работает. Программа компилируется и выполняется просто отлично, но когда я нажимаю кнопку, я не вижу всплывающего диалогового окна. Я установил геттер и сеттер логической переменной (button_clicked), значение которой проверяется в блоке main(). Помогите если знаете..

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

class abc extends JFrame implements ActionListener{

boolean button_clicked = false;
JButton b1;

abc(){
    this.setSize (400, 400);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.createUI();
}

void createUI(){
    this.setLayout(null);
    b1 = new JButton("x");
    b1.setSize(110,30);
    b1.setLocation(10,210);
    this.add(b1);

    b1.addActionListener(this);
}

public boolean isButton_clicked() {
    return button_clicked;
}

public void setButton_clicked(boolean button_clicked) {
    this.button_clicked = button_clicked;
}


public void actionPerformed(ActionEvent arg0) {
    button_clicked = true;

    //I don't want to print the dialogue box from here..
    //I want to keep everything under main()'s control.
}

}


public class tempMain extends JFrame {

public static void main(String[] args) {
    abc temp = new abc();
    temp.setVisible(true);
    while(true){
        if(temp.isButton_clicked())
            JOptionPane.showMessageDialog(null, "Hello");
    }
}

}

person Vivek Sethi    schedule 29.08.2012    source источник
comment
Вы никогда не должны использовать цикл while, подобный этому. Это имеет много конструктивных недостатков. Ваш цикл While будет потреблять ресурсы ЦП, потому что он никогда не спит. Если вы должны использовать цикл while, подобный этому, то, по крайней мере, сделайте его в новом потоке и спите поток после каждой итерации. Тем не менее, это все еще плохой дизайн.   -  person Quinma    schedule 29.08.2012
comment
Зачем комментарии в вашем коде? Если вы собираетесь настаивать на плохом дизайне вашей программы, по крайней мере, объясните причину этого.   -  person Hovercraft Full Of Eels    schedule 29.08.2012
comment
@Hovercraft: я предполагаю, что комментарий является призывом к немодальному диалогу и разыграть карту PropertyChangeListener.   -  person trashgod    schedule 29.08.2012
comment
@trash: твоя догадка так же хороша, как и любые другие, поскольку оригинальный постер, похоже, не хочет раскрывать мотивы своей просьбы.   -  person Hovercraft Full Of Eels    schedule 29.08.2012
comment
@HovercraftFullOfEels: я опубликовал свое обоснование такого дизайна в ответе ниже.   -  person Vivek Sethi    schedule 29.08.2012
comment
@Quinma: Мое приложение требует от меня этого. На самом деле оператор диалогового окна печати был просто точкой останова, чтобы проверить, возвращается ли элемент управления к основному при заданных условиях или нет. (Элемент управления возвращается к основному, но значение button_clicked никогда не становится «истинным» или что-то в этом роде). В реальной программе эта строка диалогового окна заменена кодом, который должен ожидать ввода данных пользователем. Вот почему используется такое время. Попробую реализовать в другом потоке. Спасибо за наводку..   -  person Vivek Sethi    schedule 29.08.2012
comment
@trashgod: я понятия не имею, что это такое.. Я изучу это дальше..   -  person Vivek Sethi    schedule 29.08.2012
comment
@Vivek: если вы ищете хороший модульный дизайн программы, основная логика и состояние вашей программы должны быть даже не в ваших классах графического интерфейса, а скорее в классах вашей модели, опять же а-ля MVC согласно моему другому комментарию.   -  person Hovercraft Full Of Eels    schedule 30.08.2012
comment
@Vivek: есть хороший пример этого из Hovercraft здесь, цитируется здесь.   -  person trashgod    schedule 30.08.2012
comment
@trashgod: большое спасибо за пример .. Я думаю, это сделает мою жизнь намного проще, когда я это пойму.   -  person Vivek Sethi    schedule 30.08.2012
comment
Пожалуйста, изучите соглашения об именах в Java и придерживайтесь их. И пока вы учитесь: никогда не выполняйте ручное определение размера/расположение компонентов, это исключительная задача подходящего LayoutManager.   -  person kleopatra    schedule 30.08.2012
comment
@kleopatra: что, если я хочу найти компоненты по моему желанию, а не по заранее определенному макету .. ??   -  person Vivek Sethi    schedule 30.08.2012
comment
вы никогда не захотите этого, даже если вы еще этого не знаете :-) И даже если вы действительно этого хотите: напишите LayoutManager, который делает именно то, что вы хотите.   -  person kleopatra    schedule 30.08.2012
comment
приму к сведению!!   -  person Vivek Sethi    schedule 30.08.2012


Ответы (6)


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

abc temp = new abc();
temp.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        JOptionPane.showMessageDialog(null, "Look Ma, I'm in Main...");
    }
});
temp.setVisible(true);

А в вашем abc классе...

class abc JFrame implements {
    // build your class as normal

    public void addActionListener(ActionListener listener) {
        b1.addActionListener(listener);
    }    
}
person MadProgrammer    schedule 29.08.2012
comment
Пожалуйста, не могли бы вы также объяснить мне, как эта модификация фактически передает управление главному? Здесь временный объект управляет прослушивателем событий? - person Vivek Sethi; 30.08.2012
comment
И да и нет. Прослушиватель событий находится в main, но мы предоставляем ссылку на него в temp. Когда кнопка нажата, слушатель уведомляется в основном контексте. - person MadProgrammer; 30.08.2012

Переместите вызов JOptionPane.showMessageDialog() в метод actionPerformed() и удалите объект while() в метод main.

person Dan D.    schedule 29.08.2012
comment
В коде есть специальный комментарий о том, что это решение нежелательно. Не знаю почему, но программист не хочет этого делать. - person rlinden; 29.08.2012
comment
@rlinden: оригинальный постер должен обосновать свое неудачное дизайнерское решение. Пока он этого не сделает, рекомендация Дэна будет лучшей. - person Hovercraft Full Of Eels; 29.08.2012
comment
@HovercraftFullOfEels: Дело в том, что приведенный выше фрагмент кода является частью огромной программы, в которой класс abc должен повторно использоваться для многих других будущих приложений, подобных этому. В реальном коде есть специальный класс, который занимается печатью диалоговых окон, и для поддержания объектно-ориентированной целостности мне нужно передать управление этой функции в совершенно другом классе. Класс abc просто обрабатывает часть программы с графическим интерфейсом, остальные функции модулируются для разных модулей кода. Надеюсь, вы поняли мою точку зрения. Просто ищу обходной путь.. - person Vivek Sethi; 29.08.2012
comment
@Vivek: вам нужно предоставить более конкретную информацию о ваших точных требованиях. В противном случае мы не сможем дать конкретные рекомендации, кроме того, что никоим образом не будем использовать здесь бесконечный цикл. - person Hovercraft Full Of Eels; 30.08.2012
comment
@HovercraftFullOfEels: На самом деле это длинный код. Кстати, я избавился от бесконечного цикла. Спасибо. Все, что я хочу, это то, что, как только кто-то нажимает кнопку, какая-то функция в другом классе получает информацию и на основе значений в текстовых полях (при условии, что есть текстовые поля, в которые пользователь вводит значения), выполняет некоторую бизнес-логику и дает вывод соответственно.. Не хочу, чтобы все происходило под действием actionPerformed(). Я прочитаю ваш пример MVC, опубликованный trashdog в комментарии выше. Еще раз спасибо. - person Vivek Sethi; 30.08.2012

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

Основная идея для вашего кода будет заключаться в следующем:

  • Объявить класс обработчика событий
  • Зарегистрируйте экземпляр класса обработчика событий в качестве прослушивателя с вашим JButton
  • Включите код, который реализует методы в интерфейсе прослушивателя. В вашем случае вы должны переопределить actionPerformed() и написать свою логику там, чтобы отобразить диалоговое окно. "Как создавать диалоги" будет для вас еще одним полезным руководством. .
person Sujay    schedule 29.08.2012
comment
Дело в том, что приведенный выше фрагмент кода является частью огромной программы, в которой класс abc будет повторно использоваться во многих других будущих приложениях, подобных этому. В реальном коде есть специальный класс, который занимается печатью диалоговых окон, и для поддержания объектно-ориентированной целостности мне нужно передать управление этой функции в совершенно другом классе. Класс abc просто обрабатывает часть программы с графическим интерфейсом, остальные функции модулируются для разных модулей кода. Надеюсь, вы поняли мою точку зрения. Просто ищу обходной путь.. - person Vivek Sethi; 29.08.2012
comment
@VivekSethi: Итак, вы в основном хотите, чтобы, когда пользователь нажимает JButton, управление передавалось другому объекту. Будет ли ваш класс abc ссылаться на экземпляр этого отдельного класса? Если да, то вы можете переопределить actionPerformed() и вызвать соответствующий метод другого класса. - person Sujay; 30.08.2012

Как отметил @Quinman, ваш дизайн кода действительно ошибочен. Я понимаю, что вы не хотите помещать JOptionPane в метод actionperformed по какой-то личной причине, которую я не понимаю. Основываясь на этой предпосылке, я думаю, что лучшим решением было бы создать обратный вызов, то есть сделать так, чтобы ваш JFrame знал основной класс и вызывал его при нажатии кнопки.

Можно сделать этот механизм независимым от основного класса. Ознакомьтесь с шаблоном проектирования Observer, чтобы понять, как это сделать.

В вашем коде также есть еще один недостаток - при нажатии кнопки я получаю бесконечные сообщения Hello. Чтобы этого избежать, вы должны установить для переменной button_clicked значение false. Я упомянул это только как общий совет, потому что на самом деле вам действительно следует избавиться от напряженного ожидания, которое вызывает ваше время ожидания.

person rlinden    schedule 29.08.2012
comment
Второй недостаток легко исправить. Спасибо, хотя .. Мое приложение действительно требует, чтобы я ждал ввода пользователя навсегда (что в конечном итоге попадет под действие while (true) {}, а не строку диалогового окна). Но мне нравится дизайн Observer. Вики это. Спасибо.. - person Vivek Sethi; 30.08.2012

Возможно, вы ищете немодальное диалоговое окно. В этом примере главная панель с именем Observer слушает ObservedPanel в диалоговом окне. При использовании PropertyChangeListener любые изменения, внесенные в диалоговое окно, немедленно отражаются на главной панели.

person trashgod    schedule 29.08.2012
comment
Я думаю, вы правы, это или просто шаблон слушателя в целом - это то, что он ищет. 1+ - person Hovercraft Full Of Eels; 30.08.2012

Судя по предоставленным вами комментариям, вы хотите повторно использовать свой класс abc (который имеет очень плохое имя и не соответствует стандартам именования Java) для нескольких разных целей, поэтому вы не хотите включать код, который выполняется, когда вы нажмите кнопку в классе abc.

Для этого есть несколько решений (где первое является моим предпочтительным)

  • Передайте Action в конструкторе вашего класса abc и соедините Action с JButton. Таким образом, класс, создающий экземпляр abc, отвечает за поведение при нажатии кнопки.
  • сделайте abc абстрактным и позвольте вашему ActionListener вызывать этот абстрактный метод. Затем вы можете создавать конкретные реализации этого класса каждый раз, когда вам нужно другое поведение.

Дополнительные примечания к вашему коду:

  • избавиться от этой петли while( true )
  • избавиться от макета null и использовать вместо него LayoutManager
  • Компоненты Swing должны быть созданы и доступны в потоке отправки событий. Дополнительные сведения см. в руководстве по Параллелизм в Swing.
person Robin    schedule 30.08.2012
comment
Спасибо .. Я думаю, что первый должен сделать свое дело. Любой соответствующий пример кода, если вы могли бы предоставить... любые ссылки...?? - person Vivek Sethi; 30.08.2012
comment
@VivekSethi См. руководство по действиям. - person Robin; 30.08.2012