How do I call a GUI form from another Java class - java

So I have been figuring out how to make this work but I can't find , so I decided to look for help, the below is how my code look like,What I'm trying to do is display the Main Menu after the user refuse to proceed the tutorial and I tried to
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Login {
public Login() {
String userName;
int option;
//This will ask user to input the username
userName = JOptionPane.showInputDialog(null,"Please enter your name","Welcome", JOptionPane.INFORMATION_MESSAGE);
//Display option
option =JOptionPane.showOptionDialog(null, "Welcome " + userName + "\n\nWould you like to have a tutorial about this game?",
"Welcome", JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
//Ok to continue to the tutorial
if(option == JOptionPane.OK_OPTION)
{
//Call the tutorial class
}
This is where the code gone wrong and I tried to resolve with different ways
else //If select cancel will proceed to the Main menu
{
//This is the part I can't figure it out, it display different errors when I try different ways
that I searched from website
MainMenu MainMenuGUI = new MainMenu();
}
}
}
And here's my Main Menu code
import javax.swing.*;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.*;
import javax.swing.*;
public class MainMenu {
private JButton exitButton;
private JPanel MainMenu;
private JButton startButton;
private JButton historyButton;
public MainMenu() {
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int exitButton = JOptionPane.YES_NO_OPTION;
exitButton = JOptionPane.showConfirmDialog(null, "Are you sure you want to exit?", "Warning", JOptionPane.YES_NO_OPTION);
if (exitButton == JOptionPane.YES_OPTION)
{
System.exit(0);
}
}
});
}
//Main Menu GUI setup
public static void main(String[] args) {
JFrame frame = new JFrame("Main Menu");
frame.setContentPane(new MainMenu().MainMenu);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setMinimumSize(new Dimension(500, 500));
frame.pack();
frame.setVisible(true);
}
}

Your current code has a couple of problems.
By creating the JFrame container in your main method, you're preventing the UI from ever showing up when instantiating MainMenu - that is, the UI will only show anything when the main method is invoked by the JVM. To fix this, I've moved your JFrame instantiation/setup into MainMenu's constructor.
In the MainMenu class, the mainMenu JPanel is never instantiated. This means your current code doesn't actually paint anything on the JFrame - you need to instantiate mainMenu and add your GUI controls to mainMenu.
The code below fixes both problems.
public class MainMenu
{
private JButton exitButton;
private JPanel mainMenu;
private JButton startButton;
private JButton historyButton;
public MainMenu()
{
JFrame frame = new JFrame("Main Menu");
///// mainMenu IS ALWAYS NULL WITHOUT THE NEXT LINE!!!!
this.mainMenu = new JPanel();
frame.setContentPane(this.mainMenu);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setMinimumSize(new Dimension(500, 500));
frame.pack();
frame.setVisible(true);
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
int exitButton = JOptionPane.YES_NO_OPTION;
exitButton = JOptionPane.showConfirmDialog(null, "Are you sure you want to exit?", "Warning", JOptionPane.YES_NO_OPTION);
if (exitButton == JOptionPane.YES_OPTION)
{
System.exit(0);
}
}
});
}
//Main Menu GUI setup
public static void main(String[] args)
{
new MainMenu();
}

Get rid of the public static void main(String args[]) method in your MainMenu class. You only use the main method once in a java program. Instead, create a method like public void initUI() and place all the code you have inside the main() method in it.
And in your Login class, right after you call MainMenu MainMenuGUI = new MainMenu();
you can call MainMenuGUI.initUI().
One small thing, MainMenuGUI should probably be mainMenuGUI to properly follow camel case formatting and to avoid confusion later on.

Related

How to hide a JPopupMenu by pressing a button?

I'm making a program that has a popup menu with two buttons, one of which should close the popup menu, but I have no idea how to do that and googling hasn't gone too well.
I've tried using popup.hide() but then the menu wouldn't come back, despite doing so when I tried just moving the popup. It also required me to put a SuppressWarning in that case and it took a few seconds for it to close at all. Is there any better way of doing it?
I'm not sure what kind of code is relevant, but here's the relevant buttons and their roles in this(I skipped all the creating the GUI parts that didn't seem relevant, everything looks good and I know that the buttons are working):
package test;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
interface CustomButton {
JButton create();
void react(JPopupMenu popup, JFrame frame);
}
class ErrandsButton implements CustomButton {
private JButton errands = new JButton("Errands");
public JButton create() {
return errands;
}
public void react(JPopupMenu popup, JFrame frame) {
errands.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
popup.show(frame, 120, 65);
}
});
}
}
class Test {
static JFrame frame = new JFrame("List");
static CustomButton errands = new ErrandsButton();
static JButton cancelTask = new JButton("Cancel");
static JPopupMenu popup = new JPopupMenu();
static void cancelTask() {
cancelTask.addActionListener(new ActionListener() {
#SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent e) {
popup.hide();
}
});
}
public static void main(String args[]) {
createInterface();
cancelTask();
errands.react(popup, frame);
}
static void createInterface() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
JPanel popup1 = new JPanel();
JPanel button = new JPanel();
popup1.add(cancelTask);
popup.add(popup1);
frame.add(popup);
button.add(errands.create());
frame.getContentPane().add(BorderLayout.CENTER, button);
frame.setVisible(true);
}
}
Use popup.setVisible(true) and popup.setVisible(false).
frame.add(popup); is the problem. Do not add a JPopupMenu to a Container. Instead, use setComponentPopupMenu.
Alternatively, you could do the work yourself by adding a MouseListener whose mousePressed, mouseReleased and mouseClicked methods call isPopupTrigger and show. (It is vital that you do this in all three of those methods—different platforms have different conditions for showing popup menus.)
But really, using setComponentPopupMenu is easier.

JButton Action Listener not working

I'm making a short text adventure game as my first big application, and I've run into a problem. I'm using GUI for my game, and my problem is with the action listener I'm using for the second button, proceed. All of the other code works, except for the method buttonAction. I added an action listener to proceed and whenever I run the code and click proceed, nothing happens and I can't figure out why. I moved the code now found in init2() from actionPerformed(), but it had no effect. I've also tried using #Override on buttonAction, but it gives me the error "The method buttonAction(ActionEvent) of type SimpleGui must override or implement a supertype method". Please keep in mind that my java skills are at best, elementary, so please try to explain as best you can. Any help would be greatly appreciated. The code from my application is below.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import Classes.Rogue;
import Classes.Warrior;
import Classes.Wizard;
public class SimpleGui extends JFrame implements ActionListener {
public JPanel panelControl, panel, panel2, panel3, panel4;
public JButton create, proceed;
public JTextField name;
public final JTextField textField = new JTextField();
public JComboBox playerClass;
public Char player1;
public String[] classOptions = { "Rogue", "Wizard", "Warrior" };
public JLabel textObject;
SimpleGui() {
super("RPG Quest");
name = new JTextField(20);
init();
this.setVisible(true);
this.setSize(455, 250);
this.setResizable(false);
}// end SimpleGui
public void init() {
panel = new JPanel();
panel3 = new JPanel();
panel2 = new JPanel();
playerClass = new JComboBox(classOptions);
create = new JButton("Create Character");
create.addActionListener(this);
textObject = new JLabel("Name");
panel.setBorder(BorderFactory
.createTitledBorder("<html><font color:black>Create Your Character</font></html>"));
panel.add(textObject);
panel.add(name);
panel.add(playerClass);
panel.setBackground(Color.WHITE);
panel3.setBorder(BorderFactory
.createTitledBorder("<html><font color:black>Class Descriptions</font></html>"));
panel3.add(new JLabel(
"<html><font color:black>The Rogue has a 20% chance to land Critical Hits on enemies.</font></html>"));
panel3.add(new JLabel(
"<html><font color:black>The Wizard can only cast spells and has only a 70% chance of landing a hit,</font></html>"));
panel3.add(new JLabel(
"<html><font color:black>but spells do more damage than melee attacks.</font></html>"));
panel3.add(new JLabel(
"<html><font color:black>The Warrior has a 30% chance to block an incoming attack.</font></html>"));
panel3.setBackground(Color.WHITE);
panel2.add(create);
panel2.setBackground(Color.WHITE);
this.add(panel);
this.add(panel3);
this.add(panel2);
this.pack();
this.setResizable(true);
this.setLayout(new BorderLayout());
this.add(panel, BorderLayout.NORTH);
this.add(panel3);
this.add(panel2, BorderLayout.SOUTH);
}// end void
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() == create) {
String type = classOptions[playerClass.getSelectedIndex()];
if (type == "Rogue") {
player1 = new Rogue();
}
if (type == "Wizard") {
player1 = new Wizard();
}
if (type == "Warrior") {
player1 = new Warrior();
}
player1.name = name.getText();
JOptionPane.showMessageDialog(this, "You are a " + type
+ ". Your name is " + player1.name + ".");
init2();
}
}
public void init2() {
this.remove(panel);
this.remove(panel2);
this.remove(panel3);
panel.remove(textObject);
panel.remove(name);
panel.remove(playerClass);
panel.setBorder(BorderFactory
.createTitledBorder("<html><font color:black>Info</font></html>"));
panel.setBackground(Color.WHITE);
proceed = new JButton("Proceed");
proceed.addActionListener(this);
panel.add(proceed);
textField.setText("Hello There");
textField.setEditable(false);
panelControl = new JPanel();
panelControl.setBackground(Color.WHITE);
panelControl.setBorder(BorderFactory.createBevelBorder(NORMAL));
panelControl.add(textField);
this.add(panelControl, BorderLayout.NORTH);
this.add(panel, BorderLayout.SOUTH);
this.pack();
}
public void buttonAction(ActionEvent event) {
proceed.addActionListener(this);
if (event.getSource() == proceed) {
JOptionPane.showMessageDialog(this, "It Works!");
System.out.println("hi");
}
}
}
// end class
Since your class implements ActionListener, it must define an implementation for actionPerformed, which you have correctly done. Now when you say
proceed.addActionListener(this);
you are essentially connecting the button to the actionPerformed defined in your class, and not to the buttonAction() method you seem to wish to connect to. This is the same listener that create is connected to. You should be able to fix this by using
public void actionPerformed(ActionEvent event) {
if (event.getSource() == create) {
String type = classOptions[playerClass.getSelectedIndex()];
if (type == "Rogue") {
player1 = new Rogue();
}
if (type == "Wizard") {
player1 = new Wizard();
}
if (type == "Warrior") {
player1 = new Warrior();
}
player1.name = name.getText();
JOptionPane.showMessageDialog(this, "You are a " + type
+ ". Your name is " + player1.name + ".");
init2();
} else if (event.getSource() == proceed)
{
JOptionPane.showMessageDialog(this, "It Works!");
System.out.println("hi");
{
}
This would make buttonAction() unnecessary. I will add that instead of implementing ActionListener, you could define listeners as inner classes, and connect buttons to them individually, making the code cleaner. Something for you to research :)
You have written
proceed.addActionListener(this);
So whenever you are clicking on the JButton proceed you are basically calling actionPerformed(ActionEvent event) of the class SimpleGui. Now the actionPerformed method does not have any code for proceed. So, it does nothing.
I would here suggest that you add the code for proceed variable in the actionPerformed method of the class SimpleGui. You could add the following after the existing code of you actionPerformed as illustrated below:
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() == create) {
//Your existing code;
} else if (event.getSource() == proceed){
//put the code for proceed action here.
}
}
I hope that this will solve your problem.
You made the event handler be 'this', means when the button clicked, the
#Override public void actionPerformed(ActionEvent event)
will be triggered.
public void buttonAction(ActionEvent event)
is useless in your code. And you cannot use #Override on it because none of the interface have this method signature.
if (event.getSource() == create)
will only allow the create button to pass.
So, the solution can be add another condition and add your code for proceed button, in the actionPerformed method.
if (event.getSource() == create){...}
else if (event.getSource() == proceed){...}

Waiting till button is pressed

There are a lot questions on this, but they weren't able to help me or I didn't understand it..
Basically I want user to press the button before system goes back to main method. In this case if system goes back to main method, system will quit.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class test123 implements ActionListener{
JTable table;
JButton button;
JFrame frame;
public test123 (){
frame = new JFrame();
frame.setLayout(null);
button = new JButton("Finish");
button.setBounds(200, 10, 70, 40);
button.addActionListener(this);
frame.add(button);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setSize(600, 200);
frame.setVisible(true);
frame.setTitle("TEst123");
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == button){
System.out.println("message....");
}
}
public static void main(String arg[]){
test123 gui = new test123();
System.exit(0);
}
}
Sorry if it was just me lacking the understanding and thank you for help.
EDIT:
Maybe I explained this incorrectly or displayed it incorrectly. Lets say if the system goes back to main system it will do something I don't want, therefor I want the user to press the button to go back to the main system or do "the thing". Sorry for bad explanation, including this one.
This class is separate from my work and I just used it to test stuff... In my project, user can choose from several buttons (lets say main method is the menu in this case). The user presses a button goes to a new window/frame, if the program doesn't pause or waits for button to be pressed, it will go back to main method.
The quick answer is what Andrew Thompson wrote in his comment:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTable;
public class test123 implements ActionListener {
JTable table;
JButton button;
JFrame frame;
public test123() {
frame = new JFrame();
frame.setLayout(null);
button = new JButton("Finish");
button.setBounds(200, 10, 70, 40);
button.addActionListener(this);
frame.add(button);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setSize(600, 200);
frame.setVisible(true);
frame.setTitle("TEst123");
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
System.out.println("message....");
// System.exit(0);
frame.dispose(); // better than exit
}
}
public static void main(String arg[]) {
test123 gui = new test123();
}
}
but Java class name should start with upper case test123 -> Test123 (but you can find a lot better name for sure).
Why not to extend JFrame also?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Test123 extends JFrame implements ActionListener {
private static final long serialVersionUID = 3378774311250822914L;
// private JTable table;
private JButton button;
// JFrame frame;
public Test123() {
// frame = new JFrame();
this.setLayout(null);
button = new JButton("Finish");
button.setBounds(200, 10, 70, 40);
button.addActionListener(this);
this.add(button);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(600, 200);
this.setTitle("Test123");
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
System.out.println("message....");
// System.exit(0);
this.dispose();
}
}
public static void main(String arg[]) {
Test123 gui = new Test123();
}
}
Read more in Concurrency in Swing tutorial to find out how to deal with long running tasks out of dispatch thread...
From your question it seems, that you do not know how swing application behaves. You create a GUI and the you are waiting for user's input. So basically you do not care what was your program executing, when user pressed the button...
(and therefore it doesn't matter where it returns to)

making JOptionPane disappear

public void windowClosing (WindowEvent e)
{
JFrame frame = new JFrame();
int confirm = JOptionPane.showConfirmDialog (frame, "Exit game?", "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (confirm == JOptionPane.YES_OPTION)
{
dispose ();
}
else
{
frame.setVisible(false);
}
}
So when the user clicks on the close button, a JOptionPane pops up. When the user clicks on "No" the JOptionpane is supposed to disappear and then return to the frame it was originally displaying, but with my code, even when I click on No, both frames, the one for the JOptionPane and the one it sits on, disappear.
One thing:
I know I should not create a new JFrame for a JOptionPane, but I tried using this for the component, like: JOptionPane.showConfirmDialog (this, "...",...) when the user clicks on "No" the JOptionPane is the only thing that's supposed to disappear (so I set it to: this.setVisible(false);) but when I use this even the main frame disappears, so I just thought to create a new frame to meet my needs. I can't set it to null either because I need it to appear at the center of the screen. If anyone could advise me on how to handle this, please do.
It's really simple, your frame disappear because you say that it should not be visible, just remove that else:
public void windowClosing (WindowEvent e) {
int confirm = JOptionPane.showConfirmDialog (this, "Exit game?", "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (confirm == JOptionPane.YES_OPTION) {
dispose();
}
}
EDIT:
Also replace setDefaultCloseOperation (EXIT_ON_CLOSE); with setDefaultCloseOperation (DO_NOTHING_ON_CLOSE);, else the main frame would close regardless of what happens in the windowClosing method.
Just don't put else if you don't want to hide the frame. The JOptionPane will disappear by itself, whether you click yes or no.
Don't create a new JFrame in the method. That's why you have random frame from now where.
public void windowClosing (WindowEvent e)
{
JFrame frame = new JFrame();
Pass the reference of the JFrame in question. If the code above is from a JDialog you can do something like this
public class MyDialog extends JDialog {
public MyDialog(final JFrame frame, boolean modal) {
super(frame, modal);
public void windowClosing (WindowEvent e) {
int confirm = JOptionPane.showConfirmDialog (frame, "Exit game?", "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (confirm == JOptionPane.YES_OPTION) {
dispose ();
}
}
}
}
And just instantiate the JDialog like this from your GUI class with the JFrame
MyDialog dialog = new MyDialog(thisFrame, true);
Side Note
Why Even have a JOptionPane and a JDialog? Ultimately, a JDialog is just a custom JOptionPane, they have the same functionality.
EDIT
If you just want to pass the JFrame class as reference to the JOPtionPane just pass
MyFrameClass.this
instead of a new JFrame()
UDPATE
Test out this program using a simple custom JDialog.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JDialogExample extends JFrame {
public JDialogExample() {
JButton exit = new JButton("Do you want to Exit?");
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new HelloDialog(JDialogExample.this, true);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(exit);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private class HelloDialog extends JDialog {
public HelloDialog(final JFrame frame, boolean modal) {
super(frame, modal);
JButton exit = new JButton("EXIT");
JButton cancel = new JButton("CANCEL");
setLayout(new GridLayout(2, 1));
JPanel panel = new JPanel();
panel.add(exit);
panel.add(cancel);
add(new JLabel("Do you want to exit?", JLabel.CENTER));
add(panel);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
pack();
setLocationRelativeTo(frame);
setVisible(true);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JDialogExample();
}
});
}
}

ActionListener problem

i am trying to make an actionListener on a button in another button which has also an actionlistener and i just couldn't figure it out for some way. I am trying to make an action on the 2nd button but i couldn't figure it out.If anyone helps me i'd appreciate! here is the code below:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class basic implements ActionListener{
public static void main(String[] args) {
basic process = new basic ();
}
public basic(){
JFrame fan = new JFrame("Scheme");
JPanel one = new JPanel(new BorderLayout());
fan.add(one);
JPanel uno = new JPanel();
uno.setLayout(new BoxLayout(uno, BoxLayout.Y_AXIS));
JButton addB = new JButton("first choice");
addB.setAlignmentX(Component.CENTER_ALIGNMENT);
uno.add(addB);
addDButton.setActionCommand("hehe");
addDButton.addActionListener(this);
one.add(uno,BorderLayout.CENTER);
fan.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fan.setSize(500,700);
fan.setLocationByPlatform(true);
fan.setVisible(true);
}
public void actionPerformed(ActionEvent evt) {
JPanel markP = new JPanel(new FlowLayout(FlowLayout.RIGHT,10,20));
JDialog dialog = new JDialog((JFrame)null);
dialog.getContentPane().add(markP,BorderLayout.CENTER);
if (evt.getActionCommand().equals("hehe")) {
JLabel title = new JLabel("Proceed");
title.setFont(new Font("Arial",Font.BOLD,15));
markP.add(title,BorderLayout.NORTH);
JButton exit = new JButton("Exit");
markP.add(exit);
//here i want to create another actionListener on the exit button only without affecting the other content which is in the button "addB " so that when i click on the addB button the J dialog pops up, and than when i click on exit button the program will return to the menu.I couldn't figure it out.
dialog.toFront();
dialog.setModal(true);
dialog.pack(); //
dialog.setLocationRelativeTo(null); //
dialog.setVisible(true);
}
// here the code goes on but the problem is that of the actionListener which is concerned.
JButton exit = new JButton("Exit");
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// you code here
}
});
You should use better variables names. It is not easy to follow your code
You could use the same ActionListener if you check the source of the action using
if (evt.getSource().equals(addDButton) { original code }
else { code for the other button }

Categories

Resources