Один JFrame открывает другой - PullRequest
3 голосов
/ 06 февраля 2011

У меня есть JFrame и JPanel, заполненные Jsomethings с actionlistener.Когда пользователь щелкает объект, я хочу открыть другой JFrame.Вот что я сделал:

public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();

    if (source == rejectionbutton){
        RejectApp ra = new RejectApp();
        ra.main(null);

    }

}

(RejectApp вызывает новый JFrame.) Таким образом, на экране открывается еще один JFrame с большим количеством опций.Это работает хорошо (пока), но я хочу знать, это стандарт?Я имею в виду вызов основного метода, как это?Другой вопрос, без использования карты (что я не хочу использовать), это лучший способ работать с несколькими панелями, делая такие вещи?

Ответы [ 3 ]

7 голосов
/ 06 февраля 2011

Я бы изменил несколько вещей. Во-первых, обычно у приложения есть один JFrame, а затем, если ему нужно показать другое окно, это делается как модальное или немодальное диалоговое окно, такое как может быть получено с помощью JDialog или JOptionPane. Сказав это, еще более распространено иметь один JFrame и поменять «представления» в JFrame - поменять ContentPanes или другие большие панели через CardLayout, поскольку это имитирует поведение многих программ графического интерфейса, которые мы все в настоящее время используем.

Лично я также пытаюсь направить свое создание GUI к созданию JPanel или JComponent, а не к созданию окна верхнего уровня. Таким образом, если я хочу отобразить GUI как отдельное приложение, диалог или апплет, я могу вставить его в contentPane JFrame или JDialog или JApplet соответственно, или если в качестве внутренней панели более сложного GUI, то вставьте его туда или в приложение с представлением замены, а затем как карту в CardLayout, как указано выше. Суть в том, что я считаю, что эта структура дает разработчику гораздо больше возможностей для использования этого графического интерфейса.

Кроме того, я бы не стал вызывать main другого класса, как вы это делаете (предполагая, что это публичный метод static void main), поскольку вы теряете все преимущества ООП. Вы также, кажется, пытаетесь вызывать статический метод нестатическим способом (при условии, что я правильно понимаю структуру вашей программы).

На ваш второй вопрос напрашивается мой вопрос: почему вы не хотите использовать CardLayout?

edit: пример того, что я имел в виду, выглядит следующим образом:

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;
    }
}
2 голосов
/ 06 февраля 2011

Я бы предпочел создать новый экземпляр JFrame или подкласс или вызвать новый метод, создающий новый JFrame:

public void actionPerformed(ActionEvent e) {
Object source = e.getSource();

if (source == rejectionbutton){
    JFrame frame = new JFrame("New Frame");
   //or
   makeNewFrame();
}

}

Еще один простой менеджер макетов - этоBorderLayout, это менеджер по умолчанию Layout-Manager класса JFrame.

1 голос
/ 11 февраля 2013
new YourJFrameNameHere().setVisible(true);

Замените YourJFrameNameHere на имя JFrame.

Просто, нет?

...