import java.awt.*;
public class TestButton {
private Frame f;
protected Button b;
public TestButton() {
f = new Frame("Test");
b = new Button("Press Me!");
b.setActionCommand("ButtonPressed");
}
public void launchFrame() {
b.addActionListener(new ButtonHandler());
f.add(b, BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
public static void main(String args[]) {
TestButton guiApp = new TestButton();
guiApp.launchFrame();
}
}
import java.awt.*;
import java.awt.event.*;
public class ButtonHandler extends TestButton implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if(source==b)
{
System.out.println("Action occurred");
System.out.println("Button's command is: "
+ e.getActionCommand());
}
}
}
I'm trying to invoke a ActionEvent when the button b is pressed but not working with getSource.
You're misusing inheritance. The ButtonHandler class should not extend the TestButton class, since the b variable in the handler class refers to a completely different Button object from the one displayed. I suggest:
Use the Swing library, not the AWT library
You can get the JButton pressed from the ActionEvent's getSource() method and use it directly.
If you need a reference to the GUI in the handler, pass in a reference in the handler's constructor.
Don't misuse inheritance to solve problems that don't involve inheritance issues.
For example:
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class TestButton extends JPanel {
private JButton btn = new JButton(new ButtonAction("Press Me!", "ButtonPressed"));
public TestButton() {
add(btn);
}
private static void createAndShowGUI() {
TestButton testButton = new TestButton();
JFrame frame = new JFrame("TestButton");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(testButton );
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
#SuppressWarnings("serial")
class ButtonAction extends AbstractAction {
public ButtonAction(String name, String actionCommand) {
super(name);
putValue(ACTION_COMMAND_KEY, actionCommand);
}
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("Button's actionCommand is: " + evt.getActionCommand());
}
}
That happens because you extends TestButton in your ButtonHandler, because of you have 2 different instances of your Button and thea are not equals.
To fix that you can remove extends TestButton and make ButtonHandler as inner class of TestButton
or you can compare action commands instead of Button's like next:
if(((Button)source).getActionCommand().equals("ButtonPressed"))
I think you need to remove extends TestButton as the 2 different instances of the buttons are not equal. You should go for a ButtonHandler as inner class or anonymous class to implement this.
Check this question:
Java Button Handler
Related
I'm trying to change button action in a subclass because the form is pretty much exactly the except one asks for an ID. What I i tried doing was making a ActionListener object and instantiating it to an object of an anonymous class like so:
class ParentClass extends JPanel{
JButton button;
ActionListener buttonAction;
ParentClass{
button = new JButton("Parent Action");
buttonAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("The button was clicked by the parent class");
}
};
button.add(buttonAction);
add(button);
}
}
class ChildClass extends ParentClass{
JButton button;
ActionListener buttonAction;
ChildClass{
super();
buttonAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("The button was clicked by the child class");
}
};
}
}
public static void main(String[] args){
JFrame frame = new JFrame;
frame.add(new ChildClass());
frame.setSize(600, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
I was trying to use this method but the actionPerformed of buttonAction is never called. How can I make the button action different for the parent class and the subclass?
You can let parent class implement ActionListener, then use button.addActionListener(this) in order to add the action to button. Then in the subclass #Override actionPerformed method:
class ParentClass extends JPanel implements ActionListener
{
ParentClass()
{
JButton button = new JButton("something");
button.addActionListener(this);
add(button);
}
#Override
public void actionPerformed(ActionEvent event)
{
System.out.println("I am the parent.");
}
}
class SubClass extends ParentClass
{
SubClass()
{
super();//initialize button
}
#Override
public void actionPerformed(ActionEvent event)
{
System.out.println("I am the child.");
}
}
Another way is to add the ActionListener and inside it, only call a method. Something like buttonPressed. Then in subclass #Override buttonPressed method.
A complete example:
public class Test extends JFrame {
public Test() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridLayout(2, 1));
add(new ParentPanel());
add(new ChildPanel());
pack();
setLocationByPlatform(true);
}
private class ParentPanel extends JPanel implements ActionListener {
public ParentPanel() {
super(new BorderLayout());
JButton button = new JButton("My Class:" + getClass());
button.addActionListener(this);
add(button);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Parent");
}
}
private class ChildPanel extends ParentPanel {
public ChildPanel() {
super();
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Child");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Test().setVisible(true));
}
}
I the method I posted works. The issue is if you don't remove and add the button to the subclass it doesn't change the action that will run
class ParentClass extends JPanel{
JButton button;
ActionListener buttonAction;
ParentClass{
button = new JButton("Parent Action");
buttonAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("The button was clicked by the parent class");
}
};
button.add(buttonAction);
add(button);
}
}
So in the subclass what you would do is this:
class ChildClass extends ParentClass{
JButton button;
ActionListener buttonAction;
ChildClass{
super();
buttonAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("The button was clicked by the child class");
}
};
button.removeActionListener(button.getActionListeners()[0]);
button.addActionListener(buttonAction);
}
}
I, however, do not know why but would like an explanation as to why buttonAction had to be re-registered.
Hi, I'm new to Java and I have the following problem:
I created a JFrame and I want the JPanel to change when clicking a JButton. That does almost work.The only problem is that the program creates a new window and then there are two windows. One with the first JPanel and one with the second JPanel.
Here is my current code:
first class:
public class Program {
public static void main (String [] args) {
new window(new panel1());
}
}
second class:
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Window extends JFrame {
private static final long serialVersionUID = 1L;
Window(JPanel panel) {
setLocation((int) Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 200,
(int) Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 100);
setSize(400, 200);
setTitle("test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setContentPane(panel);
setVisible(true);
}
}
third class:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Panel1 extends JPanel {
private final long serialVersionUID = 1L;
Panel1() {
JButton nextPanelButton = new JButton("click here");
add(nextPanelButton);
ActionListener changePanel = new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
new window(new panel2());
}
};
nextPanelButton.addActionListener(changePanel);
}
}
fourth class:
public class Panel2 extends JPanel {
private static final long serialVersionUID = 1L;
Panel2() {
JLabel text = new JLabel("You pressed the Button!");
add(text);
}
}
But I just want to change the JPanel without opening a new window. Is there a way to do that?
Thanks in advance!
This is a demo
import javax.swing.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new MainFrame("Title").setVisible(true);
});
}
}
MainFrame.java
import javax.swing.*;
import java.awt.*;
public class MainFrame extends JFrame {
private JPanel viewPanel;
public MainFrame(String title) {
super(title);
createGUI();
}
private void createGUI() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new BorderLayout());
setMinimumSize(new Dimension(600, 480));
viewPanel = new JPanel(new BorderLayout());
add(viewPanel, BorderLayout.CENTER);
showView(new View1(this));
pack();
}
public void showView(JPanel panel) {
viewPanel.removeAll();
viewPanel.add(panel, BorderLayout.CENTER);
viewPanel.revalidate();
viewPanel.repaint();
}
}
View1.java
import javax.swing.*;
import java.awt.*;
public class View1 extends JPanel {
final private MainFrame owner;
public View1(MainFrame owner) {
super();
this.owner = owner;
createGUI();
}
private void createGUI() {
setLayout(new FlowLayout());
add(new JLabel("View 1"));
JButton button = new JButton("Show View 2");
button.addActionListener(event -> {
SwingUtilities.invokeLater(() -> owner.showView(new View2(owner)));
});
add(button);
}
}
View2.java
import javax.swing.*;
import java.awt.*;
public class View2 extends JPanel {
final private MainFrame owner;
public View2(MainFrame owner) {
super();
this.owner = owner;
createGUI();
}
private void createGUI() {
setLayout(new FlowLayout());
add(new JLabel("View 2"));
JButton button = new JButton("Show View 1");
button.addActionListener(event -> {
SwingUtilities.invokeLater(() -> owner.showView(new View1(owner)));
});
add(button);
}
}
First of all, take a look at Java naming conventions, in particular your class names should start with a capitalized letter.
If you want to avoid to open a new window every time you click the button, you could pass your frame object to Panel1 constructor, and setting a new Panel2 instance as the frame content pane when you click the button. There is also no need to pass Panel1 to Window constructor (please note that Window class is already defined in java.awt package, it would be better to avoid a possible name clash renaming your class ApplicationWindow, MyWindow or something else).
You could change your code like this (only relevant parts):
public class Program
{
public static void main (String [] args) {
SwingUtilities.invokeLater (new Runnable () {
#Override public void run () {
new Window ().setVisible (true);
}
};
}
}
class Window extends JFrame
{
// ...
Window () {
// ...
setContentPane(new Panel1 (this));
}
}
class Panel1 extends JPanel
{
// ...
Panel1 (JFrame parent) {
// ...
ActionListener changePanel = new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
parent.setContentPane (new Panel2 ());
}
};
// ...
}
Also note the SwingUtilities's invokeLater call, which is the best way to initialise your GUI in the EDT context (for more info look at this question).
Finally, you could avoid to create a new Panel2 instance every time you click the button, simply by using a CardLayout.
Take a look at the official tutorial.
This is an old post, but it may be useful to answer it in a simplified way. Thanks to mr mcwolf for the first answer.
If we want to make 1 child jframe interact with a main jframe in order to modify its content, let's consider the following case.
parent.java and child.java.
So, in parent.java, we have something like this:
Parent.java
public class Parent extends JFrame implements ActionListener{
//attributes
//here is the class we want to modify
private some_class_to_modify = new some_class_to_modify();
//here is a container which contains the class to modify
private JPanel container = new JPanel();
private some_class = new some_class();
private int select;
//....etc..etc
//constructor
public Parent(){
this.setTitle("My title");
//etc etc
//etc....etc
container.add(some_class_to_modify,borderLayout.CENTER);
}
//I use for instance actionlisteners on buttons to trigger the new JFrame
public void actionPerformed(ActionEvent arg0){
if((arg0.getSource() == source_button_here)){
//Here we call the child class and send the parent's attributes with "this"
Child child = new Child(this);
}
//... all other cases
}//Here is the class where we want to be able to modify our JFrame. Here ist a JPanel (Setcolor)
public void child_action_on_parent(int selection){
this.select = selection;
System.out.println("Selection is: "+cir_select);
if(select == 0) {
//Do $omething with our class to modify
some_class_to_modify.setcolor(Color.yellow);
}
}
In child.java we would have something like this:
public class Child extends JFrame implements ActionListener {
//Again some attributes here
private blabla;
//Import Parent JFrame class
private Parent owner;
private int select_obj=0;
//Constructor here and via Parent Object Import
public Child(Parent owner){
/*By calling the super() method in the constructor method, we call the parent's
constructor method and gets access to the parent's properties and methods:*/
super();
this.owner = owner;
this.setTitle("Select Method");
this.setSize(400, 400);
this.setContentPane(container);
this.setVisible(true);
}
class OK_Button implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object Selection = select;
if(Selection == something) {
select_obj=0;
valid = JOptionPane.showConfirmDialog(null,"You have chosen option 1. Do you want to continue?","Minimum diameter",2);
}
System.out.println("Option is:"+valid);
if(valid == 0) {
setVisible(false);
//Here we can use our herited object to call the child_action_on_parent public class of the Parent JFrame. So it can modify directly the Panel
owner.child_action_on_parent(select_obj);
}
}
}
I have two jframes,
I want to get value from opened another jframe to other opened jframe.
when click jframe1 open button showing jframe2 and type some text in text field and click ok button, text field value want to get jframe1 jlable. how to do this i tried but i can't find a way to do this.
Is this possible ?
Use a callback,
add this code to your project:
Define an interface
public interface ICallbackListener{
void onNewEvent(String msg);
}
add to jframe 2:
private ICallbackListener myListener;
public void addCallback(ICallbackListener myListener){
this.myListener = myListener;
}
...
if(myListener!=null){
myListener.onNewEvent("myMessage");
}
...
add to jframe 1:
private ICallbackListener myListener;
ICallbackListener i = new ICallbackListener() {
#Override
public void onNewEvent(String msg) {
// TODO Auto-generated method stub
}
};
public void setCallback( ){
jframe2.addCallback(myListener);
}
now, every thime the jframe2 call the interface method you will get asynchronous a call to the TODO label in the jframe1
Try This
import java.awt.FlowLayout;
import javax.swing.*;
import java.awt.event.*;
class TestFrameExample extends JFrame implements ActionListener{
static JLabel label ;
public static TestFrameExample test;
TestFrameExample()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
label = new JLabel("This is a label!");
JButton button = new JButton("Open");
button.setText("Press me");
button.addActionListener(this);
panel.add(label);
panel.add(button);
add(panel);
setSize(300, 300);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void actionPerformed(ActionEvent a)
{
new TestFrameExample1();
}
public static void main(String s[]) {
test=new TestFrameExample();
}
}
class TestFrameExample1 extends JFrame implements ActionListener {
JTextField t;
TestFrameExample test;
public TestFrameExample1()
{
setSize(300, 300);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(null);
t=new JTextField();
t.setBounds(100,20,150,20);
JButton button=new JButton("oK");
button.setBounds(100,50,100,30);
button.addActionListener(this);
add(t);
add(button);
}
public void actionPerformed(ActionEvent a)
{
test.label.setText(t.getText());
}
}
create a method that takes jframe1 in the jframe2
in the open button action event create a object from jframe2 and call that method that take jframe1.
so when u click Ok button in the jframe2 pass that text field value to the jframe1 object (that u passed to the jframe2) via a methdo
public class jframe1 {
public void actionPerformed(ActionEvent a){
jfame2 jf2 = new jframe2();
jf2.setJframe1(this);
}
public void updateLable(String value){
lblIdk.setText(value);
}
}
public class jframe2 {
private jframe1 jf1;
public void setJframe1(jframe1 jf1){
this.jf1 = jf1;
}
public void actionPerformed(ActionEvent a){
this.jf1.updateLable(txtidk.getText());
}
}
I have two JFrames (frameA and FrameB). frameB can only be opened from frameA and when I open frameB, frameA must be left open. frameB has got a button (Close_frameA). I would like when the button is clicked to close frameA.
How can i do it?
First of all, is each JFrame made by a different class( I would assume so because I don't know any other way to make two frames).
Possible solution to try:
in frame A, create a "static variable":
//lets call the class that create frameA ClassA
public class ClassA extends JFrame {
static JFrame frameA;
instead of doing
JFrame frameA=new JFrame("Name of the frame");
in the public static void main(String[] args).Then, in the public static void main(String[] args) program, do
//the static JFrame assigned before
frameA= new JFrmae("Nameof the frame");
this lets the program in frameB to read "frameA" with the following code in ClassB(lets call the class that make frameB ClassB):
JFrame frameA= ClassA.frameA;
then, still in ClassB, we can do
frameA.dispose();
I hope you understand(please comment for what you don't understand if you don't), and i hope it works.
Code:
import javax.swing.JFrame;
public class ClassA {
static JFrame frameA;
public ClassA(){
//a useless constructor because I am not adding any Listeners(don't worry about it)
}
public static void main(String[] args){
frameA=new JFrame("Name");
//your ordinary things(some peiople put these in the constructor)
frameA.setSize(300,300);
frameA.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frameA.setVisible(true);
//runs ClassB
new ClassB();
}
}
and
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class ClassB extends JFrame implements ActionListener{
static JButton close=new JButton("close");
public ClassB(){
//your ordinary thigns
add(close);
setSize(300,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
close.addActionListener(this);
System.out.println("what?");
}
public static void main(String[] args){
JFrame frameB=new JFrame("Clae Frame A");
}
#Override
public void actionPerformed(ActionEvent arg0) {
if(arg0.equals("close")){
JFrame frameA=ClassA.frameA;
frameA.dispose();
}
}
}
You can use below two class: TJFrame and OpenFrame to close a JFrame class with a button in another JFrame
public class TJFrame {
public static OpenFrame openWindow;
public static void main(String[] args) {
JFrame frame = new JFrame("Swing Frame");
JButton button = new JButton("Open");
frame.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
openWindow = new OpenFrame();
openWindow.setVisible(true);
}
});
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setSize(350, 200);
frame.setVisible(true);
}}
public class OpenFrame extends JFrame{
JPanel back_panel;
public JButton button = new JButton("Cross");
public OpenFrame() {
back_panel = new JPanel();
setContentPane(back_panel);
this.setSize(350, 200);
button.setBounds(380, 10, 20, 20);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
dispose();
}
});
back_panel.add(button);
}}
To be short, I create a class Something witch have a function with a JFrame where I have a label and a button on it. On the button I have an addActionListener(new changeLabel()).
I did class changeLabel in the src package for the listener but when I start the application and I click the button throw an NullPointerException on the changeLabel at
nameLabel.setText("Name changed");
line. I want to mention that if I create this listener class in Something class, work perfectly.
I don't know why throw null exception because the label is initialized firstly and after that, the button just want to change the text.
I tryed to make a getFunction, to call that label, I tryed with object Something, with object changeLabel etc... but doesn't work.
Here is some code
package trying;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.*;
public class Something {
JFrame frame;
JLabel changeName;
JButton button;
public void gui(){
frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//is just an example
changeName = new JLabel("Stefan");
//is just an example
button = new JButton("Change");
button.addActionListener(new changeLabel());
frame.getContentPane().add(changeName, BorderLayout.NORTH);
frame.getContentPane().add(button, BorderLayout.SOUTH);
frame.setVisible(true);
}
public static void main(String args[]){
new Something().gui();
}
}
The listener class
package trying;
import java.awt.event.*;
public class changeLabel extends Something implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
changeName.setText("Andrei");
}
}
How can I solve this problem?
The problem is that because the changeLabel class extends Something, it will contain it's own changeName variable which is not initialized == null.
You can:
make the changeLabel implementation private class of Something (good practice) or
pass the JLabel to its constructor.
In both ways changeLabel should not extend Something.
Code Sample #1:
public class Something {
JFrame frame;
JLabel changeName;
JButton button;
public void gui(){
frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//is just an example
changeName = new JLabel("Stefan");
//is just an example
frame.getContentPane().add(changeName, BorderLayout.NORTH);
button = new JButton("Change");
button.addActionListener(new changeLabel());
frame.getContentPane().add(button, BorderLayout.SOUTH);
frame.setVisible(true);
}
public static void main(String args[]){
new Something().gui();
}
class changeLabel implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
changeName.setText("Andrei");
}
}
}
Code Sample #2:
public class Something {
...
public void gui() {
...
button.addActionListener(new changeLabel(changeName));
}
}
public class changeLabel implements ActionListener {
private final JLabel label;
public changeLabel(JLabel label) {
this.label = label;
}
#Override
public void actionPerformed(ActionEvent e) {
label.setText("Andrei");
}
}