button.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
label.setText("Accepted");
}
});
In the code above we are defining what will happen when we press the button. This is all good but I wanna create new ActionListener and then add it to my button.
Normally in JButton I can just add ActionListener like this:
button.addActionListener(someControllerClass.createButtonListener());
In code above createButtonListener() returns ActionListener.
My question is: What is the equivalent of JButton addActionListener ?
If you want to e.g. reuse an EventHandler, define it like described in JavaFX Documentation as:
EventHandler<ActionEvent> buttonHandler = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
label.setText("Accepted");
event.consume();
}
};
You can now add your defined buttonHandler to the onAction of your button via:
button.setOnAction(buttonHandler);
And citing from the documentation providing the remove option for completeness:
To remove an event handler that was registered by a convenience method, pass null to the convenience method, for example, node1.setOnMouseDragged(null).
Resulting for you in:
button.setOnAction(null)
The documentation furthermore provides some examples how to add handler for specific events - it's a good read.
Just the same approach, but easier with lamda expressions:
button.setOnAction(event -> buttonSaveClicked());
I think this is how I should do. Creating the handler:
public EventHandler<Event> createSolButtonHandler()
{
btnSolHandler = new EventHandler<Event>() {
#Override
public void handle(Event event) {
System.out.println("Pressed!");
biddingHelperFrame.getBtnSag().setVisible(false);
}
};
return btnSolHandler;
}
Adding Handler to button:
btnSol.addEventHandler(MouseEvent.MOUSE_CLICKED, biddingHelperFrameController.createSolButtonHandler());
Related
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.
Suppose I want to have my program to react same way, say, navigate to next record, in response to different events, including pressing a key, clicking GUI button, selecting menu item and so on.
This was done with "actions" in Swing.
Can I materialize this concept in some program object in JavaFX?
Or I should make a porridge of interacting objects?
Action is still there in JavaFX. Example belows how to create an action, bind it to a keyboard shortcut and share between two different elements.
Button go = new Button("Go");
EventHandler<ActionEvent> goAction = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
browser.load(location.getText(), new Runnable() {
#Override
public void run() {
System.out.println("---------------");
System.out.println(browser.getHTML());
}
});
}
};
...
MenuItem menuItem = new MenuItem("Go!");
menuItem.setAccelerator(new KeyCodeCombination(KeyCode.G, KeyCombination.CONTROL_DOWN));
go.setOnAction(goAction);
menuItem.setOnAction(goAction);
JavaFX provides many events. You also do this with setOn() method:
button.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
// code here
}
});
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.
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.
Perhaps I am going about this the wrong way. Let me know
Using Swing and AWT, I have several buttons set up on a frame and they each have an ActionListener corresponding to their specific function I.E.
JButton foo_button = new JButton("Foo-Me");
foo_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Fancy schmancy code work
}
})
JButton bar_button = new JButton("Bar None");
bar_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Fancy schmancy code work
}
})
So each of these buttons do their own thing. However, what if I want all the buttons to do a certain thing (the same exact method for each), in my case, clear a label, before they do their own thing.
Obviously I could add whatever_label.setText("") to each actionPerformed() but that entails a lot of duplication, something I'm not so much a fan of.
Oh Java and Swing gurus come to my aid.
You can subclass your own implementation of ActionListener:
private static abstract class MyListener implements ActionListener {
#Override
final public void actionPerformed(ActionEvent evt) {
theSameTask();
uniqueTask(evt);
}
private void theSameTask() {
// the identical task
}
public abstract void uniqueTask(ActionEvent evt);
}
And then, the new listeners will look like this:
JButton bar_button = new JButton("Bar None");
bar_button.addActionListener(new MyListener() {
#Override public void uniqueTask(ActionEvent evt) {
//Fancy schmancy code work
}
});
Another possibility is to use the 'Decorater' pattern, and write an ActionListener decorator for the common behavior. Your code would then be of the form
bar_button.addActionListener(new MyActionListenerDecorator( new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Fancy schmancy code work
} }) );
I think the best way to do this is to use Action. That way all the listeners always do the same thing.