One JFrame opening another

28,341

Solution 1

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;
    }
}

Solution 2

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.

Solution 3

new YourJFrameNameHere().setVisible(true);

Replace YourJFrameNameHere with the JFrame name.

Simple, no?

Share:
28,341
Admin
Author by

Admin

Updated on February 11, 2020

Comments

  • Admin
    Admin about 4 years

    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?

  • 01es
    01es about 13 years
    Don't forget to call frame.setVisible(true); Also, potentially one may want to keep references to open frames. This could be useful if reopening of the same frame is desired. However, this requires a proper handling of cached JFrame references (i.e. disposing them when required etc.).
  • 01es
    01es about 13 years
    -1 This does not sound right at all... any references to back the statement "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"?
  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels about 13 years
    It seems true for most applications that I use. For instance when you use Microsoft Word, how many main windows do you typically see? If the user needs to change a property of some sort and clicks on a menu to change a property and a window pops up, what type of window is typically seen > 90% of the time? Again in my experience it is a dialog. Also, if the user closes a dialog, is there ever any risk of shutting down the entire application? Can you say the same for a JFrame?
  • Costis Aivalis
    Costis Aivalis about 13 years
    +1 Hovercraft's suggestion is the "healthy" way of viewing a JFrame. It makes sense to have only one top level container.
  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels about 13 years
    Also, using dialogs gives the coder the option of modal vs. non-modal. A second frame wouldn't allow for modal interaction.
  • 01es
    01es about 13 years
    @Hovercraft Full Of Eels There could be a notion of the main application frame, which handles creation/disposal of other frames, and when user decides to close the main frame it should react accordingly (i.e. check if all the spawned frames can be safely closed, reject closing of the application if data loss could occur etc.). Enterprise desktop applications have multiple non-dialog windows, web applications have multiple windows (any link can be open in a separate browser tab or window) etc.
  • 01es
    01es about 13 years
    @Hovercraft Full Of Eels Modality should be used only when it makes sense -- not as a way to have "other windows".
  • Admin
    Admin about 13 years
    Yes. I called the main method in a non-static way. I knew it was wrong, but the way I encapsulated my application meant I went through an intermediate class to build a JFrame. Takinga minute to sit back and think about it, the intermediate class is pointless.
  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels about 13 years
    @01es: the points you make are valid. Thanks for making them.