How to close a JFrame and open it consequently, without exit the JVM/Application?

一世执手 提交于 2019-12-10 12:34:36

问题


How to close a JFrame and open it consequently, without exit the JVM/entire application? I want that only the JFrame be exited and opened immediately, without close the JFrame1 nor principally exit the JVM/entire application. I want do it with a JButton.

I want a JButton this way: JButton("I close this JFrame and open this immediately, so that the constructor is executed again, without exit the JVM/application");

What I want but I don't know how to do is: I need a method that closes the JFrame window the same way when you click on the "x" of a window. Would be as follows: JFrame.close(); //like the "x" of a window JFrame.setVisible(true)

Thanks.

The print of JFrame functionality is here:

I DID A SELF ANSWER


回答1:


Don't show a "sub" JFrame, since an application usually only displays one JFrame. The job you're talking about, that of a window that is dependent on a parent window is what a modal or non-modal JDialog is for, a window that if closed will never cause the application to exit. Although having said this consider other alternatives too such as using CardLayout to swap JComponents or a JTabbedPane.

And please understand that a JDialog can display a GUI just as complex and rich as that displayed on any JFrame.

Edit, regarding:

I have a JTable at JFrame, and yes, i want instatiate the JFrame again to show a different state of GUI, closing and opening the JFrame, because the code is on its constructor.

Code can be moved out of constructors. For change in state in a GUI, I strongly suggest that you use a CardLayout. Put your JTable in a JPanel, and then swap JPanels held by your JFrame's contentPane. User interfaces are much smoother if you don't have windows popping in and out of view.

Edit 2
OK, if you want to show a window that edits a row of a JTable, what I would do would be to create a JPanel that holds the data from the row in JTextFields, then display the JPanel in a JOptionPane.showConfirmDialog(...), and then use the data held by the JTextFields to edit your JTable row. I would not create a separate JFrame for this.

Edit 3 For example:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

@SuppressWarnings("serial")
public class Foo1 extends JPanel {
   private static final String[] COLUMN_NAMES = { "Foo", "Bar", "Licious" };
   private static final Object[][] DATA = { { 1, "Abaddon", "A" },
         { 2, "Beelzebub", "B" }, { 3, "Chuck", "C" }, { 4, "Dagon", "D" },
         { 5, "Eisheth", "E" }, {6, "Forneus", "F"}};
   private DefaultTableModel tableModel = new DefaultTableModel(DATA,
         COLUMN_NAMES);
   private JTable table = new JTable(tableModel);

   public Foo1() {
      JPanel bottomPanel = new JPanel();
      bottomPanel.add(new JButton(new EditRowAction()));

      setLayout(new BorderLayout());
      add(new JScrollPane(table));
      add(bottomPanel, BorderLayout.PAGE_END);
   }

   private class EditRowAction extends AbstractAction {
      public EditRowAction() {
         super("Edit Row");
         putValue(MNEMONIC_KEY, KeyEvent.VK_E);
      }

      @Override
      public void actionPerformed(ActionEvent arg0) {
         int rowIndex = table.getSelectedRow();
         if (rowIndex != -1) {
            Object[] row = new Object[table.getColumnCount()];
            for (int column = 0; column < row.length; column++) {
               row[column] = tableModel.getValueAt(rowIndex, column);
            }
            MyRowPanel myRowPanel = new MyRowPanel(row);
            int result = JOptionPane.showConfirmDialog(Foo1.this, myRowPanel,
                  "Edit Row Information and Press \"OK\"", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if (result == JOptionPane.OK_OPTION) {
               for (int col = 0; col < row.length; col++) {
                  tableModel.setValueAt(myRowPanel.getFieldText(col), rowIndex,
                        col);
               }
            }
         }
      }
   }

   private class MyRowPanel extends JPanel {
      private JTextField[] textFields;

      public MyRowPanel(Object[] row) {
         textFields = new JTextField[row.length];
         for (int i = 0; i < row.length; i++) {
            textFields[i] = new JTextField(String.valueOf(row[i]), 10);
            add(textFields[i]);
         }
      }

      public String getFieldText(int index) {
         // check first that index is not out of range and throw exception if it
         // is
         if (index < 0 || index > textFields.length) {
            throw new ArrayIndexOutOfBoundsException("for index = " + index);
         }

         return textFields[index].getText();
      }

   }

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

      JFrame frame = new JFrame("Foo1");
      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();
         }
      });
   }
}

Edit 4 regarding:

Yes, I understand your point and it really works, this is, i will identify the row that was edited and replace with the newer values. But in reality, I want to refresh to persist the real data on the database, not to do a makeup "to edit" JTable.

OK, so then in my code example above, I'd create a PreparedStatement immediately after showing the JOptionPane and inside of my if block, and with it call executeUpdate on the PreparedStatement (but of course in a background thread).




回答2:


I googled and i find the solution, and is this:

       WindowEvent closingEvent = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
       Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closingEvent);
       frame.setVisible(true);

It uses a WindowEvent to do the same as "x" click does.

Thank you guys anyway for your help!!!




回答3:


If you just want to close and reopen a nested frame without exit the JVM/entire application you should change "defaultCloseOperation" attribute of your nested frame.

see my simple example and pay attention to usage of setDefaultCloseOperation :

    JFrame mainFrame = new JFrame("Main Frame");
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    final JFrame nestedframe = new JFrame("Nested Frame");
    nestedframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    JButton btn = new JButton("Close & Reopen Nested Frame");
    btn.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            nestedframe.dispose();
            nestedframe.setVisible(true);
        }
    });

    mainFrame.getContentPane().add(btn);
    mainFrame.setSize(350, 200);
    nestedframe.setSize(250,150);

    mainFrame.setLocation(0,0);
    nestedframe.setLocation(400,0);

    mainFrame.setVisible(true);
    nestedframe.setVisible(true);


来源:https://stackoverflow.com/questions/11354473/how-to-close-a-jframe-and-open-it-consequently-without-exit-the-jvm-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!