-1

I have two java files (classes) PMotion.java and Menu.java.

Menu.java has a button. When I press that button, I want it to dispose the current Menu.java frame and go to the PMotion.java class. As you can see in the file Menu.java, I have

 new PMotion().setVisible(true);
            frame.dispose();

The frame.dispose(); works, as it closes Menu.java. But instead of opening PMotion.java, it just opens a blank JFrame. Please note: I only copied the relevant code from PMotion.java - in reality, it is a fully working application. Help is appreciated!

PMotion.java

import java.awt.EventQueue;
import java.awt.Font;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextPane;
import javax.swing.JTextArea;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JSeparator;
import javax.swing.JScrollBar;


public class PMotion extends JFrame {

    private JFrame frame;


    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    PMotion window = new PMotion();
                    window.frame.setVisible(true);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public PMotion() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame("Projectile Motion");
        frame.setBounds(100, 100, 800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        frame.setResizable(false);

Menu.java

        JButton btnProjectile = new JButton("Projectile");
        btnProjectile.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                new PMotion().setVisible(true);
                frame.dispose();


            }
        });
        btnProjectile.setBounds(260, 137, 117, 29);
        frame.getContentPane().add(btnProjectile);
    }
}
Programmer
  • 1,266
  • 5
  • 23
  • 44
  • Remove the frame member from PMotion. In PMotion.initialize(), add the components to PMotion itself. That, or you override setVisible() in PMotion to make frame visisble. – KC Wong Oct 28 '16 at 03:04

2 Answers2

3

Why does your class extend JFrame and then in the constructor create a new JFrame?

You either:

  1. extend JFrame (which is not a good idea), or
  2. create a new JFrame(...)

but you don't do both.

//frame = new JFrame("Projectile Motion");
frame = this;

In your case you could just use the code from above, since PMotion is a JFrame already.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Oh wow, just changing that one line of code makes it work now. Thanks very much! – Programmer Oct 28 '16 at 03:08
  • But now I cannot create the name for the window, or is there another way to do this? My old code contained //frame = new JFrame("Projectile Motion"); which gave it the name "Projectile Motion" but now it's just frame = this; – Programmer Oct 28 '16 at 03:13
  • Read the JFrame API there is a method that allows you to set the title of the JFrame the same as you use setResizable(...), setContentPane(...) etc. – camickr Oct 28 '16 at 03:20
2

I only copied the relevant code from PMotion.java - in reality, it is a fully working application.

Not enough to fully answer without guessing though, and in the future, you'll want to create and post a valid minimal example program (please read the link -- it's important if you're going to be asking future questions on this site), but on glancing at the little bit of code you did post, your PMotion class creates two JFrames when created, one, the PMotion class, which you're displaying, as well as a separate JFrame that is held within the PMotion class, one that you're not displaying, and I'm guessing that you're putting some (most???) of your GUI components into this separate JFrame .

Solution 1: simplify! have PMotion extend JFrame and have it hold the GUI components, and get rid of the secondary unnecessary JFrame it holds.

Better solution: You are painting yourself in a corner by having classes that extend JFrame, forcing you to create and display JFrames, when often more flexibility is called for. In fact, I would venture that most of the Swing GUI code that I've created and that I've seen does not extend JFrame, and in fact it is rare that you'll ever want to do this. More commonly your GUI classes will be geared towards creating JPanels, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via CardLayouts, wherever needed. This will greatly increase the flexibility of your GUI coding. Instead create JPanels and swap views using a CardLayout. For more on why this is important, please see The Use of Multiple JFrames, Good/Bad Practice?

Separate issue: frame.getContentPane().setLayout(null);. Please don't do this. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373