How to get the source of all JButton components from an ActionEvent? - java

I'm trying to implement a simple window that contain two buttons Yes and No.
When clicking on Yes I want to disable the No button and when pressing on No I want to disable the Yes button.
I've implemented:
JButton btnYes = new JButton("Yes");
contentPane.add(btnYes);
btnYes.setActionCommand("Yes");
btnYes.addActionListener(this);
...the same for the No button...
Now I'm catching the event in this method:
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("Yes"))
{
//I know how to get the button that caused the event
//but I don't know how to disable the OTHER button.
JButton source = (JButton)e.getSource();
//Handle the source button...
}
}
In the above method I have an access to the button that caused the event, but not to the other button.
What is the best way of getting the buttons?

You should just implement ActionListener as a nested class of your Dialog's class, in this case you will have full access to all fields of outer class (in which you should store reference to buttons when your create them).
The bad dirty solution (that should NOT be used) still exists: to navigate to battens through getParent() of JButton and then through getChildren() of parents childrens. Just to show that it is possible anyway.

You could use a JButton array as class member variable and to check which instance didnt cause the event:
for (JButton button: buttonArray) {
if (button != source) {
button.setEnabled(false); // disable the other button
}
}

Related

How to check which button in my JFrame was clicked if I have more than one button with the same text?

I am designing Reversi game in java, and the structure is as follows:
a. A JFrame with 64 buttons in it. The buttons are stored in an array.
b. The JButtons will have black circles or white circles.
So whenever a move is to be made, the program will highlight those boxes where a move can be made, but how can I know which button (I want to know the index of that button) has been clicked when all are highlighted the same way?
From my understanding, you are attempting to detect when a specific JButton is pressed.
The simplest way to do this is by implementing an ActionListener.
public class ExampleClass implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == buttonNameOne)
System.out.println("Button One was pressed");
else if (e.getSource() == buttonNameTwo)
System.out.pringln("Button Two was pressed);
}
}
Detecting an action
The actionPerformed(ActionEvent e) method will activate whenever any button is pressed.
Recording source of action
When it is pressed, it automatically detects the source of this action (the button) and stores it in parameter "e".
Using recorded source of action
By simply doing e.getSource() you are able to get the component which invoked this method and compare it to pre-existing components in your program.
Customized arguments
With each if statement, you are able to customize and personalize the result of the condition (which is if the button being pressed is equal to a specific button). Do this by putting arguments within the body of each conditional statement:
if (e.getSource == sayHiButton)
System.out.println("Hi");
You probably have one ActionListener added to all buttons. Then the ActionEvent getSource passed to performAction has info. That is ugly, like testing the button text.
What is more normal is to use Action (take a look) and setting different actions bearing the 64 states.
public BoardAction extends AbstractAction {
public BoardAction(int x, int y) { ... }
#Override
public void actionPerformed(ActionEvent e) {
...
}
}
JButton button = new JButton(new BoardAction(x, y));
In an Action you can also specify the button caption, and an Action can also be (re)used in a JMenuItem and such.
Because of the extra indirection needed, most examples use an ActionListener,
but swing interna use Action quite often. For instance having an edit menu with cut/copy/pase and a toolbar with cut/copy/paste icons, context menus.

Setting Actor To Listen For Button Click In LibGDX

Background Information: I am currently working in a Dialog class I have extended for my game. Inside of this dialog's content table I have both an Image and a Table (lets call it ioTable). Inside of ioTable I have a combination of both Labels and TextFields. The idea is that the dialog becomes a sort of form for the use to fill out.
Next, inside of the Dialog's button table, I want to include a "Clear" TextButton (clearButton). The idea that clearButton will clear any values written to the TextFields of ioTable.
My Question: Is is possible to add a listener to each of the TextFields of ioTable that will trigger when clearButton is pressed. As always, any other creative solution is more than welcome.
You could just give the EventListener a reference to the table you want to clear:
// Assuming getSkin() and ioTable are defined elsewhere and ioTable is final
TextButton clearButton = new TextButton("Clear", getSkin());
clearButton.addListener(new EventListener() {
#Override
public boolean handle(Event event) {
for(Actor potentialField : table.getChildren()) {
if(potentialField instanceof TextField) {
((TextField)potentialField).setText("");
}
}
return true;
}
});
// Add clearButton to your dialog
If you see yourself creating multiple clearButtons, you could easily wrap this in a helper method or extend TextButton.

Java: Creating multiple (duplicate) buttons that perform the same action but to themselves

BACKGROUND INFO: I want to make a 9x9 grid of buttons that act as empty beds. All buttons say "Add bed" and when clicked open up a window to write data about the occupant. Once saved the button will change to an occupied bed image.
QUESTION: Is it possible to create an event listener that does the same thing for each button, but applies it to the button being pressed? Im new to java but I understand that good code should be able to do this in a few lines rather than 100+
CODE:
//button1 (inside the gui function)
addBed1 = new JButton("Add bed"); //button 1 of 9
addBed1.addActionListener(new room1Listener());
class room1Listener implements ActionListener{
public void actionPerformed(ActionEvent event){
addBed1.setText("Adding bed..);
addBedGui(); //Generic window for adding bed info.
}
}
Is it possible to create an event listener that does the same thing for each button, but applies it to the button being pressed? Im new to java but I understand that good code should be able to do this in a few lines rather than 100+
Absolutely. In fact you can create one ActionListener object and add this same listener to each and every button in a for loop. The ActionListener will be able to get a reference to the button that pressed it via the ActionEvent#getSource() method, or you can get the JButton's actionCommand String (usually its text) via the ActionEvent#getActionCommand() method.
e.g.,
// RoomListener, not roomListener
class RoomListener implements ActionListener{
public void actionPerformed(ActionEvent event){
AbstractButton btn = (AbstractButton) event.getSource();
btn.setText("Adding bed..);
addBedGui(); //Generic window for adding bed info.
}
}
and
RoomListener roomListener = new RoomListener();
JButton[] addButtons = new JButton[ADD_BUTTON_COUNT];
for (int i = 0; i < addButtons.length; i++) {
addButtons[i] = new JButton(" Add Bed "); // make text big
addButtons[i].addActionListener(roomListener);
addBedPanel.add(addButtons[i]);
}

Locking JButton to prevent multiple SwingWorkers

I cant seem to find a way to prevent a SwingWorker from being called twice on a double click.
The issue is that simply setting the JButton to setEnabled(false) doesn't prevent someone from double clicking fast enough to run it more than once.
startButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent arg0) {
makeItSo();
}
});
private void makeItSo () {
startButton.setEnabled(false);
myWorker myW = new myWorker();
myW.execute(); // Executes allot of work. But errors if this is running more than once.
}
Don't use a MouseListener for buttons, you should be using an ActionListener
See How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listener for more details
Use ActionListener instead of MouseListener
why you use ActionListener, An ActionListener is used to handle the logical click of a button.
A click happens
- when the mouse is pressed then released on a button,
- when the keyboard shortcut of that button is used,
- when the button has the focus and the space bar is pressed,
- when the button is the default button and Enter is pressed,
- when the button's click() method is called programmatically
A MouseListener only handles low-level mouse events.

Fast double key pressed on Jbutton leads results in same operation twice

1> I have a JButton in Jframe.
2> The click of JButton opens new instance of another JFrame.
The problem is when a Key is pressed very fast on the above Jbutton .Two instances of the same JFrame opens up.
I have to open these frames. I knows there are other options also not using the Jframes as I read.
I managed to solve this problem for Doulbl click of Mouce by setMultiClickThreshHold('time in miliseconds'). But it worked only for mouse.
Tried some other stuffs which I got in google, But none worked.
Is there any other way to solve this issue?
For full control of how often/quickly again an Action is triggered, implement it to disable itself in its actionPerformed. Something like:
singlePerform = new AbstractAction("DoSomthing") {
#Override
public void actionPerformed(ActionEvent e) {
setEnabled(false);
doSomething();
}
};
JButton button = new JButton(singlePerform);
When it's safe for doSomething to be triggered again, simply re-enable the Action:
singlePerform.setEnabled(true);

Categories