سؤال

I want that main should print hello (in a pop up dialogue box) everytime the button is clicked. So I designed the following program but it doesn't seem to work. The program compiles and executes just fine but when I click the button, I don't see the any dialogue box popping up. I have put in place the getter and setter of the boolean variable (button_clicked) whose value is being tested in the main() block. Please help if you know..

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

}
هل كانت مفيدة؟

المحلول

As has already been pointed out by a number of people, you approach and design are flawed. I won't go into further as it has already been dealt with, but as a suggestion you could try...

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

And in your abc class...

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

    public void addActionListener(ActionListener listener) {
        b1.addActionListener(listener);
    }    
}

نصائح أخرى

Move the JOptionPane.showMessageDialog() call under the actionPerformed() method and delete the while() thing under the main method.

You might want to read about "How to Write an Action Listener" to help you implement an ActionListner in your code.

The basic idea for your code would be to:

  • Declare an event handler class
  • Register an instance of the event handler class as a listener with your JButton
  • Include code that implements the methods in listener interface. In your case, you would over-ride actionPerformed() and write your logic over there to show a dialog box. "How to Make Dialogs" would be another useful tutorial for you.

As @Quinman pointed out, your code design is really flawed. I understand that you do not want to put the JOptionPane under the actionperformed method for some personal reason which I don't understand. Based on that premise, I think that the best solution would be to create a callback, that is, make your JFrame know the main class and call it when the button is clicked.

It is possible to make this mechanism independent of the main class. Please check the Observer design pattern in order to understand how to do that.

Your code also has another flaw - when the button is clicked I get infinite Hello messages. In order to avoid that, you should set the button_clicked variable to false. I only mention that as a general tip, for in truth you really should get rid of the busy wait that your while is causing.

You may be looking for a modeless dialog. In this example, the main panel, named Observer, listens to an ObservedPanel in a dialog. By using a PropertyChangeListener, any changes made to the dialog are immediately reflected in the main panel.

Judging from the comments you provided, you want to reuse your abc class (which has a very poor name and does not comply to the Java naming standards) for several different purposes, so you do not want to include the code which is executed when you press the button in the abc class.

There are multiple solutions for this (where the first is my preferred one)

  • Pass an Action in the constructor of your abc class and couple that Action to the JButton. This way the class which constructs the abc instance is responsible for the behavior when the button is pressed
  • make abc abstract and let your ActionListener call that abstract method. You can then make concrete implementations of this class each time you want different behavior.

Further notes on your code:

  • get rid of that while( true ) loop
  • get rid of the null layout and use a LayoutManager instead
  • Swing components should be created and accessed on the Event Dispatch Thread. Consult the Concurrency in Swing tutorial for more information
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top