简体   繁体   English

在打开另一个JFrame之前关闭一个JFrame

[英]Close one JFrame before opening another JFrame

I want to close completely one JFrame before opening another . 我想在打开另一个之前完全关闭一个JFrame

Consider the code : 考虑一下代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import javax.swing.*;
import javax.swing.border.EmptyBorder;


/**
 * 
 * @author X
 *
 */
class ServerConnect extends JFrame implements ActionListener
{
    private static final long serialVersionUID = 1L;
    private JTextField m_serverIP;
    private JTextField m_serverPort; // you can use also JPasswordField
    private JButton m_submitButton;

    // location of the jframe
    private final int m_centerX = 500;
    private final int m_centerY = 300;

    // dimensions of the jframe
    private final int m_sizeX = 1650;
    private final int m_sizeY = 150;


    /**
     * Ctor
     */
    ServerConnect()
    {
        this.setTitle("Sever Side Listener");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        m_serverIP = new JTextField(20);
        m_serverPort = new JTextField(20);

        JPanel gui = new JPanel(new BorderLayout(3,3));
        gui.setBorder(new EmptyBorder(5,5,5,5));
        gui.setSize(m_sizeX , m_sizeY);
        this.setContentPane(gui);

        JPanel labels = new JPanel(new GridLayout(0,1));
        JPanel controls = new JPanel(new GridLayout(0,1));
        gui.add(labels, BorderLayout.WEST);
        gui.add(controls, BorderLayout.CENTER);

        labels.add(new JLabel("Server IP: "));
        controls.add(m_serverIP);
        labels.add(new JLabel("Server Port: "));
        controls.add(m_serverPort);
        m_submitButton = new JButton("Start Listening");
        m_submitButton.addActionListener(this);

        gui.add(m_submitButton, BorderLayout.SOUTH);
        this.setLocation(m_centerX , m_centerY);
        this.setSize(m_sizeX , m_sizeY);
        this.pack();
        this.setVisible(true);
    }

    public static void main(String[] args) {
        new ServerConnect();
    }

    @Override
    public void actionPerformed(ActionEvent event) {

        Object object = event.getSource();
        if (object == this.m_submitButton)
        {
            // grab all values from the connection box 
            // if one of them is missing then display an alert message 

            String ip = this.m_serverIP.getText().trim();
            String port = this.m_serverPort.getText().trim();

            if (ip.length() == 0)
            {
                JOptionPane.showMessageDialog(null, "Please enter IP address !");
                return;
            }

            if (port.length() == 0)
            {
                JOptionPane.showMessageDialog(null, "Please enter Port number!");
                return;
            }

            int s_port = 0;

            try
            {
                // try parse the Port number 
                // throws exception when an incorrect IP address 
                // is entered , and caught in the catch block 
                s_port = Integer.parseInt(port);
            }

            catch(Exception exp)
            {
                JOptionPane.showMessageDialog(null, "Port number is incorrect!");
                return;
            }

            try
            {
                // try parse the IP address 
                // throws exception when an incorrect IP address 
                // is entered , and caught in the catch block 
                InetAddress.getByName(ip);
            }

            catch(Exception exp)
            {
                JOptionPane.showMessageDialog(null, "IP address is incorrect!");
                return;
            }
            this.setVisible(false);
            new ServerGUI(ip , s_port);
        }
    }
}

In actionPerformed() after the user had entered the IP number and port , I set the window to false , ie : 在用户输入IP号和端口后的actionPerformed() ,我将窗口设置为false,即:

        this.setVisible(false);      // don't show the current window
        new ServerGUI(ip , s_port);  // open another JFrame

I want to close the current JFrame completely, not to set its visibility to false. 我想完全关闭当前的JFrame ,而不是将其可见性设置为false。

How can I do that ? 我怎样才能做到这一点 ?

Regards 问候

Your problem appears that if you call close on the JFrame, the program will exit since you've set its setDefaultCloseOperation to setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 您的问题似乎是,如果您在JFrame上调用close,程序将退出,因为您已将其setDefaultCloseOperation设置为setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); .

Options: 选项:

  • Use a different defaultCloseOperation, one that doesn't close the application, perhaps JFrame.DISPOSE_ON_CLOSE . 使用不同的defaultCloseOperation,一个不关闭应用程序的,可能是JFrame.DISPOSE_ON_CLOSE
  • Use a JDialog initially instead of a JFrame. 最初使用JDialog而不是JFrame。 These types of windows can't shut down the application. 这些类型的窗口无法关闭应用程序。 Here is the JDialog and JOptionPane Tutorial 这是JDialog和JOptionPane教程
  • Don't swap JFrames at all, but rather swap views by using a CardLayout. 根本不要交换JFrame,而是使用CardLayout交换视图 The CardLayout Tutorial link CardLayout教程链接

My own preference is to use a CardLayout as much as possible to avoid annoying the user who usually doesn't appreciate having a bunch of windows flung at him. 我自己的偏好是尽可能多地使用CardLayout以避免让那些通常不喜欢把一堆窗户扔在他身上的用户烦恼。 I also use modal JDialogs when I want to get information from the user in a modal fashion, ie, where the application absolutely cannot move forward until the user gives the requested information, and non-modal dialogs to present program state monitoring information for the user. 当我想以模态方式从用户那里获取信息时,我也使用模态JDialogs,即,在用户提供所请求的信息之前应用程序绝对不能向前移动,而非模态对话框为用户呈现程序状态监视信息。 I almost never use multiple JFrames in a single application. 我几乎从不在单个应用程序中使用多个JFrame。


Edit 编辑
As an aside, I almost never create classes that extend JFrame or any top-level window since I find that much too restricting. 顺便说一句,我几乎从不创建扩展JFrame或任何顶级窗口的类,因为我发现它太受限制了。 Instead most of my GUI type classes are geared towards creating JPanels. 相反,我的大多数GUI类型都面向创建JPanels。 The advantage to this is then I can decide when and where I want to put the JPanel, and can change my mind at any time. 这样做的好处是我可以决定何时何地放置JPanel,并且可以随时改变主意。 It could go into a JFrame, a JDialog, a JOptionPane, be a card that is swapped in a CardLayout,... anywhere. 它可以进入JFrame,JDialog,JOptionPane,是一个在CardLayout中交换的卡,......在任何地方。


Edit 2 编辑2

For example, here's a small program that uses your code, slightly modified, and puts it into a JDialog: 例如,这是一个使用您的代码的小程序,略有修改,并将其放入JDialog:

My code: 我的代码:

import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class MyServerMain extends JPanel {
   private JTextField serverIp = new JTextField(8);
   private JTextField serverPort = new JTextField(8);
   private ServerConnect serverConnect = new ServerConnect();
   private JDialog serverConnectDialog = null;

   public MyServerMain() {
      serverIp.setFocusable(false);
      serverPort.setFocusable(false);

      add(new JLabel("Server IP:"));
      add(serverIp);
      add(new JLabel("Server Port:"));
      add(serverPort);
      add(new JButton(new SetUpServerAction("Set Up Server", KeyEvent.VK_S)));
   }

   private class SetUpServerAction extends AbstractAction {
      public SetUpServerAction(String name, int keyCode) {
         super(name);
         putValue(MNEMONIC_KEY, keyCode);
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         if (serverConnectDialog == null) {
            Window owner = SwingUtilities.getWindowAncestor(MyServerMain.this);
            serverConnectDialog = new JDialog(owner, "Server Set Up",
                  ModalityType.APPLICATION_MODAL);

            serverConnectDialog.getContentPane().add(serverConnect);
            serverConnectDialog.pack();
            serverConnectDialog.setLocationRelativeTo(owner);
         }
         serverConnectDialog.setVisible(true);

         // when here, the dialog is no longer visible
         // so extract information from the serverConnect object
         serverIp.setText(serverConnect.getServerIp());
         serverPort.setText(serverConnect.getServerPort());
      }
   }

   private static void createAndShowGui() {
      MyServerMain mainPanel = new MyServerMain();

      JFrame frame = new JFrame("My Server Main");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

Your modified code: 你修改过的代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;

import javax.swing.*;
import javax.swing.border.EmptyBorder;

class ServerConnect extends JPanel implements ActionListener {
   private static final long serialVersionUID = 1L;
   private JTextField m_serverIP;
   private JTextField m_serverPort; // you can use also JPasswordField
   private JButton m_submitButton;

   // location of the jframe
   private final int m_centerX = 500;
   private final int m_centerY = 300;

   // dimensions of the jframe
   private final int m_sizeX = 1650;
   private final int m_sizeY = 150;

   ServerConnect() {
      m_serverIP = new JTextField(20);
      m_serverPort = new JTextField(20);

      JPanel gui = new JPanel(new BorderLayout(3, 3));
      gui.setBorder(new EmptyBorder(5, 5, 5, 5));
      gui.setSize(m_sizeX, m_sizeY);
      setLayout(new BorderLayout()); // !!
      add(gui, BorderLayout.CENTER);

      JPanel labels = new JPanel(new GridLayout(0, 1));
      JPanel controls = new JPanel(new GridLayout(0, 1));
      gui.add(labels, BorderLayout.WEST);
      gui.add(controls, BorderLayout.CENTER);

      labels.add(new JLabel("Server IP: "));
      controls.add(m_serverIP);
      labels.add(new JLabel("Server Port: "));
      controls.add(m_serverPort);
      m_submitButton = new JButton("Start Listening");
      m_submitButton.addActionListener(this);

      gui.add(m_submitButton, BorderLayout.SOUTH);
      this.setLocation(m_centerX, m_centerY);
      this.setSize(m_sizeX, m_sizeY);
      // !! this.pack();
      // !! this.setVisible(true);
   }

   public static void main(String[] args) {
      new ServerConnect();
   }

   @Override
   public void actionPerformed(ActionEvent event) {

      Object object = event.getSource();
      if (object == this.m_submitButton) {
         // grab all values from the connection box
         // if one of them is missing then display an alert message

         String ip = this.m_serverIP.getText().trim();
         String port = this.m_serverPort.getText().trim();

         if (ip.length() == 0) {
            JOptionPane.showMessageDialog(null, "Please enter IP address !");
            return;
         }

         if (port.length() == 0) {
            JOptionPane.showMessageDialog(null, "Please enter Port number!");
            return;
         }

         int s_port = 0;

         try {
            // try parse the Port number
            // throws exception when an incorrect IP address
            // is entered , and caught in the catch block
            s_port = Integer.parseInt(port);
         }

         catch (Exception exp) {
            JOptionPane.showMessageDialog(null, "Port number is incorrect!");
            return;
         }

         try {
            // try parse the IP address
            // throws exception when an incorrect IP address
            // is entered , and caught in the catch block
            InetAddress.getByName(ip);
         }

         catch (Exception exp) {
            JOptionPane.showMessageDialog(null, "IP address is incorrect!");
            return;
         }

         // !! this.setVisible(false);
         // !! new ServerGUI(ip , s_port);
         // !!
         Window ownerWindow = SwingUtilities.getWindowAncestor(this);
         ownerWindow.dispose();
      }
   }

   // !!
   public String getServerIp() {
      return m_serverIP.getText();
   }

   // !!
   public String getServerPort() {
      return m_serverPort.getText();
   }
}

Hope this another_Frame frm = new another_Frame(); frm.setVisible(true); this.dispose();// this represent the fram to close 希望这个another_Frame frm = new another_Frame(); frm.setVisible(true); this.dispose();// this represent the fram to close another_Frame frm = new another_Frame(); frm.setVisible(true); this.dispose();// this represent the fram to close

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

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