This question already has answers here:
Java anonymous class that implements ActionListener?
(6 answers)
Closed 6 years ago.
how do i access the variable 'button' from the actionlistner method?
i am trying to get the program to print 'button clicked' (System.out.println("")) to the console whenever the button is clicked. how do i do that?
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Game implements ActionListener
{
public static void main(String[] args)
{
new Game().buildframe();
}
public void buildframe()
{
//making the frame
JFrame frame = new JFrame("Game");
GridLayout table = new GridLayout(5,1);
frame.setLayout(table);
//creating the labels and textfields
JLabel usernameLabel = new JLabel("Username;");
JTextField username = new JTextField("");
JLabel passwordLabel = new JLabel("Password:");
JTextField password = new JTextField("");
//create the button and action listener
JButton button = new JButton();
button.setText("Login");
button.addActionListener(this);
//adding the components
frame.add(usernameLabel);
frame.add(username);
frame.add(passwordLabel);
frame.add(password);
frame.add(button);
//sdets the size of the Jframe
frame.setSize(300, 150);
//puts the JFrame in the midle of the screen
frame.setLocationRelativeTo(null);
//setws the default operation when the user tries to close the jframe
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent evt)
{
if(evt.getSource() == button)
{
}
}
}
Make button a class variable (so called field) instead of a local variable in the buildframe() method.
Here's a little example for you:
class MyClass {
Object myField;
void aMethod() {
myField = new Object();
}
void anotherMethod() {
myField.aMethod();
}
}
Related
I am building a GUI program in which specific code takes place when a certain condition is meant (JButton is pressed). I have a seperate class that constructs my Jframe called "MyFrame" .
Essentially I want to know the proper way to use my use a ActionListener/ ActionEvent from my "MyFrame" class in conjunction when a JButton is pressed in which it would correlate properly in the main class.
For example i am able to initiate specific code when a JButton is pressed in my MyFrame class through the actionPerformed provided method by java in my Myframe class, I am just puzzled on how I can make the same thing work through my main class as well.
Any assistance would be appreciated
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main {
public static void main(String[] args) {
MyFrame mf;
mf= new MyFrame();
Expenses exp ;
BudgetSystem system ;
ActionEvent e ;
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class MyFrame extends JFrame implements ActionListener {
JFrame myFrame;
JPanel myPanel;
JLabel greetText ;
JButton addReportButton;
JButton exitButton;
ActionListener event ;
BorderLayout layout ;
MyFrame() {
myFrame = new JFrame();
myPanel = new JPanel();
greetText = new JLabel();
addReportButton = new JButton();
exitButton = new JButton();
myPanel.setBorder(null);
myFrame.setPreferredSize(new Dimension(400,300));
greetText.setText("Please choose one of the following options to begin:" );
myPanel.add(greetText);
myFrame.add(myPanel);
addReportButton.setText("Add a budget report");
addReportButton.addActionListener(this);
myPanel.add(addReportButton);
exitButton.setText("Close Program");
exitButton.addActionListener(this);
myPanel.add(exitButton);
myFrame.setVisible(true);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setLocationRelativeTo(null);
myFrame.pack();
}
#Override
public void actionPerformed(ActionEvent e) {
/*
if (e.getSource()==addReportButton)
{
JOptionPane.showMessageDialog(myFrame,"This button Works!");
}
else if (e.getSource()== dummyButton)
{
JOptionPane.showMessageDialog(myFrame,"This is the dummy button ! , you are targeting specific buttons now ! ... YOU ROCK :) ");
}else
JOptionPane.showMessageDialog(myFrame,"This is does not work :( ");
*/
}
}
I tried to make a specific ActionEvent object in main but that did not work properly.
I also tried to use a MyFrame object to access the actionPerformed method in java but that doesnt seem to work either.
If your goal is to add listeners to a JButton from another class, one option is to give the class that holds the JButton a public method that allows this to happen, for instance:
public void addMyButtonListener(ActionListener listener) {
myButton.addActionListener(listener);
}
This would allow any object that holds an instance of the class that holds the JButton to call this method and pass in a listener.
For instance:
import java.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.*;
public class AddOutsideActionListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
SomeGUI mainPanel = new SomeGUI();
mainPanel.addMyButtonListener(e -> {
String message = "Message from the main method";
String title = "Message";
int type = JOptionPane.PLAIN_MESSAGE;
JOptionPane.showMessageDialog(mainPanel, message, title, type);
});
JFrame frame = new JFrame("Some GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
class SomeGUI extends JPanel {
public static final int PREF_W = 600;
public static final int PREF_H = 400;
private JButton myButton = new JButton("My Button");
public SomeGUI() {
add(myButton);
setPreferredSize(new Dimension(PREF_W, PREF_H));
}
public void addMyButtonListener(ActionListener listener) {
myButton.addActionListener(listener);
}
}
I was trying to make a program that calculates the numbers of the TextField. To let it start calculating you have to press a button and to do that I have to add an ActionListener to the button but it isn't possible as far as I can see, because you can't use this in a static context.
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public abstract class math extends JFrame implements ActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame();
JButton button = new JButton("text");
JPanel mainPanel =new JPanel();
JLabel mainLabel = new JLabel("text");
JTextField mainField = new JTextField(5);
button.addActionListener(this);
mainPanel.add(mainLabel);
mainPanel.add(mainField);
mainPanel.add(button);
frame.setTitle("text");
frame.setSize(1000, 700);
frame.setVisible(true);
frame.add(mainPanel);
//when the button something gets done here
double num = Double.valueOf(mainField.getText());
num * 4;
}
}
I know how to write an ActionListener that is not in the main method but here it has to be, at least I think so. I hope while shortening the code I didn't cut out some important parts of it.
Option 1: instantiate an object that implements ActionListener
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// whatever you need to do
System.out.println("The button was pressed!");
}
});
Option 2: use a lambda function (Java 8 or above)
button.addActionListener(e -> {
// whatever you need to do
System.out.println("The button was pressed!");
});
This question already has answers here:
Why are only final variables accessible in anonymous class?
(15 answers)
Closed 7 years ago.
I have a very simple GUI app. It only consists of a button and a label to display how many times that button has been clicked. I implemented it as follows:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Scratch {
public static void main(String[] args) {
JFrame frame = new JFrame("Click Counter");
frame.setSize(400,250);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
JButton button = new JButton("Click Here");
final int count = 0;
final JLabel label = new JLabel("Click Count: 0");
panel.add(button);
panel.add(label);
frame.add(panel):
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
count++; // Error
String s = label.getText();
label.setText("Click Count: " + count);
}
});
frame.setVisible(true);
}
}
The problem is with the count variable. If I don't declare it as final, I cannot access it inside the anonymous class. If I do however, I cannot modify it. So what do I do? I really prefer creating actionlistener classes as anonymous classes as opposed to creating multiple classes in a single .java file.
declare variable outside function as a class variable
private static int count = 0;
public static void main(String[] args) {
JFrame frame = new JFrame("Click Counter");
frame.setSize(400,250);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
JButton button = new JButton("Click Here");
final JLabel label = new JLabel("Click Count: 0");
panel.add(button);
panel.add(label);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
count++;
String s = label.getText();
s = s.substring(0, s.length()-1);
label.setText(s + count);
}
});
frame.setVisible(true);
}
I'd like to create a simple table game by Swing. I have a JFrame and a JPanel variable.
I want to add JButtons to this JPanel, but I'd like to create an own class.
I made a class that extends JButton (inheritence):
public class GameField extends JButton {...}
So I could add GameFields to the JPanel.
But I'd like to create GameFields by composition:
public class GameField{
private JButton button;
}
But in this clase how I can add GameField to JPanel?
Can I solve this problem by compisition?
But in this clase how I can add GameField to JPanel? Can I solve this
problem by compisition?
You do this by adding a simple getter like this:
public class GameField{
private JButton button;
public GameField(String text) {
button = new JButton(text);
// do your stuff here
}
public JButton getButton() {
return button;
}
}
Then in your GUI:
public void createAndShowGUI() {
JPanel panel = new JPanel(new GridLayout(5,5));
panel.add(new GameField("Button # 1").getButton());
panel.add(new GameField("Button # 2").getButton());
...
JFrame frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
Edit
You've stated in a comment:
Thanks, but in this case if I'd like to access this field (i.e.
panel.getComponent(i)), I can get only a JButton, and not a GameField.
You can keep a list with your GameField objects or you can use putClientProperty() method to keep a reference to the GameField object as shown in the example below:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Demo {
private void createAndShowGUI() {
ActionListener actionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
GameField gameField = (GameField)button.getClientProperty("GameField");
if(gameField != null) {
System.out.println(gameField.getText());
}
}
};
GameField gameField1 = new GameField("Button # 1");
gameField1.getButton().addActionListener(actionListener);
GameField gameField2 = new GameField("Button # 2");
gameField2.getButton().addActionListener(actionListener);
JPanel content = new JPanel(new GridLayout());
content.add(gameField1.getButton());
content.add(gameField2.getButton());
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
class GameField {
private String text;
private JButton button;
public GameField(String text) {
this.text = text;
button = new JButton(text);
button.putClientProperty("GameField", GameField.this);
}
public JButton getButton() {
return button;
}
public String getText() {
return text;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
If you wish your GameField objects to have JComponents and still be able to add them to other JComponents, have them extend JPanel instead of JButton.
You can then have your GameField objects as JPanels with other JComponents and add them to your JFrame.
I'm creating a very simple program.
I have created this classes :
MainJframeClass, JDesktopPaneClass, JinternalFrameClass1 and JinternalFrameClass2.
what ive done is that i instantiated my jdesktoppaneclass and named it desktoppane1 and i added it to the MainJframeclass. i have also instantiated the 2 jinternalframes and named it internal1 and internal2. Now, i have button in mainjframeclass that when i press, i add the internal1 to desktoppane1. what my problem now is how to add the internal2 to desktoppane1 using a button placed somewhere in internal1. i know that why could i just add another button to desktoppane1 and add the internal2. but i have done it already, i just want to solve this problem. if you can help me please. sorry for my english by the way.
It's simply a matter of references. The code that adds something to the JDesktopPane must have a reference to it, and so you will need to pass that reference into the class that needs it say via either a constructor parameter or a method parameter.
Edit 1
For example:
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
public class ReferenceExample extends JPanel {
private JDesktopPane desktop = new JDesktopPane();
private Random random = new Random();
public ReferenceExample() {
JButton addInternalFrameBtn = new JButton("Add Internal Frame");
addInternalFrameBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
addInternalFrame();
}
});
JPanel btnPanel = new JPanel();
btnPanel.add(addInternalFrameBtn);
setPreferredSize(new Dimension(600, 450));
setLayout(new BorderLayout());
add(new JScrollPane(desktop), BorderLayout.CENTER);
add(btnPanel, BorderLayout.SOUTH);
}
public void addInternalFrame() {
MyInternalFrame intFrame = new MyInternalFrame(ReferenceExample.this);
int x = random.nextInt(getWidth() - intFrame.getPreferredSize().width);
int y = random.nextInt(getHeight() - intFrame.getPreferredSize().height);
intFrame.setLocation(x, y);
desktop.add(intFrame);
intFrame.setVisible(true);
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Reference Eg");
frame.getContentPane().add(new ReferenceExample());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class MyInternalFrame extends JInternalFrame {
// pass in the reference in the constructor
public MyInternalFrame(final ReferenceExample refEg) {
setPreferredSize(new Dimension(200, 200));
setClosable(true);
JButton addInternalFrameBtn = new JButton("Add Internal Frame");
addInternalFrameBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// use the reference here
refEg.addInternalFrame();
}
});
JPanel panel = new JPanel();
panel.add(addInternalFrameBtn);
getContentPane().add(panel);
pack();
}
}
how to add the internal2 to desktoppane1 using a button placed somewhere in internal1.
In the ActionListener added to your button you can use code like the following to get a reference to the desktop pane:
Container container = SwingUtilities.getAncestorOfClass(JDesktopPane.class, (Component)event.getSource());
if (container != null)
{
JDesktopPane desktop = (JDesktopPane)container;
JInternalFrame frame = new JInternalFrame(...);
desktop.add( frame );
}