Java Swing - How to make JMenuItem open a new frame - java

I am trying to create a program where when the user clicks a JMenuItem (basic) in the frame in class2, it opens the frame in class1. However, when I try to run the code, I keep getting errors about how it can't find the "setVisible" method. I was wondering whether something could give me some pointers. Also, both classes are stored in different java files (but in the same folder).
CLASS 1:
public class CalculatorFrame {
private JFrame frame;
public String calc = "";
public CalculatorFrame() {
frame = new JFrame("Basic Calculator");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
CLASS 2:
public class CalculatorFrameA extends CalculatorFrame{
private JFrame frameA;
public CalculatorFrameA() {
frameA = new JFrame("Advanced Calculator");
frameA.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ActionListener basicListener = new ActionListener(){ //basic is a JMenuItem
#Override
public void actionPerformed(ActionEvent e){
CalculatorFrame frame = new CalculatorFrame();
//frame.show();
frameA.dispose();
frame.setVisible(true);
}
};

Related

How do i switch between screens in swing

This has been asked before but I would like clarification, I'm new to java coding (sort of, started coding last month) and would like to know simply how can I switch between UIs in one JFrame, Picture this, a settings menu, How do I make it in one JFrame window instead of just make a new window with all the settings, If you don't get it, ask for clarification.
You can implement a frame (JFrame) and, for example, two panels (JPanel). Initially you embed panel A inside frame, when you want to show panel B then call the method showPanelB()
public class MyFrame extends JFrame {
PanelA panelA = new PanelA();
PanelB panelB = new PanelB();
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MyFrame().setVisible(true);
}
});
}
public MyFrame() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
showPanelA();
}
public void showPanelA() {
getContentPane().add(panelA, BorderLayout.CENTER);
}
public void showPanelB() {
getContentPane().add(panelB, BorderLayout.CENTER);
}
}
class PanelA extends JPanel {
// Panel implementation
}
class PanelB extends JPanel {
// Panel implementation
}

Setting up main-class to incorporate multiple JFrames/Gui Forms

I'm using IntelliJ IDEA, and I have created two GUI forms I want to use as screens for my application.
However I am stuck on how to get my separate main-class to incorporate the two JFrames, and how to control the switch from one JFrame to another. In the code below in the main-class, I'm first initializing an object of both GUI forms, afterwards I'm running the setup-frames 'run' method, which sets the frame visible. This step works.
Now I want an actionListener on my button 'udførButton' which gets the values typed in it's TextFields, so that I can use them as parameters to initialize an instance of the 'Billetautomat' class.
Furthermore, I want the button to close the 'setup' JFrame and to start up the 'gui' JFrame with the gui.run() method.
My intended flow in the program is:
Run 'setup' gui, where I can type in three names and three ints
Run 'gui' (not done designing yet), where I can press multiple buttons to trigger different actions
Run other JFrames for non-specified actions and return to 'gui' (step 2)
Problem is, that the actionListener won't work as I want it to... If I change the code inside the actionListener to billet1Label.setText("HELLO"); it indeed changes the Label's text to display HELLO, but I can't make it work as I intend... I think the problem is that the program doesn't stop and wait for my button click, but just races through the main code...
Do I need some sort of check to see if the button has been pressed, or have you got any expert-advise?
This is my first time working with Swing in Java, so please be patient with me...
The final and the [] on the variables was suggested by IntelliJ....
BenytBilletautomat_GUI.java (main-class)
package automat;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class BenytBilletautomat_GUI {
public static void main(String[] args) {
final int[] pris1 = new int[1];
final int[] pris2 = new int[1];
final int[] pris3 = new int[1];
final String[] navn1 = new String[1];
final String[] navn2 = new String[1];
final String[] navn3 = new String[1];
Setup_GUI setup = new Setup_GUI();
Billetautomat_GUI gui = new Billetautomat_GUI();
setup.udførButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
navn1[0] = setup.getBillet1Text();
pris1[0] = setup.getBilletPris1();
navn2[0] = setup.getBillet1Text();
pris2[0] = setup.getBilletPris1();
navn3[0] = setup.getBillet1Text();
pris3[0] = setup.getBilletPris1();
Billetautomat automat = new Billetautomat(navn1[0],pris1[0],navn2[0],pris2[0],navn3[0],pris3[0]);
setup.frame.setVisible(false);
setup.frame.dispose();
gui.run();
}
});
setup.run();
}
}
Setup_GUI.java (setup gui class)
package automat;
import javax.swing.*;
public class Setup_GUI {
private JPanel mainPanel;
private JLabel gui_title;
private JTextField billet1Text;
private JTextField billet2Text;
private JTextField billet3Text;
private JLabel billet1Label;
private JLabel billet2Label;
private JLabel billet3Label;
private JLabel setupLabel;
private JTextField billetPris1;
private JTextField billetPris2;
private JTextField billetPris3;
public JButton udførButton;
JFrame frame = new JFrame("Setup");
public void run() {
frame.setContentPane(new Setup_GUI().mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public String getBillet1Text() {
return billet1Text.toString();
}
public String getBillet2Text() {
return billet2Text.toString();
}
public String getBillet3Text() {
return billet3Text.toString();
}
public int getBilletPris1() {
return Integer.parseInt(billetPris1.toString());
}
public int getBilletPris2() {
return Integer.parseInt(billetPris2.toString());
}
public int getBilletPris3() {
return Integer.parseInt(billetPris3.toString());
}
}
Billetautomat_GUI.java (gui class, not done yet)
package automat;
import javax.swing.*;
import java.awt.event.ComponentAdapter;
public class Billetautomat_GUI {
JFrame frame = new JFrame("Billetautomat_GUI");
private JPanel mainPanel;
public void run() {
frame.setContentPane(new Billetautomat_GUI().mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}

Java Swing - .dispose() method not closing JFrame

I'm writing a simple game that is based on two JFrames. The user is only displayed on JFrame at a time. To get to the other JFrame, the user clicks a button. The button in the new JFrame will have an overriden method that should navigate the user back to the old JFrame.
I've found success doing this however the .dispose() method doesn't seem to close the new frame when the user tries to navigate back to the old frame.
Here's a snippet of my code (original JFrame class):
public class TicTacToe extends JFrame implements ActionListener{
....
public class gameModeListener implements ActionListener
{
#Override public void actionPerformed(ActionEvent e)
{
TicTacToeSingle singlePlayer = new TicTacToeSingle();
singlePlayer.setVisible(true);
dispose();
}
}
}
And from the other JFrame class:
public class TicTacToeSingle extends TicTacToe{
private int i;
private int j;
JButton boardArray[][];
Random random_generator = new Random();
int randomI;
int randomJ;
public TicTacToeSingle()
{
super("Single Player");
gameMode.setText("Two Player"); //gameMode is the button that has it's actionlistener method overriden. It navigates the user to and back from JFrame to JFrame
gameMode.addActionListener(new gameModeListener());
....
}
....
public class gameModeListener implements ActionListener
{
#Override public void actionPerformed(ActionEvent e)
{
TicTacToe twoPlayer = new TicTacToe("Two Player");
twoPlayer.setVisible(true);
dispose();
}
}
Your help is greatly appreciated :)
Well when u have used Object of the class and u are calling just Dispose(); then how compiler came to know that for this particular class object should be dispose on that call.?
so for giving reference u need to use this try this:
TicTacToe twoPlayer = new TicTacToe("Two Player");
twoPlayer.setVisible(true);
twoPlayer.dispose();
if still there is prob let me know.

Passing values between classes

I have a JPanel form which contains a JList and some JButton.
The JPanel looks like this
When I click the Add List button, a separate JFrame form is displayed.
The JFrame form will look like this
When the add button on the JFrame is clicked, I need to add the value of the JTextfield (named List Name) to the JList on the previous JPanel. I wonder how to pass the value from the JFrame to the JPanel? Any suggestion would be appreciated.
Here is a code of the JPanel form (using Designer GUI)
package multimediaproject;
public class musicPlayerPanel extends javax.swing.JPanel {
public musicPlayerPanel() {
initComponents();
}
private void initComponents() {
//...here is the generated code by using designer GUI
}
// Variables declaration - do not modify
//..generated code
// End of variables declaration
}
Here is the code of JFrame form (using Designer GUI)
package multimediaproject;
public class addListFrame extends javax.swing.JFrame {
public addListFrame() {
initComponents();
this.setLocation(515, 0);
setVisible(true);
}
private void initComponents() {
//..here is the generated code by using Designer GUI
}
private void addBtnActionPerformed(java.awt.event.ActionEvent evt){
//some validation
if(...)
{
//validation
}
else
{
//IF VALUE IS CORRECT, ADD the List Name JTextfield value to the JList on the previous JPanel
errorMessage.setText("");
}
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new addListFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
//....generated code
// End of variables declaration
}
UPDATE with your code.
You can take advantage of PropertyChangeListener and PropertyChangeSupport (This classes implements Observer Pattern).
I give you an example you for guidance:
public class MusicPlayerPanel extends JPanel {
private JList list;
private JButton addButton;
private PropertyChangeListener listener = new MyPropertyChangeListener();
//..in some place
addButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
JFrame form = new FrameForm();
form.addPropertyChangeListener(FrameForm.BUTTON_CLICKED,listener);
form.setVisible(true);
}
});
//in another place
private class MyPropertyChangeListener implements PropertyChangeListener{
#Override
public void propertyChange(PropertyChangeEvent evt){
if(evt == null)
return;
if(evt.getPropertyName().equals(FrameForm.BUTTON_CLICKED)){
String value = (String) evt.getNewValue();
((DefaultListModel)list.getModel()).addElement(value);
}
}
}
}
And the frame form like this:
public class AddListFrame extends JFrame{
private JTextField textfield;
private JButton submitButton;
public static final String BUTTON_CLICKED ="buttonClicked";
// in some place
submitButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent evt){
firePropertyChange(BUTTON_CLICKED,null,textfield.getText());
}
});
}
Note: In java by convention, classes start with uppercase and follow a camel style. This is very important for readability.
OK.This is easy if i understand your problem.
Step 1:Create setter and getter for your JList object reference.
Step 2:On button click , when you open new JFrame pass your panel reference in constructor of class which inherits JFrame.
Step 3:By doing this you are able to call getter method on panel reference.
Step 4:Now you have reference of JList,do what you want.
I hope this is best solution of your problem
"when I click the add button, a separate jFrame form is displayed. The jFrame contain a jTextfield and a submit button."
Did you seriously create an entirely new JFrame for a JTextField and a JButton?!
Have you not heard of JOptionPane? That's exactly what you are trying to replicate. The only code you need is this:
String s = JOptionPane.showInputDialog(component, message);
model.addElement(s);
The first line will cover all your code for your custom JFrame.
Take a look at this example
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class JOPDemo extends JPanel {
JList list;
JButton button = new JButton("Add Name");
String name;
DefaultListModel model;
public JOPDemo() {
model = new DefaultListModel();
list = new JList(model);
setLayout(new BorderLayout());
add(list, BorderLayout.CENTER);
add(button, BorderLayout.SOUTH);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
name = JOptionPane.showInputDialog(this, "Enter a name");
model.addElement(name);
}
});
}
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
private static void createAndShowGui() {
JFrame frame = new JFrame();
frame.add(new JOPDemo());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Edit
What you can do is have an inner class which is your JFrame. Personally, I'd go with a JDialog though.
From comment: Have your frame as an inner class of your main class. That way it can access all the variables from your main class. You can have a String listName also in the GUI class. From the other frame when you hit add, it sets the listName in GUI class, then adds to the list.
public class GUI {
String listName;
JList list;
InnerFrame inner = new InnerFrame();
private class InnerFrame extends JFrame {
JButton addButton;
}
}

One JFrame opening another

I have a JFrame and JPanel full of Jsomethings with an actionlistener. When the user clicks an object I want to open another JFrame. Here is what I did:
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == rejectionbutton){
RejectApp ra = new RejectApp();
ra.main(null);
}
}
(RejectApp calls a new JFrame.) So another JFrame opens on the screen with more options. It works OK (so far), but I want to know is this standard? I mean calling the main method like this?
Another question is, without using a cardlayout (which I don't want to use), is the best way to handle multiple panels, by doing this sort of thing?
I would change a few things. First off, usually an application has one JFrame and then if it needs to show another window does so as a modal or non-modal dialog such as can be obtained with a JDialog or JOptionPane. Having said that, it's even more common to have one JFrame and swap "views" in the JFrame -- swap contentPanes or other large panels via a CardLayout as this would mimic the behavior of many gui programs we all currently use.
Personally, I also try to gear my GUI creation towards creating a JPanel or JComponent rather than towards creating a top-level window. This way if I want to display the GUI as a stand alone app, a dialog, or an applet I can pop it into the contentPane of a JFrame or JDialog or JApplet respectively, or if as an inner panel of a more complex GUI, then insert it there, or in an application with a swapping view, then as a card in a CardLayout as noted above. The bottom line is I feel that this structure gives you the developer a lot more options in how you can use this GUI.
Also, I would avoid calling another class's main as you're doing (assuming this is the public static void main method) as you lose all benefits of OOPs. You also seem to be trying to call a static method in a non-static way (assuming I understand your program structure correctly).
For your second question, it begs a question of my own: why do you not want to use CardLayout?
edit: an example of what I meant is as follows:
import java.awt.Dimension;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SwingEg {
private static void createAndShowUI() {
JFrame frame = new JFrame("Main JFrame");
frame.getContentPane().add(new MainGUI().getMainPanel());
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 MainGUI {
private static final Dimension MAIN_PANEL_SIZE = new Dimension(450, 300);
private JPanel mainPanel = new JPanel();
private JDialog modalDialog;
private JDialog nonModalDialog;
public MainGUI() {
JButton openModalDialogBtn = new JButton("Open Modal Dialog Window");
openModalDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openModalDialogBtnActionPerformed(e);
}
});
JButton openNonModalDialogBtn = new JButton("Open Non-Modal Dialog Window");
openNonModalDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openNonModalDialogBtnActionPerformed(e);
}
});
mainPanel.setPreferredSize(MAIN_PANEL_SIZE);
mainPanel.add(openModalDialogBtn);
mainPanel.add(openNonModalDialogBtn);
}
private void openModalDialogBtnActionPerformed(ActionEvent e) {
if (modalDialog == null) {
Window topWindow = SwingUtilities.getWindowAncestor(mainPanel);
modalDialog = new JDialog(topWindow, "Modal Dialog", ModalityType.APPLICATION_MODAL);
modalDialog.getContentPane().add(new DialogPanel().getMainPanel());
modalDialog.pack();
modalDialog.setLocationRelativeTo(topWindow);
modalDialog.setVisible(true);
} else {
modalDialog.setVisible(true);
}
}
private void openNonModalDialogBtnActionPerformed(ActionEvent e) {
if (nonModalDialog == null) {
Window topWindow = SwingUtilities.getWindowAncestor(mainPanel);
nonModalDialog = new JDialog(topWindow, "Non-Modal Dialog", ModalityType.MODELESS);
nonModalDialog.getContentPane().add(new DialogPanel().getMainPanel());
nonModalDialog.pack();
nonModalDialog.setLocationRelativeTo(topWindow);
nonModalDialog.setVisible(true);
} else {
nonModalDialog.setVisible(true);
}
}
public JPanel getMainPanel() {
return mainPanel;
}
}
class DialogPanel {
private static final Dimension DIALOG_SIZE = new Dimension(300, 200);
private JPanel dialogPanel = new JPanel();
public DialogPanel() {
dialogPanel.add(new JLabel("Hello from a dialog", SwingConstants.CENTER));
dialogPanel.setPreferredSize(DIALOG_SIZE);
}
public JPanel getMainPanel() {
return dialogPanel;
}
}
I would rather make a new instance of JFrame or a subclass, or call a new method who makes a new JFrame:
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == rejectionbutton){
JFrame frame = new JFrame("New Frame");
//or
makeNewFrame();
}
}
Another simple Layout-Manager is the BorderLayout, it´s the default Layout-Manager of the JFrame class.
new YourJFrameNameHere().setVisible(true);
Replace YourJFrameNameHere with the JFrame name.
Simple, no?

Categories