So for my program i have three buttons;
Button1: 8
Button2: 5
Button3: 3
public void actionPerformed(ActionEvent e) {
JButton b1= (JButton) e.getSource();
JButton b2= (JButton) e.getSource();
String button= b1.getText();
String button2 = b2.getText();
System.out.println("b1: " + button);
System.out.println("b2: " + button2);
I'm trying to check which buttons are pressed and storing them into the variable. So when the user presses 8, button should be 8, and once they press any second button, button2 should get that button
Do i make a new ActionEvent?
Currently both your buttons refer to the same source (I.e the same button)
If the actions to be triggered are similar in nature (for example, the buttons in MineSweeper, they are different buttons, but the actions to be triggered are the same), then you don't have to create multiple action listeners for multiple buttons. You can let your buttons add the same action listener:
//Example
class MyPanel extends JPanel{
private JButton btn1, btn2;
public MyPanel(){
btn1 = new JButton("Button 1");
btn2 = new JButton("Button 2");
ButtonHandler bn = new ButtonHandler();
btn1.addActionListener(bh);
btn2.addActionListener(bh);
}
}
Infact, what you wanted to do is just a one-liner:
private class ButtonHandler implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
System.out.println((JButton)e.getSource().getText());
}
}
However, if you have different actions for different buttons (for example, Start Game and Exit Game), then you can create separate action listeners for them.
So maybe you want to check the source of the event? Like:
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
System.out.println("b1 pressed");
} else if (e.getSource() == b2) {
System.out.println("b2 pressed");
} else {
System.out.println("some other button pressed");
}
}
and you should really create different buttons outside of the scope of this actionPerformed method!
EDIT
The example solution by user3437460 is much better than this oneā¦
Every component can hold information on it, by putClientProperty();
This mechanism is kind of map, so can hold few named objects. We use only one.
This obcjet (pie of information) is not visible for user, it is not text written on button like getText() in few tries, is only for consuming by algorithm. There can live not only primitives or strings, but live objects too.
class MyPanel extends JPanel{
private JButton btn1, btn2;
public MyPanel(){
btn1 = new JButton("Button 1");
btn1.putClientProperty("myinternalsense", 8); // <-- here
btn2 = new JButton("Button 2");
btn1.putClientProperty("myinternalsense", 5); // <-- here
btn1.putClientProperty("myfunctor", new MyFunctor() ); // <-- here
ButtonHandler bn = new ButtonHandler();
btn1.addActionListener(bh);
btn2.addActionListener(bh);
}
}
This information is accessible in any context, for example common event handler to many buttons.
private class ButtonHandler implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
System.out.println((JButton)e.getSource().getClientPropertygetText("myinternasense")); // <-- here
}
}
Related
I'm trying to simulate a car renting system on a GUI.
Since I'm not very experienced with Swing components I decided to create a car list using GridBagLayout.
Each row has different panels each having different rental prices and car names.
CarList
The "Details" button is shared through all the panels in the list. I'm looking for a way in which "Details" gets the title and price text from the panel were it was pressed, then saves them inside variables.
so far whenever I press it, it only saves and sends the text from the last panel in the list even if I pressed the first button in the list.
CarDetails
This is the button's Event:
JButton btnNewButton = new JButton("details");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String Car, price;
Car = Name.getText();
price = Price.getText();
Main.add(new CarD(Car,price), "2");
cl.show(Main, "2");
add.setVisible(false);
}
});
EDIT:
Following camickr's example, all that was left was to get the labels from the parent Panel using the location where they are placed within it.
JButton btnNewButton = new JButton("Details");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String Car, price;
JButton button = (JButton)e.getSource();
JPanel panel = (JPanel)button.getParent();
JLabel N = (JLabel)panel.getComponentAt(202, 62);
JLabel P = (JLabel)panel.getComponentAt(202, 24);
Car = N.getText();
price = P.getText();
Main.add(new CarD(Car,price), "2");
cl.show(Main, "2");
add.setVisible(false);
}
});
In the ActionListener of your "Details" button you can get the button from the ActionEvent and the panel from the button:
JButton button = (JButton)e.getSource();
JPanel panel = (JPanel)button.getParent();
In ActionListener try this :
public void actionListener(ActionEvent evt)
{
if(evt.getSource()==b1) // b1 is button variable
{
//code
// this will run if you click on b1 button
}
if(evt.getSource()==b2) // b2 is another button variable
{
//code
// this will run if you click on b2 button
}
}
I want to reduce the amount of button action listeners I have by simply calling one Action Listener:
ActionListener calculatorListener = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
int x = 9;
calc.calculate(x);
}
};
JButton button9 = new JButton("9");
buttonPanel.add(button9);
button9.addActionListener(calculatorListener);
JButton button8 = new JButton("8");
buttonPanel.add(button8);
button8.addActionListener(calculatorListener); //etc.....
I have many different buttons, but need the parameter in the one ActionListener (x for example) to be different for each button that uses the ActionListener. Is there a way that the action listener can detect which JButton is being used?
There are lots of ways of accomplishing your goal. Here's one that's fairly simple and straightforward.
First, make your action listener a named class that you can construct with a parameter:
private class CalcListener implements ActionListener {
private int x;
private CalcListener(int x){
this.x = x;
}
#Override
public void actionPerformed(ActionEvent e) {
calc.calculate(x);
}
}
Then, use it like this:
button1.addActionListener(new CalcAction(1));
...
button8.addActionListener(new CalcAction(8));
button9.addActionListener(new CalcAction(9));
I've been trying to get two buttons to work.
However it seems that actionPerformed cannot see my buttons.
Things I've tried:
- checking my import statements, they seem to be correct
- checking for missing parentheses
- checked if I put the actionPerformed in the constructor by accident
- checked acces modifiers
- checked variable names
So far I'm lost at why it can't solve the symbols for button1 and button2.
Please help?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionListener;
public class Wisselscherm
extends JFrame
implements ActionListener {
public Wisselscherm(Wisselkoers wisselkoers){
String munt1 = String.valueOf(wisselkoers.getMunt1().getNaam() );
String munt2 = String.valueOf(wisselkoers.getMunt2().getNaam() );
setTitle(munt1 + " - " + munt2 + " Converter" );
setSize(500,500);
setLayout(new FlowLayout());
String teken1 = String.valueOf(wisselkoers.getMunt1().getTeken() );
JLabel munteenheid1 = new JLabel(teken1);
add(munteenheid1);
JTextField textf1 = new JTextField(10);
add(textf1);
JButton button1 = new JButton(">>");
add(button1);
button1.addActionListener(this);
JButton button2 = new JButton("<<");
button2.addActionListener(this);
add(button2);
String teken2 = String.valueOf(wisselkoers.getMunt2().getTeken() );
JLabel munteenheid2 = new JLabel(teken2);
add(munteenheid2);
JTextField textf2 = new JTextField(10);
add(textf2);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button1) {
System.out.println("Button1 is pressed");
} else if (e.getSource() == button2) {
System.out.println("Button2 is pressed");
}
}
}
Your buttons are defined as local variables to the Wisselscherm's constructor, so they will not be accessible outside of it's context
You could...
Make them instance variables, which would allow them to be accessible from within the whole class
You could...
Use anonymous listeners, which would allow you to associate a individual listener with each button, meaning that you can gurentee what triggered the ActionListener
You could...
Make use of the actionCommand property of the JButton and ActionEvent to decouple the listener from the source of the event, allowing you to re-use the ActionListener with other buttons/actions which generate the same actionCommand.
By default, the actionCommand will be the text of the button if it's not otherwise set directly
You could...
Use the Action API
All in or, you should probably have a closer look at How to Write an Action Listeners, How to Use Actions and How to Use Buttons, Check Boxes, and Radio Buttons for more details
This is a scope problem, just move button1 and button2 to the Class's scope level:
public class Wisselscherm extends JFrame implements ActionListener {
JButton button1;
JButton button2;
...
Then you can have:
button1 = new JButton(">>");
(Note that I removed JButton word in that line)
I created this little test program. It has 2 buttons and 2 labels. I want to know how I can use 2 buttons. So when I press button-1 then I change the text for text-1 and when I press button-2 then I change text for text-2. I just wanna get an idea of how I can use multiple buttons.
My code:
JLabel text1, text2;
JButton button1, button2;
public Game(String title) {
super(title);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().setLayout(new FlowLayout());
addComponents();
setSize(250, 250);
setResizable(false);
}
public void addComponents() {
text1 = new JLabel();
getContentPane().add(text1, text2);
text2 = new JLabel();
getContentPane().add(text2);
button1 = new JButton("Button");
getContentPane().add(button1);
button1.addActionListener(this);
button2 = new JButton("Button 2");
getContentPane().add(button2);
button2.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e) {
}
I'm new to programming, so I would also like if someone could write some comments for the code. Just so I get an idea on how the code for multiple buttons work.
In your actionPerformed method you can get the source of the action
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button1){
//Do Something
}else if(e.getSource() == button2){
//Do Something Else
}
There are various approaches to add listeners to buttons, here just a couple:
Inner
If you don't have to do much actions in each button you can add inner listener in each button
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// DO STUFF
}
});
Common Listener
If you have more than 2 buttons (i guess your app will be bigger) you can use your actionPerformed(ActionEvent e) and get source of the action
#Override
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
if(source.equals(button1)){
// DO STUFF
}
}
Use actionCommand to clarify
To clarify this approach I would reccommend to use JButton.setActionCommand(stringCommand) so after you can use a switch:
Declaring buttons:
button1.setActionCommand("command1");
button2.setActionCommand("command2");
In ActionListener::actionPerformed()
public void actionPerformed(ActionEvent e) {
String command = ((JButton) e.getSource()).getActionCommand();
switch (command) {
case "command1":
// DO STUFF FOR BUTTON 1
break;
case "command2":
// DO STUFF FOR BUTTON 2
break;
}
}
Using Java 8, its it much more concise to add ActionListeners:
button.addActionListener(ae -> System.out.println("foo"));
Using multiple statements:
button.addActionListener(ae -> {
System.out.println("foo");
System.out.println("bar");
});
You should not use setVisible(true) before the components are added.
There are a few ways to deal with more elements in an ActionEvent:
e.getSource() returns the object on which the event occurred. So, if button1 was pressed, e.getSource() will be the same as button1 (and e.getSource()==button1 will thus be true)
You can use separate classes for each ActionEvent. If you would add the ActionListener "Button1ActionEvent" [button1.addActionListener(new Button1ActionEvent());] you have to create this class, let it implement ActionListener and add the method actionPerformed as you had in your main class. Also, you can create a listener inside of the addActionListener-method [button1.addActionListener(new ActionListener() { // actionPerformed-method here });]
Basically, at the moment I am doing certain actions that are being held in an ArrayList and when I click the Play Button, they are being output to a TextArea. I have two other buttons, Start and Stop.
When I click Start, every action that I do is supposed to start recording.
When i click Stop, it stops recording the actions.
When I click Play, the actions are supposed to be printed in the text area.
I have got the hard bit working but I just can't seem to implement the start and stop buttons. I will attach part of my code so you are able to see. Thanks in advance!!
public class jPanelBottom extends javax.swing.JPanel
{
private JTextField jtfBoundaryLength, jtfArea;
private JSlider jsShapes;
private JLabel jLabelBoundaryLength, jLabelArea, jLabelSlider;
private JButton jbStart, jbStop, jbPlay;
public static ActionPanel yes;
public jPanelBottom()
{
initComponents();
jbStart = new JButton();
jbStop.setText("Start");
jbStart.setSize(80, 25);
jbStart.setLocation(400, 95);
this.add(jbStart);
jbStop = new JButton();
jbStop.setText("Stop");
jbStop.setSize(80, 25);
jbStop.setLocation(500, 95);
this.add(jbStop);
jbPlay = new JButton();
jbPlay.setText("Play");
jbPlay.setSize(80, 25);
jbPlay.setLocation(600, 95);
this.add(jbPlay);
jbPlay.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
try{
//jbStart.addActionListener(this);
{
jbPlay.addActionListener(this);
ArrayList<String> list = MyFrame.shape1.getArrayList();
for (String s : list)
{
ActionPanel.jtaWoof.append(s);
ActionPanel.jtaWoof.append("\n");
}
}}catch(Throwable ex){}}
});
}
I really appreciate any help!!
The best way is to add a general actionPerformed:
public class Frame extends JFrame implements ActionListener{
[...]
public Frame(){
JButton Test = new JButton("Nutton Name");
[...]
Test.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e){
Object src = e.getSource();
if(src == Test){
System.out.print("You've pressed Test!");
}
}
}
Don't forget to add the .addActionListener and to implement ActionListener to the class.
This is much easier than adding one every single time.