How to make one class react to a button pressed in another? - java

Hi I am new to programming and trying to figure things out as I go. Thanks in advance for the help.
I am trying to make a button in one class that when pressed, the other class knows.
Here is the first class that contains the testWindow method that I want to call in my other class.
import javax.swing.*;
import java.awt.event.*;
public class TestWindow {
public static void testWindow() {
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel text = new JLabel("this is a test!",SwingConstants.CENTER);
text.setBounds(0,30,300,50);
JButton button = new JButton("Start");
button.setBounds(100,100,100,40);
frame.add(text);
frame.add(button);
frame.setSize(300,200);
frame.setLayout(null);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//I don't know what to put here
}
});
}
}
And here is the second class where I want to use my testWindow method.
public class MainTest extends TestWindow {
public static void main(String[] arg){
testWindow();
//other stuff that happens when "start" is pressed
}
}
When I run the MainTest class, the testWindow appears as it should. But when the "start" button is pressed, I want to close that frame then do other actions in the main method. How would I go about that?

When I run the MainTest class, the testWindow appears as it should. But when the "start" button is pressed, I want to close that frame then do other actions in the main method. How would I go about that?
You're desiring the functionality of a modal dialog, a window that halts program flow until it has been dealt with. And in this situation you shouldn't be using a JFrame which does not allow for this type of modality, but rather a Swing modal dialog such as a JOptionPane or a JDialog that you create, make modal, and display. Then the GUI program flow halt until the dialog window is no longer visible.
If you do this, all the button's action listener has to do is to close the dialog window that holds it, that's it.
Side note: You're misusing inheritance here, as your MainTest class should most definitely not extend from the TestWindow class. While it may not matter in this simple code, it can and will cause problems in future code.
e.g.,
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;
public class TestWindow {
public static void testWindow() {
// JFrame frame = new JFrame("test");
final JDialog frame = new JDialog((JFrame) null, "Test", ModalityType.APPLICATION_MODAL);
frame.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel text = new JLabel("this is a test!", SwingConstants.CENTER);
// text.setBounds(0, 30, 300, 50);
JButton button = new JButton("Start");
// button.setBounds(100, 100, 100, 40);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.dispose();
}
});
int eb = 15;
JPanel panel = new JPanel(new BorderLayout(eb, eb));
panel.setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
panel.add(text, BorderLayout.PAGE_START);
panel.add(button, BorderLayout.CENTER);
frame.add(panel);
frame.pack();
// frame.setSize(300, 200);
// frame.setLayout(null);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
and
import javax.swing.SwingUtilities;
public class TestTestWindow {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
TestWindow.testWindow();
System.out.println("Called after test window no longer visible");
});
}
}

Related

How to mimic the behavior of JPopupMenu with JDialog?

I'm implementing an "in app" search engine with Swing and I want it to behave exactly like Windows 10's search box.
The search box should:
Open above and to the right of the search button, touching the button's edge.
Have the focus when open.
Close (if open) on a press of the search button.
Close (if open) when pressing with the mouse anywhere out of the search box.
It was perfect if JPopUpMenu could have JDialog as it's child but since it can't I need to implement the behaviors from scratch (or do I?).
This is my first time using Swing and I'm having difficulties implementing everything by myself.
I tried looking for examples online but I couldn't find much helpful information.
Is there a workaround to the fact that JPopUpMenu can't host JDialog?
Are there examples of implementing the behaviors I described?
Thanks
===============================Edit============================
Thanks for the comments so far. I've managed to get the behavior I wanted except one issue.
The following code creates a frame with a button:
public static void main(String[] args){
JFrame mainWindow = new JFrame();
mainWindow.setSize(420,420);
mainWindow.setVisible(true);
JFrame popUp = new JFrame();
popUp.setSize(210, 210);
JButton button = new JButton("button");
mainWindow.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(!button.isSelected()){
button.setSelected(true);
popUp.setVisible(true);
}
else{
button.setSelected(false);
popUp.setVisible(false);
}
}
});
popUp.addWindowFocusListener(new WindowAdapter() {
#Override
public void windowLostFocus(WindowEvent e) {
popUp.setVisible(false);
}
});
}
When I click the button, a pop-up window appears and if I click out of the main window the pop up disappear but then when I want to re-open the pop-up I need to press the button twice.
How can I get the button to operate correctly when the pop-up was closed due to lose of focus?
Your "solution" is very brittle. Try moving the main JFrame before left-clicking on the JButton.
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Netbeans section. Study the rest of the tutorial.
I created a main JFrame that pops up a JDialog. I put the close JButton on the JDialog. The JDialog is modal, meaning you cannot access the main JFrame while the JDialog is visible.
You can place the JDialog anywhere you wish on the screen. Normally, you have a JDialog appear in the center of the parent JFrame. That's where users expect a dialog to appear. I placed the JDialog towards the upper left, just to show you how it's done.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PopupExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PopupExample().createAndShowGUI());
}
private JFrame mainWindow;
public void createAndShowGUI() {
mainWindow = new JFrame("Main Window");
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.add(createMainPanel(), BorderLayout.CENTER);
mainWindow.pack();
mainWindow.setLocationByPlatform(true);
mainWindow.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(200, 200, 200, 200));
JButton button = new JButton("button");
panel.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
createAndShowDialog(mainWindow);
}
});
return panel;
}
private void createAndShowDialog(JFrame frame) {
JDialog dialog = new JDialog(frame, "Dialog", true);
dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
dialog.add(createDialogPanel(dialog), BorderLayout.CENTER);
dialog.pack();
// Here's where you set the location of the JDialog relative
// to the main JFrame
Point origin = frame.getLocation();
dialog.setLocation(new Point(origin.x + 30, origin.y + 30));
dialog.setVisible(true);
}
private JPanel createDialogPanel(JDialog dialog) {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
JButton button = new JButton("Close");
panel.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
return panel;
}
}

Weird Issue with JComponent Visibility

I am working on a GUI project with Swing in Java and the program is generally working fine. However, under each screen, I have a back button that calls the method of the screen before it and goes through the ArrayList containing all of the elements on the current screen and calls setVisible(false) on them. Upon running the program, the back button works correctly if you click it once but if you go back on the screen, and click it again, it takes two clicks for it to correctly work and then four clicks and then eight clicks and so on. I have no idea what is going on or why it is behaving this way as nothing in my code seems to do it. Also, sometimes, the button correctly returns to the previous screen but then keeps the components on the current screen active as if setVisible(false) was never called. The following code represents the general structure of my project. Is there anything that it is doing that is generating this problem?
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MAIN {
static JFrame frame;
static JPanel panel;
public static void main(String [] args) {
mainScreen();
}
public static void mainScreen() {
JButton newScreen = new JButton("Next Screen");
frame = new JFrame();
panel = new JPanel();
panel.setBounds(0,0,1920,1080);
panel.setBackground(Color.cyan);
newScreen.setBounds(50, 500, 100, 500);
newScreen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
newScreen.setVisible(false);
JButton returnButton = new JButton("return");
returnButton.setBounds(50, 50, 100, 100);
panel.add(returnButton);
returnButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
returnButton.setVisible(false);
mainScreen();
}
});
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.add(newScreen);
frame.add(panel);
frame.setSize(1920,1080);
frame.setLayout(null);
frame.setVisible(true);
}
}

Calling different screen thru button from a screen

Hello I would like to ask how can I call my Main menu screen from MainScreen? and kindly explain a little more details about Listener.
below is my prepared code:
public class MainScreen {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(panel);
frame.setVisible(true);
}
private static void placeComponents(JPanel panel) {
JLabel WelcomeNote = new JLabel("Welcome");
panel.add(WelcomeNote);
JButton Start = new JButton("Start");
panel.add(Start);
//Insert action for Start button here
}
}
public class MainMenu {
public static void main(String[] args){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(panel);
frame.setVisible(true);
}
private static void placeComponents(JPanel panel) {
JLabel menuLbl = new JLabel("Main Menu");
panel.add(menuLbl);
}
}
What is wrong?
You cannot have two main methods in a single file in Java.
Program
Here is a demo program to change windows.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class First extends JFrame
{
JLabel jlb = new JLabel("Label in First Window");
JButton jb = new JButton("Next Window");
First()
{
super("First Windows");
//Set this frame
this.setSize(350,250);
this.setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Setting size of components
jlb.setBounds(10,10,200,40);
jb.setBounds(10,120,150,40);
add(jlb);
add(jb);
jb.addActionListener((e)->{
this.setVisible(false);
new Second();
});
setVisible(true);
}
}
class Second extends JFrame implements ActionListener
{
JLabel jlb = new JLabel("Label in Second Window");
JButton jb = new JButton("Prev. Window");
Second()
{
super("Second Window");
this.setSize(350,250);
this.setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Setting size of components
jlb.setBounds(10,10,200,40);
jb.setBounds(10,120,150,40);
add(jlb);
add(jb);
jb.addActionListener(this);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
this.setVisible(false);
new First();
}
}
class StartHere
{
public static void main(String[] args) {
Runnable r = ()->{
new First();
};
r.run();
}
}
Understanding the above program.
The StartHere class has a main method. It is just used for calling the first window you like. I could even call Second using new Second().
First and Second are similar codes.
Both of them have buttons. On each button (or JButton) I have added a method named addActionListner(this). This method fires up an ActionEvent which as you can see in Second class is captured by actionPerformed method. This method is declared in Functional Interface, ActionListener. The 'this' passed in Second class is you telling where the actionPerformed method is present in your code. The parameter is an ActionListener. Hence, you have to implement ActionListener for the class where you define actionPerformed.
Bonus
The First class doesn't seem to follow the norms described above. I passed a strange syntax. It is a new feature included in Java 8.
See this Oracle tutorial about Lambda Expressions.

Java JButton - making simple menu

Hi take a look on this code:
package arkanoid;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.event.*;
public class Arkanoid extends JFrame
{
private static final long serialVersionUID = 6253310598075887445L;
static JFrame frame;
static class Action1 implements ActionListener {
public void actionPerformed (ActionEvent e) {
//frame = new JFrame("Arkanoid");
frame.setLocationRelativeTo(null);
frame.setIgnoreRepaint(true);
frame.setResizable(false);
frame.setVisible(true);
frame.setSize(500,400);
frame.add(new Gra());
}
}
static class Action2 implements ActionListener {
public void actionPerformed (ActionEvent e) {
frame.dispose();
System.exit(0);
}
}
public static void main(String[] args)
{
//new Arkanoid();
frame = new JFrame("Arkanoid");
frame.setSize(500,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Arkanoid BETA");
frame.setLocationRelativeTo(null);
frame.setIgnoreRepaint(true);
frame.setResizable(false);
frame.setVisible(true);
JPanel panel = new JPanel();
frame.add(panel);
JButton button = new JButton("Nowa Gra");
panel.add(button);
button.addActionListener (new Action1());
JButton button2 = new JButton("Wyjscie");
panel.add(button2);
button2.addActionListener (new Action2());
}
}
This code almost works, I want to make a button2 a quit button working like X button in top right frame's icons and button1 need to open a Gra() in the same window. When im doing it like this it isnt work fine:/ i need to click 2 times on button1 to go to Gra() and what is more KeyListeners in Gra() arent working :(
Im new in buttons, frames and panels in java so please help with this code. Correct it please.
There are a number of fundamental problems with your code, the least of which is why your button1 requires 2 clicks.
However, for your problem you should try rearranging the order of your button1 listener, so that your Component is added to the frame first, before setting it to be visible. An example that should work:
static class Action1 implements ActionListener {
public void actionPerformed (ActionEvent e) {
frame.add(new Gra());
frame.revalidate();
}
}
Note you have already set the size, location etc of frame in main, so there is no need to set them again every time the button is clicked.
I stress that there are more important problems with your code than this issue. You should take a look at Java's Modifier Types (static does not seem applicable here), as well as object-oriented concepts such as inheritance (you define your Arkanoid class to extend JFrame, yet have a JFrame object as a class variable).
I want to make a button2 a quit button working like X button in top right frame's
You can use the ExitAction class found in Closing an Application.
For other examples of how to use buttons read the Swing tutorial on How to Use Buttons. This is the place to start for all you Swing related questions.
There are many problems with your code. I've refactored it a little. With below code & #ricky116 answer I think you should get all of them.
import javax.swing.*;
import java.awt.Color;
import java.awt.event.*;
public class Arkanoid extends JFrame
{
public Arkanoid() {
super("Arkanoid");
setSize(500,400);
setTitle("Arkanoid BETA");
setLocationRelativeTo(null);
setResizable(false);
final JPanel panel = new JPanel();
setContentPane(panel);
panel.add(new JButton(new AbstractAction("Nowa Gra") {
public void actionPerformed (ActionEvent e) {
panel.removeAll();
panel.add(new Gra());
panel.revalidate();
panel.repaint();
}
});
panel.add(new JButton(new AbstractAction("Wyjscie") {
public void actionPerformed (ActionEvent e) {
Arkanoid.this.setVisible(false);
}
});
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Arkanoid frame = new Arkanoid();
frame.setVisible(true);
}
});
}
}

ActionListener Event in Java

Ok, i started learning java, and this is a code from internet that doesn't work on my pc
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class form2
{
public static void main(String args[])
{
// Create Frame 1
JFrame frame = new JFrame("Frame 1");
frame.setSize(333,333);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create panel
JPanel panel = new JPanel();
// Create button
JButton button = new JButton("Press me!");
// Add things
panel.add(button);
frame.add(panel);
frame.setVisible(true);
// Add the action listener to that button
button.addActionListener(new action());
static class action implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
// Create Frame 2
JFrame frame2 = new JFrame("Frame 2");
frame2.setSize(200,200);
frame2.setVisible(true);
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Clicked!");
JPanel panel2 = new JPanel();
// First add to frame2 the panel just create
frame2.add(panel2);
// Add to panel the label
panel2.add(label);
}
}
}
}
And it give me an error about action and i don't understand why.
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
action cannot be resolved to a type
Illegal modifier for the local class action; only abstract or final is permitted
at form2.main(form2.java:26)
What is my problem?? On that guy's computer works
http://www.youtube.com/watch?v=jEXxaPQ_fQo&feature=channel_video_title
Can anyone help me??
You are declaring a static class inside of a method which you shouldn't do. So take it out of the method, or better, make it an anonymous inner class:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Create Frame 2
JFrame frame2 = new JFrame("Frame 2");
frame2.setSize(200, 200);
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Clicked!");
JPanel panel2 = new JPanel();
// First add to frame2 the panel just create
frame2.add(panel2);
// Add to panel the label
panel2.add(label);
frame2.setVisible(true);
}
});
What does this question have to do with java-ee by the way??
You declare a class inside a method, in this case main, however, it should be outside of it, like the guy in the video says.
Hope that helps!
Static classes cannot be defined inside a method. Move the class definition static class .... { } outside of your main method. Also, it is good practice to start classes with an uppercase character (e.g AddPanelAction).
The actionlistener class must be declared outside of the main method like this:
import javax.swing.*;
import java.awt.event.*;
public class Main
{
public static void main(String args[])
{
// Create Frame 1
JFrame frame = new JFrame("Frame 1");
frame.setSize(333,333);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create panel
JPanel panel = new JPanel();
// Create button
JButton button = new JButton("Press me!");
// Add things
panel.add(button);
frame.add(panel);
frame.setVisible(true);
// Add the action listener to that button
button.addActionListener(new action());
}
public static class action implements ActionListener {
public void actionPerformed(ActionEvent e) {
// Create Frame 2
JFrame frame2 = new JFrame("Frame 2");
frame2.setSize(200,200);
frame2.setVisible(true);
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Clicked!");
JPanel panel2 = new JPanel();
// First add to frame2 the panel just create
frame2.add(panel2);
// Add to panel the label
panel2.add(label);
}
}
}
Or you can declare the actionlistener by using an anonymous inner class like this:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Do things here
}
});
Static classes can not be defined inside a method. Move that class outside the main method or declare your class non-static within the main method itself, if you need . A static class always requires one outer non-static class.
A day late and dollar short.... but I'll still add it.
Most of the Java actionListener examples on the web are too darn complex. To understand it, you just really need a form, button, and the actionListener. In the example below, the form server as the listener through the addition of 'implements ActionListener'.
import java.applet.Applet;
import java.awt.Button;
import java.awt.Toolkit;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Sample extends Applet implements ActionListener {
Button button;
public void init() {
setLayout(new BorderLayout());
button = new Button("Test");
add("Center", button);
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
// your code to do what you want when the button was clicked goes here
}
}

Categories

Resources