问题
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