简体   繁体   English

关闭Java弹出框而不退出程序

[英]Closing java popup frame without exiting program

public ButtonGrid(int width, int length){ //constructor
            frame.setTitle("MPC");
            frame.setLayout(new GridLayout(width,length)); //set layout
            grid=new JButton[width-1][length]; //allocate the size of grid
            for(int y=0; y<length; y++){
                    for(int x=0; x<width-1; x++){
                            grid[x][y]=new JButton("("+x+","+y+")"); //creates new button     
                            frame.add(grid[x][y]); //adds button to grid
                            grid[x][y].addActionListener(this);
                            grid[x][y].addKeyListener(this);
                            //grid[x][y].setMnemonic(KeyEvent.VK_0);
                            grid[x][y].setPreferredSize(new Dimension(75,75));
                    }
            }

            for(int i =0; i<boxList.length; i++)
                box.addItem(boxList[i]);
            box.addActionListener(this);
            frame.add(box);
            frame.add(met_speed);
            frame.add(Play);
            Play.addActionListener(this);


            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack(); //sets appropriate size for frame
            frame.setVisible(true); //makes frame visible



    }
    public void newWindow(){
        JFrame frame1 = new JFrame();

        frame1.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        JTextField[] btn = new JTextField[12];
        JLabel[] lbl = new JLabel[12];
        JLabel name = new JLabel("Preset Name");
        JTextField name1 = new JTextField();
        name1.setPreferredSize(new Dimension(100,25));


        gbc.gridx = 0;
        gbc.gridy = 0;
        frame1.add(name, gbc);
        gbc.gridx++;
        frame1.add(name1, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        for(int i = 0; i<12; i++){
            lbl[i] = new JLabel("Button" + (i+1));
            frame1.add(lbl[i], gbc);
            gbc.gridy++;
        }

        gbc.gridx = 1;
        gbc.gridy = 1;
        for(int i = 0; i<12; i++){
            btn[i] = new JTextField();
            btn[i].setPreferredSize(new Dimension(75,25));
            frame1.add(btn[i], gbc);
            gbc.gridy++;
        }


        gbc.gridx = 0;
        gbc.gridy = 14;
        JButton save = new JButton("Save");
        frame1.add(save, gbc);

        frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame1.pack(); //sets appropriate size for frame
        frame1.setVisible(true); //makes frame visible

    }

The first function ButtonGrid is called in the main and contains the real program. 第一个函数ButtonGrid在主体中被调用,并包含实际程序。 After a button is pressed, the newWindow() is called as a popup. 按下按钮后,newWindow()被称为弹出窗口。 Up to that point, it works fine, but when I close frame1, it closes frame with it and ends the program. 到目前为止,它工作正常,但是当我关闭frame1时,它随之关闭frame并结束程序。

Am I doing this correctly or is there something I need to add? 我是正确执行此操作还是需要添加一些内容?

Best solution: don't "pop-up" a JFrame. 最佳解决方案:不要“弹出” JFrame。 Use a JDialog instead since closing it won't close your program, and this is exactly what they're made for. 请改用JDialog,因为关闭它不会关闭您的程序,而这正是它们的用途。 And yes, you can change the JFrame's defaultCloseOperation to DO_NOTHING_ON_CLOSE, but you'd still be using a main program window for something it was not meant to do. 是的,您可以将JFrame的defaultCloseOperation更改为DO_NOTHING_ON_CLOSE,但是您仍将使用主程序窗口执行其本不希望做的事情。 Better to use the correct tool for the job, the JDialog. 最好使用正确的工具JDialog。 Note also that a JDialog can take whatever complex GUI you're currently putting in your "pop-up" JFrame. 还请注意,JDialog可以采用您当前在“弹出式” JFrame中放置的任何复杂GUI。

For example: 例如:

import java.awt.Dialog.ModalityType;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TwoWindows {
   public static final int PREF_W = 600;
   public static final int PREF_H = 400;

   private static void createAndShowGui() {
      final JFrame frame = new JFrame("Main Application");
      JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));

      buttonPanel.add(new JButton(new AbstractAction("New JFrame") {
        {
           putValue(MNEMONIC_KEY, KeyEvent.VK_F);
        }

         @Override
         public void actionPerformed(ActionEvent e) {
            JFrame frame2 = new JFrame("Frame 2");
            frame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            setupAndDisplay(frame2);
         }
      }));
      buttonPanel.add(new JButton(new AbstractAction("New Modeless JDialog") {
        {
           putValue(MNEMONIC_KEY, KeyEvent.VK_D);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
           JDialog dialog = new JDialog(frame, "Modeless Dialog", ModalityType.MODELESS);
           setupAndDisplay(dialog);
        }
     }));

      buttonPanel.add(new JButton(new AbstractAction("New Modal JDialog") {
        {
           putValue(MNEMONIC_KEY, KeyEvent.VK_M);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
           JDialog dialog = new JDialog(frame, "Modal Dialog", ModalityType.APPLICATION_MODAL);
           setupAndDisplay(dialog);
        }
     }));

      JPanel mainPanel = new JPanel() {
         @Override
         public Dimension getPreferredSize() {
            if (isPreferredSizeSet()) {
               return super.getPreferredSize();
            }
            return new Dimension(PREF_W, PREF_H);
         }
      };

      mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
      mainPanel.add(buttonPanel);

      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   private static void setupAndDisplay(Window window) {
      window.add(Box.createRigidArea(new Dimension(200, 100)));
      window.pack();
      window.setLocationByPlatform(true);
      window.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Please run this to note the difference in behaviors between the two types of top level windows.: 请运行此命令以注意两种顶级窗口在行为上的差异。

  • When a second JFrame is created, a second and unncessary icon is created on the toolbar since the OS thinks that you're creating a completely new application rather than a 2nd window in a single application. 创建第二个JFrame时,由于操作系统认为您正在创建一个全新的应用程序,而不是在单个应用程序中创建第二个窗口,因此会在工具栏上创建第二个不必要的图标。 The JDialog does not do this. JDialog不这样做。
  • The second JFrame can go behind the main JFrame window while the JDialog, since it is a sub-window of the main application always remains on top of the main window. 第二个JFrame可以在JDialog主窗口后面,而JDialog是主应用程序的子窗口,因此它始终保留在主窗口的顶部。
  • If you close the main window when the dialog is visible, the entire application appropriately closes, but not so the 2nd JFrame, meaning this can leave you with a dangling window that does not have the main application to support it. 如果在对话框可见时关闭主窗口,则整个应用程序会适当关闭,但第二个JFrame不会关闭,这意味着您可能会得到一个悬空的窗口,而该窗口没有主应用程序来支持它。
  • The JDialog has the option of being displayed in a modal fashion, meaning the underlying window is locked from user interaction until the dialog is no longer visible. JDialog具有以模式方式显示的选项,这意味着底层窗口被锁定,无法与用户交互,直到该对话框不再可见为止。 This option is not available with a JFrame. 该选项不适用于JFrame。

您可以尝试以下方法:

frame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//<-- destroy only this frame

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM