Calling actionlistener of a disabled JButton - java

I was working on something in which I need to call the actionlistner of a disabled jbutton from another function. How it can be done?

Make a new method which will be called by the disabled jbutton, write all the code there which will be executed when you click the button. You can not call the actionlistiner in other way.
...
JButton disButton = new JButton("Disabled");
disButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
//do not write any statement here
doSomething();
}
});
...
private void doSomething() {
//all action event execution code here
System.out.println("I am in the action listener");
}
....
//in the other method or another button click event call doSomething()
//even button is disables like
JButton Button = new JButton("Submit");
Button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
doSomething();
}
});
//or from another method
public void method() {
doSomething();
}

You cannot call/do actions on disabled GUI controls.That is what actually disable means
What you can do is create a separate common method like doClick() and call where ever you need.

Related

Java - Doing something when button clicked, then revert it

Ok, so I'm doing a Java window (a JFrame, doesn't really matter what it is for) and I have a button on it. What I want to approach is when the button is clicked, it changes its text, then the app does something, and when it's finished the button gets its initial text back.
Something like this...
JButton myButton = new JButton("Initial");
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
((JButton) e.getSource()).setText("New");
//Do other things
//Do more other things
((JButton) e.getSource()).setText("Initial");
}
});
That's what I've tried so far, but I know it doesn't work as expected (all the code executes. I'm not really an expert and I'm doing this things to learn, so I have no clue if there's a way to do it or not.
I've already looked for a solution to this in the web but I've not found anything (maybe I didn't search properly), so I hope there's someone who can help me with this!
PS: Sorry if my English is not perfect, I know about it. Ask me if something isn't clear about the question. Thanks to all!
Kevin.
EDIT: The app is a sudoku solver, so it takes a while //doing other things. Thats why I'm trying to change the solve button text (so it sais it is solving and when it finished it says solved).
Your logic is not wrong! Take a look at my example below:
public class MainFrame extends JFrame {
public MainFrame() {
setMinimumSize(new Dimension(200, 100));
JButton myButton = new JButton("Initial");
add(myButton);
myButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final JButton triggerBtn = (JButton) e.getSource();
final String originalValue = triggerBtn.getText();
triggerBtn.setText("New");
JOptionPane.showMessageDialog(null, "Speak softly and carry a big stick and you will go far.");
triggerBtn.setText(originalValue);
}
});
}
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MainFrame mainFrame = new MainFrame();
mainFrame.setVisible(true);
}
});
}
}
If you run this you will see that the button is changed. If you were to change the showMessageDialog line to Thread.sleep(10*1000), you would not see a change! This is because you're running the event on the dispatcher thread and the text, even though it is changed, will not allow the change event to be triggered until your method finishes.
Consider the following alternative if the work you're doing is on the same thread:
myButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final JButton triggerBtn = (JButton) e.getSource();
final String originalValue = triggerBtn.getText();
triggerBtn.setText("New");
SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
Thread.sleep(10*1000);
return null;
}
#Override
protected void done() {
triggerBtn.setText(originalValue);
}
};
sw.execute();
}
});
This sets the text, and launches a SwingWorker to run the job asynchronously. Once finished, the dispatcher thread will update the text without requiring the dispatcher thread to be tied up waiting for it to finish (and so events are therefore handled properly).
Let me know if that works for you!
Have you tried with:
JButton myButton = new JButton("Initial");
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
myButton.setText("New");
//Do other things
//Do more other things
myButton.setText("Initial");
}
});
In your example you're missing actionPerformed and you're not accessing button directly (I can't say what's e in your example)
Just save your current text in a local variable and set it back after you've performed your other actions.
You should also make sure it's really the button that you clicked or at least check instanceof JButton before casting.
final JButton myButton = new JButton("Initial");
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == myButton) {
String initialText = myButton.getText();
myButton.setText("New");
// Do other things
// Do more other things
myButton.setText(initialText);
}
}
});
You were also missing out on your actionPerformed method, the code in the question won't compile - I guess you just wrote it in the editor.

Member Object Calling Class Method

I hope this question is not really a repetition of an existing one! I searched and found no good answer to my question. Here it is:
I have a class MyGame that contains a Button member object. Whenever that button is clicked, MyGame should do something.
class MyGame extends Application {
MyBoard board = new MyBoard();
MyButton btn = new MyButton();
public MyGame() {
board.add(btn);
}
// this method should be called whenever the button is clicked!
public void doSomething() {
doingSomething();
}
}
class MyButton extends Button {
int someData;
// some code here
public MyButton() {
this.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
MyGame.doSomething(); // ==> NOT POSSIBLE!!!
}
});
}
}
Would an interface be the best way to make the communication between the MyButton and MyGame go? If so, how would you do it?
I don't want to hand over a reference of MyGame object to the MyButton object! I think this is not a good way to resolve this problem.
I appreciate any suggestions and help!
Cheers
In the constructor of MyGame you can add an ActionListener to btn that will be called when an action is performed on the button.
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Insert thing to do within MyGame here
}
});
One way is to do it the other way around (game should be a member of button). I know that you think "it is not a good way to resolve this problem", but you think wrong, there is really nothing wrong with it.
Alternatively, move the registering of the listener out of the button's constructor into the game itself:
public MyGame() {
btn.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent arg0) { doSomething(); }
});
}
Make the "button action" an interface that can be passed to the constructor when creating MyButton. Example:
public MyButton(final Runnable action) {
this.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
action.run(); // POSSIBLE!!!
}
});
}
or save the action in a MyButton instance field:
public MyButton(Runnable action) {
buttonAction = action; // make buttonAction an instance field
this.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
buttonAction.run();
}
});
}
Then when MyGame creates a new MyButton, the MyGame gets to tell the button what to do when the button is clicked:
MyButton btn = new MyButton(new Runnable() {
#Override
public void run() {
MyGame.this.doSomething();
}
}
or in Java 8:
MyButton btn = new MyButton(this::doSomething);
NOTE: I haven't yet tested this. I think I got the syntax right, but I may have made a mistake. You may need to assign btn in the MyGame constructor rather than in an initializer expression.
This is a generalized approach (dependency injection?) that works in lots of situations. There may be other solutions specific to Button (or other Swing components for which a listener mechanism is already defined). But this mechanism reduces coupling, because the MyButton doesn't really need to know anything about who created it, and the MyGame doesn't need to know what the MyButton plans to do with the Runnable action. Some other possible solutions involve having MyGame doing some of MyButton's work, which increases coupling.

ActionListener in java performs action on the second click

I am programming my first complex application in Java, Swing. When I have added ActionListener to my JButton.
ActionListener changeButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e){
if(startButton.getText() == "Spustit") {
startButton.setText("STOP");
} else {
startButton.setText("Spustit");
}
}
}
I am adding ActionListener to the button itself
private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
startButton.addActionListener(changeButton);
}
Can you tell me where I coded ActionListener badly?
Thanks to all!
You have coded the ActionListener good enough to be working, at least, for the action listener itself. The problem is that you are adding the action listener after an event (your second sample), thus your action listener will get called the second time you will click it.
A solution is very simple:
JButton button = new JButton();
button.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//...
}
});
Now the action listener should activate on the first click if you directly add a new ActionListener to the button, not after an action is performed
Why are you adding the actionlistener in actionPerformed? I think you should do something like this:
public static void main(String[] args) {
final JButton startButton = new JButton("Spustit");
ActionListener changeButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (startButton.getText() == "Spustit") {
startButton.setText("STOP");
} else {
startButton.setText("Spustit");
}
}
};
startButton.addActionListener(changeButton);
// Add it to your panel where you want int
}

Activities in button

where can i insert the class calling here in my code?
what i would like to happen is that when i click the button, the maze.java(the class that i would like to call) would run? ,thanks!
public class Main extends Applet {
Button mazebutton;
Button hexbutton;
public void init() {
mazebutton = new Button("Create a maxe");
hexbutton = new Button ("Create a hexagonal Maze");
mazebutton.setBounds(20,20,100,30);
hexbutton.setBounds(20,70,100,40);
add(mazebutton);
add(hexbutton);
}
}
you need to just makethe code like
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//here you need to call a function that you need to make
//on "maze.java" that returns the values of each variable
//or starts by launching other function in the same class
//(maze.java) that activates the game
}
});

If 2 action listener are registered for same JButton, then prevent execution of listener2 on certain condition

I have a JButton, two action listeners are registered for it. Listener1 will be executed first because it is registered first.
So, what i need is, In a condition matches in the Listener1 then the code of Listener2 should not be executed.
Would you please help me, how to prevent execution of Listener2 if condition matches in Listener1.
JButton jbtn=new JButton();
jbtn.addActionListener(new ActionListener() {
//Listener1
public void actionPerformed(ActionEvent e)
{
if(condition==true){
//do not execute the code of listner2
//stop further executeion of current action
}
}
});
jbtn.addActionListener(new ActionListener() {
//Listener2
public void actionPerformed(ActionEvent e)
{
//some code
}
});
It looks to me as if you may be over-complicating things. Why not simply use one ActionListener or AbstractAction and nest the if block inside:
jbtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(condition) { // no need for the == true part!
myMethod1();
} else { // condition is false
myMethod2();
}
}
});
It's easy. AbstractButton has the method getActionListeners(). So you can remove any listener, added before. Then you can create your listener, which can call the another listener (which was removed from the button).
Something like this:
public class MyActionListener implements ActionListener {
private ActionListener anotherListener;
public MyActionListener(ActionListener another) {
anotherListener = another;
}
public void actionPerformed(ActionEvent ae) {
doSomething();
if (myCondition) {
anotherListener.actionPerformed(ae);
}
}
}
Depending on the exact event you are firing, sometimes you can use consume() / isConsumed(). (e.g. java.awt.event.InputEvent)
Your listeners check for isConsumed() before doing anything, and call consume().
In this way, only one listener will get the event, assuming that they all follow this convention. So if one listener is from an outside or library class this won't help. And the order of which Listener gets the event first may not be under your control.
So #Hovercraft's option may be better. Depends on how decoupled you wish to be.

Categories

Resources