I have several actionListeners throughout my code for when I push a button, it changes tabs between the ones I have.
However, I would like to create a general action that depending on which button was pressed (through an int), it changed to a different tab. This is the current actionListener I have.
JButton btnSaveAddESS = new JButton("Save");
btnSaveAddESS.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
tabbedBackground.setSelectedIndex(0);
tabbedBackground.setEnabledAt(1, false);
}
});
With this, I would like to create a general action, however , while creating the action as a different class, I am not able to access the TabbedPane (tabbedBackground) component.
How can I implement this, avoiding actionListeners?
Thanks,
Nhekas
changeTab(int i){
tabbedBackground.setSelectedIndex(i);
tabbedBackground.setEnabledAt(i, false);
}
public void actionPerformed(ActionEvent e) {
int i = Integer.parseInt(Jbutton.getText());
changeTab(int i);
}
what you need is actually a method which handles the operation pass an int to the method changetab and the method will change the selectedTab
Related
private JButton jBtnDrawCircle = new JButton("Circle");
private JButton jBtnDrawSquare = new JButton("Square");
private JButton jBtnDrawTriangle = new JButton("Triangle");
private JButton jBtnSelection = new JButton("Selection");
How do I add action listeners to these buttons, so that from a main method I can call actionperformed on them, so when they are clicked I can call them in my program?
Two ways:
1. Implement ActionListener in your class, then use jBtnSelection.addActionListener(this); Later, you'll have to define a menthod, public void actionPerformed(ActionEvent e). However, doing this for multiple buttons can be confusing, because the actionPerformed method will have to check the source of each event (e.getSource()) to see which button it came from.
2. Use anonymous inner classes:
jBtnSelection.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
selectionButtonPressed();
}
} );
Later, you'll have to define selectionButtonPressed().
This works better when you have multiple buttons, because your calls to individual methods for handling the actions are right next to the definition of the button.
2, Updated. Since Java 8 introduced lambda expressions, you can say essentially the same thing as #2 but use fewer characters:
jBtnSelection.addActionListener(e -> selectionButtonPressed());
In this case, e is the ActionEvent. This works because the ActionListener interface has only one method, actionPerformed(ActionEvent e).
The second method also allows you to call the selectionButtonPressed method directly. In this case, you could call selectionButtonPressed() if some other action happens, too - like, when a timer goes off or something (but in this case, your method would be named something different, maybe selectionChanged()).
Your best bet is to review the Java Swing tutorials, specifically the tutorial on Buttons.
The short code snippet is:
jBtnDrawCircle.addActionListener( /*class that implements ActionListener*/ );
I don't know if this works but I made the variable names
public abstract class beep implements ActionListener {
public static void main(String[] args) {
JFrame f = new JFrame("beeper");
JButton button = new JButton("Beep me");
f.setVisible(true);
f.setSize(300, 200);
f.add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Insert code here
}
});
}
}
To add an action listener, you just call addActionListener from Abstract Button.
I have an array of Tile objects (Panel, Button to a tile) in a JPanel, 20x20. If button 1 is clicked, a thing happens, button 2 is pressed, a thing happens, etc.
I want a specific function to happen every time a button other than one in the top row is clicked (the top row of buttons all have functions assigned, the other 380 buttons do not have assigned functions).
So in the top buttons' cases I have the code:
if(e.getSource() == tiles[0][0].button)
{
//do stuff
}
else if(e.getSource() == tiles[0][1].button)
{
//do stuff
}
For the other buttons, I want something along the lines of:
JButton button;
button = e.getSource();
JPanel hostPanel = button.PanelInWhichButtonisContained();
but I'm not sure what the syntax or what sort I would to do achieve that task. I don't really have any code to present prior attempts because I'm not sure how to approach this task, but I haven't been able to find anything on the World Wide Web to help me in this task.
I'm currently just using default application window libraries and classes (javax.swing, java.awt, etc) but I'm completely open to downloading external libraries.
Determining the "source" of an action like a button press in the actionPerformed method is usually brittle (and fortunately, hardly ever necessary).
This means that this is highly questionable:
class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// DON'T DO THIS!
if (e.getSource() == someButton) doThis();
if (e.getSource() == someOtherButton) doThad();
}
}
You should usually NOT do this.
And of course, it's even worse to add casts and walk up some container hierarchy:
// DON'T DO THIS!
Object source = e.getSource();
Component button = (Component)source;
Component parent = button.getParent();
if (parent == somePanel) doThis();
if (parent == someOtherPanel) doThat();
In basically all cases, it is far more flexible and elegant to attach a listener to the button that is specific for the button - meaning that it knows what the button should do.
For individual buttons, this can be solved the old-fashioned way, using an anonymous inner class:
class Gui {
void create() {
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
startSomething();
}
});
}
private void startSomething() { ... }
}
The same can be written far more concisely using lambda expressions with Java 8:
class Gui {
void create() {
JButton startButton = new JButton("Start");
startButton.addActionListener(e -> startSomething());
}
private void startSomething() { ... }
}
(A side note: I consider it as a good practice to only call a single method in the ActionListener implementation anyhow. The actionPerformed method should not contain many lines of code, and particularly no "business logic". There should be a dedicated method for what the button does - for example, to startSomething, as in the example above)
For buttons that are contained in arrays, as in the example in your question, there is a neat trick to retain the information about the button that was clicked:
class Gui {
JButton buttons[];
void create() {
buttons = new JButton[5];
for (int i=0; j<buttons.length; i++) {
int index = i;
buttons[i] = new JButton("Button " + i);
buttons[i].addActionListener(e -> clickedButton(index));
}
}
private void clickedButton(int index) {
System.out.println("Clicked button at index " + index);
}
}
In many cases, you then don't even have to keep the JButton buttons[] array any more. Often you can just create the buttons, add them to some panel, and then are only interested in the index that is passed to the clickedButton method. (The button[] array may be necessary in some cases, though - for example, if you want to change the label of a button after it was clicked).
This has been bugging me for a while. If I define setText on a JButton before defining setAction, the text disappears:
JButton test = new JButton();
test.setText("test"); // Before - disappears!
test.setAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
// do something
}
});
this.add(test);
If it's after, no problems.
JButton test = new JButton();
test.setAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
// do something
}
});
test.setText("test"); // After - no problem!
this.add(test);
Furthermore, if I set the text in the JButton constructor, it's fine! Yarghh!
Why does this happen?
As described in the documentation:
Setting the Action results in immediately changing all the properties
described in Swing Components Supporting Action.
Those properties are described here, and include text.
Have a look at
private void setTextFromAction(Action a, boolean propertyChange)
in AbstractButton. You can see it's calling setText() based on the action.
It looks like you can call setHideActionText(true); to sort out your problem.
This is because Action has name for the control as well. Since you are not setting any name in the Action it is getting set to empty string.
1) Listeners put all Events to the EDT,
2) all events are waiting in EDT and output to the screen would be done in one moment
3) you have to split that to the two separate Action inside Listener
setText()
invoke javax.swing.Timer with Action that provide rest of events inside your original ActionListener
If you only want to handle the event, you don't need Action. You can add an ActionListener:
JButton test = new JButton();
test.setText("test");
test.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do something
}
});
this.add(test);
Calling setAction overrides pre-set text.
Is it possible, in Java, when you hover over a single button, to make the program think you are hovering over multiple buttons?
I'm using a multi-dimensional array with buttons and want to be able to have 5 buttons be hovered over at a time. (All the buttons near the actual hover).
Any ideas on how to do this?
Note: I'm not using JButtons, just regular buttons. (awt.Button)
EDIT
I obviously wasn't clear enough, and I apologize for that.
Here is a screenshot of what I'm looking for:
So, the cursor is hovering over the first gray space, and all of the space next to it have a different background, however, they are not considered as being hovered over, which if what I need.
Assuming you are using a MouseListener, when the mouseEntered(MouseEvent e) method is called on the master button, explicitly call the same method on all of the listeners of all of the other buttons, passing the event you have been given. Ditto for the mouseExited(MouseEvent e) method.
It's up to you to maintain a reference from the master button to the subordinate buttons.
The subordinate buttons' listeners will receive an event that refers to the master button. If necessary, create your listeners with a reference to the button that they are attached to, so that you can operate on that button when receiving an event.
EDIT:
This is the kind of thing I'm talking about. Does it help?
final List<Button> subordinateButtons = Arrays.asList(new Button(), new Button(), new Button());
Button myButton = new Button();
myButton.addMouseListener(new MouseListener() {
public void mouseEntered(MouseEvent e) {
for (Button subordinateButton : subordinateButtons) {
subordinateButton.setBackground(Color.GRAY);
}
}
public void mouseExited(MouseEvent e) {
for (Button subordinateButton : subordinateButtons) {
subordinateButton.setBackground(Color.LIGHT_GRAY);
}
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
});
There's no reason why you can't keep a reference from a MouseListener to a List<Button>. If it's the business of the listener to work on those buttons then design your classes so that it happens.
private JButton jBtnDrawCircle = new JButton("Circle");
private JButton jBtnDrawSquare = new JButton("Square");
private JButton jBtnDrawTriangle = new JButton("Triangle");
private JButton jBtnSelection = new JButton("Selection");
How do I add action listeners to these buttons, so that from a main method I can call actionperformed on them, so when they are clicked I can call them in my program?
Two ways:
1. Implement ActionListener in your class, then use jBtnSelection.addActionListener(this); Later, you'll have to define a menthod, public void actionPerformed(ActionEvent e). However, doing this for multiple buttons can be confusing, because the actionPerformed method will have to check the source of each event (e.getSource()) to see which button it came from.
2. Use anonymous inner classes:
jBtnSelection.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
selectionButtonPressed();
}
} );
Later, you'll have to define selectionButtonPressed().
This works better when you have multiple buttons, because your calls to individual methods for handling the actions are right next to the definition of the button.
2, Updated. Since Java 8 introduced lambda expressions, you can say essentially the same thing as #2 but use fewer characters:
jBtnSelection.addActionListener(e -> selectionButtonPressed());
In this case, e is the ActionEvent. This works because the ActionListener interface has only one method, actionPerformed(ActionEvent e).
The second method also allows you to call the selectionButtonPressed method directly. In this case, you could call selectionButtonPressed() if some other action happens, too - like, when a timer goes off or something (but in this case, your method would be named something different, maybe selectionChanged()).
Your best bet is to review the Java Swing tutorials, specifically the tutorial on Buttons.
The short code snippet is:
jBtnDrawCircle.addActionListener( /*class that implements ActionListener*/ );
I don't know if this works but I made the variable names
public abstract class beep implements ActionListener {
public static void main(String[] args) {
JFrame f = new JFrame("beeper");
JButton button = new JButton("Beep me");
f.setVisible(true);
f.setSize(300, 200);
f.add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Insert code here
}
});
}
}
To add an action listener, you just call addActionListener from Abstract Button.