Swing and events - java

Well, this is a very newie cuestion. Im stating to write by myself the code of my GUI applications with the help of window builder, i have decided to stop using netbeans couse ive read some peope in here that said that would be good. You may think i havent investigate, but trust me, i did my homework...
I tryed the way oracle says:
Declare an event handler class and specify that the class either implements an ActionListener interface or extends a class that implements an ActionListener interface. For example:
public class MyClass implements ActionListener {
Register an instance of the event handler class as a listener on one or more components. For example:
someComponent.addActionListener(instanceOfMyClass);
Include code that implements the methods in listener interface. For example:
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
}
and my own way (wrong, off course, but i dont know whats wrong)
package Todos;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Main extends JFrame {
private JPanel contentPane;
protected JButton btnNewButton;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setLayout(new BorderLayout());
//setDefaultLookAndFeelDecorated(false);
//setIconImage(Image imagen);
setTitle("");
setSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
setPreferredSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
setLocationRelativeTo(null);
this.btnNewButton = new JButton("New button");
this.btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
asd(arg0);
}
});
this.getContentPane().add(this.btnNewButton, BorderLayout.NORTH);
}
public void asd(ActionEvent arg0) {
this.getContentPane().add(new JButton("asd"));
}
}
The cuestion is, why this code doesnt work, the JButton im trying to add to the JFrame with the ActionPerformed event is not visible after i click.
This is an example code, may look silly, but i think it simplifies the cuestion, since my problem is in a few lines of code its not neccesary to show you the hole proyect.
Thank you in advance!

Your problem is here:
public void asd(ActionEvent arg0) {
this.getContentPane().add(new JButton("asd"));
}
Form Container.add() javadoc:
This method changes layout-related information, and therefore,
invalidates the component hierarchy. If the container has already been
displayed, the hierarchy must be validated thereafter in order to
display the added component.
You need to call validate() method to make added button visible:
public void asd(ActionEvent arg0) {
this.getContentPane().add(new JButton("asd"));
this.getContentPane().validate();
}

Related

Button that opens a new JFrame

I'm writing a program where I am supposed to have a title screen for a game, where you can click a 'play' button that opens a different window and simultaneously closes the other one. What I am attempting to do is utilize an ActionListener for a button that makes the current window invisible while simultaneously making a different window visible. I am having a hard time getting this to work and am encountering a lot of syntax and logical errors. I'm quite certain there is a better way to do this, so any pointers will be greatly appreciated. I am using swing. Disclaimer: beginner java level programmer lol :p
My first class includes this (does not include my imports):
public static void main(String[] args) {
//Creating the Frame
MyFrame menuFrame = new MyFrame();
// (here i have code for the frame in my actual program)
}
static class MyFrame extends JFrame {
MyFrame () {
this.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(new JLabel(new ImageIcon("logo.png")));
this.pack();
this.setVisible(true);
new EightOff.returnHomeListener (this);
}
}
}
My other class that has the other frame being opened includes the following button and action listener where I am trying to reference my frame from GameMenu:
public class EightOff
{
private static JButton returnHome = new JButton("Return to Game Menu");
public static class returnHomeListener implements ActionListener {
public returnHomeListener(GameMenu.MyFrame myFrame) {
}
#Override
public void actionPerformed(ActionEvent e)
{
returnHomeListener (JFrame visibleFrame) {
visibleFrame.toSetVisible (true);
}
}
}
}
You should start by having a look at How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listener
The ActionListener should be registered to the button, so if can be notified when some action occurs, for example...
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JButton button = new JButton("Click me");
button.addActionListener(new TestActionListener());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "I'd prfefer if you did't do that");
}
}
}
In order to make changes to a object, you first need a reference to that object. This is pretty basic, Java 101 kind of stuff and you should have a look at Passing Information to a Method or a Constructor for more details.
You should also have a read of the JavaDocs for JFrame to get a better understanding of what properties and functionality the class provides.
Having a look at How to Make Frames also wouldn't hurt.
I'd recommend having a look at How to use CardLayout instead of trying to hide/show windows, you'll have a better user experience generally.

Access difficulty with ArrayList of panels with buttons

my question is: how do I get the object of my CustomPanel, so that I am able to access its fields (because in my real programm I have some more fields in there) and also am able to delete it from my ArrayList?
I don't know how I have to implement an ActionListener in the Class Window, to somehow get the Object in my Arraylist, which containes the button that got pressed.
Also I am wondering if I am somehow able to implement an ActionListener in the Class CustomPanel which can influence the behaviour of the Object which is an instance of my Class Window.
I have kind of the following code:
public class Window extends JFrame{
ArrayList<CustomPanel> aLCustomPanel = new ArrayList();
JPanel jp = new JPanel();
public Window() {
for(int i=0;i<5;i++){
aLCustomPanel.add(new CustomPanel());
//here I could put the code from the 1 edit - see below
jp.add(aLCustomPanel.get(i));
}
this.add(jp);
}
public static void main(String args[]){
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Window().setVisible(true);
}
});
}
}
class CustomPanel extends JPanel {
private JButton button;
public CustomPanel(){
button = new JButton("button");
this.add(button);
}
public JButton getButton(){
return this.button;
}
}
my Code is much longer and weirder, so I tried to extract the (for this question) importing things.
Thanks for any help in advance!
edit:
for example: I would like to delete the object from the ArrayList, of which the button got pressed.
//imagine this comment in above code
aLCustomPanel.get(aLCustomPanel.size()-1).getButton().addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button_IwantToDeleteYou(e); //here I want to remove the panel, containing the button that got pressed from the above ArrayList, which is located in Class Window
}
});
edit2:
added a missing bracket and fixed some mistakes, code should be ok now.
Your code contained a few "gaps", i.e. missing code, which I filled in, as follows:
Added calls to [JFrame] methods setDefaultCloseOperation() and pack() and setLocationByPlatform(). I suggest you refer to the javadoc for those methods in order to understand what they do.
I set a layout manager for jp class member variable in your Window class.
Yes, you need to register an ActionListener with the JButton in class CustomPanel and that listener should reside in your Window class - the one that extends JFrame.
Here is my rewrite of your code. Note that I changed the name of class Window to CusPanel so as to distinguish between your class and java.awt.Window class. Not that it makes a difference, I just prefer not to use names of classes from the JDK.
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class CusPanel extends JFrame implements ActionListener {
private static final int COUNT = 5;
private ArrayList<CustomPanel> aLCustomPanel = new ArrayList<>();
private JPanel jp = new JPanel(new GridLayout(0, COUNT));
public CusPanel() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
for (int i = 0; i < COUNT; i++) {
aLCustomPanel.add(new CustomPanel(this));
// here I could put the code from the 1 edit - see below
jp.add(aLCustomPanel.get(i));
}
this.add(jp);
pack();
setLocationByPlatform(true);
}
public void actionPerformed(ActionEvent actionEvent) {
Object source = actionEvent.getSource();
if (source instanceof JButton) {
JButton button = (JButton) source;
Container parent = button.getParent();
jp.remove(parent);
jp.invalidate();
jp.repaint();
pack();
// aLCustomPanel.remove(parent); <- optional
}
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new CusPanel().setVisible(true);
}
});
}
}
class CustomPanel extends JPanel {
private JButton button;
public CustomPanel(ActionListener parent) {
button = new JButton("button");
button.addActionListener(parent);
this.add(button);
}
public JButton getButton() {
return this.button;
}
}
Note that after removing a CustomPanel, the GUI components need to be laid out again and the JFrame should also be resized accordingly. Hence in the actionPerformed() method, I call invalidate(), then repaint() and then pack(). I also think that if you remove a CustomPanel from the GUI, you should also remove it from the ArrayList, but hey, I still don't understand why you want to do this although I obviously don't know the whole story behind you wanting to do this in the first place.
Of-course, since each button (and each CustomPanel) looks exactly the same, you can't really know which button was removed. Again, I assume you see the big picture whereas I don't.

how to define action listener for buttons in java

I have a jframe that includes JButton.I have six buttons in this frame, but I don't know how to define action listener for this buttons.please help to solve this problem.
First you have to import the package java.awt.event.* to enable events. After the class name you have to add implements ActionListener so that the class can handle events. When you have created the buttons you have to add an actionlistener to each button. Since you haven't showed which code you use I make an example with a simple program that counts votes, if the user clicks the yesButton the votes are increased with 1 and if the user clicks the noButton the votes are decreased with 1.
Here is the code to add an ActionListener to each button:
yesButton.addActionListener(this);
noButton.addActionListener(this);
Then write the following code to handle the events:
public void actionPerformed(ActionEvent e) {
JButton src = (JButton) e.getSource();
if(src.getActionCommand().equals("Yes")) {
yesCount++;
} else {
noCount++;
}
label.setText("Difference: " + (yesCount - noCount));
}
If you have 6 buttons you need to have an if statement and then 5 "else if" statements instead of only an if and an else statement.
Have a look at the Java tutorials on how to use ActionListeners:
https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html
Here's a simple example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Hello extends JPanel implements ActionListener {
JButton button;
public Hello() {
super(new BorderLayout());
button = new JButton("Say Hello");
button.setPreferredSize(new Dimension(180, 80));
add(button, BorderLayout.CENTER);
button.addActionListener(this); // This is how you add the listener
}
/**
* Invoked when an action occurs.
*/
public void actionPerformed(ActionEvent e) {
System.out.println("Hello world!");
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Hello");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new Hello();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
buttons have a method called addActionListener, use that for adding the action listener that you can implement for the click...
Example:
dummyButton = new JButton("Click Me!"); // construct a JButton
add(dummyButton); // add the button to the JFrame
dummyButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(" TODO Auto-generated method stub");
}
});
It's really simple.
I suppose you have an instance of your button, right? Let's say that instance is called myButton.
You can just add an action listener by calling addActionListener:
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Do whatever you like here
}
});
Protip: next time you don't know what method to call, just type the instance name and .. Then, your IDE will show you all the methods you can call, unless you are not using an IDE. If that is the case, download one.

How can I add the ActionEvent to the JButton so that when i click it it will fire the event?

I want to be able to add the ActionListener to the JButton but cannot seem to get it to work properly.
I have tried to add the ActionListeneer and also the ActionEvent and neither seems to fire the ActionPerformed method.
I did not one curious aspect was the the compiler made me take off the #Override keyword since the interface is used to create a variable and not implemented.
Does this make a difference? I am certain that you can do it this way but I think I am just a bit off the mark.
Code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
public class testInterfaces2 {
static ActionListener m;
static ActionEvent me;
testInterfaces2() {
}
public void actionPerformed(ActionEvent e) {
System.out.println("Mouse Clicked");
}
public static void main(String[] args) {
JFrame f = new JFrame("Test");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JButton pButton = new JButton("Print");
pButton.addActionListener(m);
//pButton.addActionListener(m.actionPerformed(me));
f.add("Center", pButton);
f.pack();
f.setVisible(true);
}
}
It should be like this and remove ActionListener and ActionEvent variables that is not needed.
public class testInterfaces2 implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Mouse Clicked");
}
...
JButton pButton = new JButton("Print");
pButton.addActionListener(this);
}
#Override doesn't do any thing extra other than compile time checking of the overridden method.
In simple term, You need a class that implements ActionListener and obviously implements actionPerformed() method. Simply create a object of that class and pass in addActionListener() method.
I did not one curious aspect was the the compiler made me take off the
#Override keyword since the interface is used to create a variable and
not implemented.
This should have highlighted your first problem, your testInterfaces2 class can't override actionPerformed as it's not defined in any part of the parent class or it's parents. This is because testInterfaces2 doesn't implement ActionListener directly or indirectly (via inheritance).
Your second problem is m is null, you've never initialised it
Take a closer look at How to write ActionListeners for more details
I think it's best to define a new ActionListener for each button. Like this
JButton pButton = new JButton();
pButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
System.exit(0);
}
});

How to find which component is focused?

Hey I have a panel class in which there are two panels, one of the panels have text field. I want to perform an action when it gets focused.
The panel is added on the main frame.
Use FocusListener, here is simple example:
import java.awt.BorderLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class TestFrame extends JFrame{
public TestFrame(){
init();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
private void init() {
JTextField f1 = new JTextField(5);
f1.addFocusListener(getFocusListener());
add(f1,BorderLayout.SOUTH);
add(new JTextField(5),BorderLayout.NORTH);
}
private FocusListener getFocusListener() {
return new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
super.focusGained(e);
System.out.println("action");
}
};
}
public static void main(String... s){
new TestFrame();
}
}
Also JFrame has getFocusOwner() method.
Use the api
JFrame.getFocusOwner()
This will return a reference to the component with focus
You ca also check....
KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()
To the modification, just add a FocusListener to your respective Component, and implement the interface to your particular acitons.
There are visual clue that helps to know which component has the focus, such as an active cursor in a text field. To work with the FocusListener Interface and in order to listen’s the keyboards gaining or losing focus, the listener object created from class is need to registered with a component using the component’s addFocusListener() method. The two important method focusGained(FocusEvent e) and void focusLost(FocusEvent e) which helps to find which component is focused.
To know more about What is FocusListener Interface and How it Works.

Categories

Resources