一个 JFrame 打开另一个

2022-01-24 00:00:00 main java swing jframe awt

我有一个 JFrame 和 JPanel,里面装满了 Jsomethings 和一个 actionlistener.当用户单击一个对象时,我想打开另一个 JFrame.这是我所做的:

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 调用一个新的 JFrame.)因此屏幕上会打开另一个 JFrame,其中包含更多选项.它工作正常(到目前为止),但我想知道这是标准吗?我的意思是这样调用主要方法?另一个问题是,不使用卡片布局(我不想使用),是通过做这种事情来处理多个面板的最佳方式吗?

(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?

推荐答案

我会改变一些事情.首先,通常一个应用程序有一个 JFrame,然后如果它需要显示另一个窗口,则可以使用模态或非模态对话框,例如可以通过 JDialog 或 JOptionPane 获得.话虽如此,更常见的是拥有一个 JFrame 并在 JFrame 中交换视图"——通过 CardLayout 交换 contentPanes 或其他大面板,因为这将模仿我们目前使用的许多 gui 程序的行为.

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.

就个人而言,我还尝试将我的 GUI 创建转向创建 JPanel 或 JComponent,而不是创建顶级窗口.这样,如果我想将 GUI 显示为独立应用程序、对话框或小程序,我可以将其分别弹出到 JFrame 或 JDialog 或 JApplet 的 contentPane 中,或者作为更复杂 GUI 的内部面板,然后将其插入那里,或者在具有交换视图的应用程序中,然后作为 CardLayout 中的卡片,如上所述.最重要的是,我认为这种结构为开发人员提供了更多使用此 GUI 的选择.

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.

另外,我会避免调用另一个类的 main 方法(假设这是公共静态 void main 方法),因为您会失去 OOP 的所有好处.您似乎还试图以非静态方式调用静态方法(假设我正确理解您的程序结构).

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).

关于你的第二个问题,它引出了我自己的一个问题:你为什么不想使用 CardLayout?

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

相关文章