问题
A typical way to use JFileChooser
includes checking whether user clicked OK, like in this code:
private void addModelButtonMouseClicked(java.awt.event.MouseEvent evt) {
JFileChooser modelChooser = new JFileChooser();
if(modelChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION ){
File selectedFile = modelChooser.getSelectedFile();
if(verifyModelFile(selectedFile)){
MetModel newModel;
newModel = parser.parse(selectedFile, editedCollection.getDirectory() );
this.editedCollection.addModel(newModel);
this.modelListUpdate();
}
}
}
I tried to mimic this behavior in my own window inheriting JFrame
. I thought that this way of handling forms is more convenient than passing collection that is to be edited to the new form. But I have realized that if I want to have a method in my JFrame
returning something like exit status of it I need to make it wait for user clicking OK or Cancel without freezing the form/dialog window.
So, how does showOpenDialog()
work? When I tried to inspect the implementation, I found only one line methods with note "Compiled code".
回答1:
I tried to mimic this behavior in my own window inheriting JFrame.
JFrame
is not a modal or 'blocking' component. Use a modal JDialog
or JOptionPane
instead.
E.G.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
/** Typical output:
[JTree, colors, violet]
User cancelled
[JTree, food, bananas]
Press any key to continue . . .
*/
class ConfirmDialog extends JDialog {
public static final int OK_OPTION = 0;
public static final int CANCEL_OPTION = 1;
private int result = -1;
JPanel content;
public ConfirmDialog(Frame parent) {
super(parent,true);
JPanel gui = new JPanel(new BorderLayout(3,3));
gui.setBorder(new EmptyBorder(5,5,5,5));
content = new JPanel(new BorderLayout());
gui.add(content, BorderLayout.CENTER);
JPanel buttons = new JPanel(new FlowLayout(4));
gui.add(buttons, BorderLayout.SOUTH);
JButton ok = new JButton("OK");
buttons.add(ok);
ok.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
result = OK_OPTION;
setVisible(false);
}
});
JButton cancel = new JButton("Cancel");
buttons.add(cancel);
cancel.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
result = CANCEL_OPTION;
setVisible(false);
}
});
setContentPane(gui);
}
public int showConfirmDialog(JComponent child, String title) {
setTitle(title);
content.removeAll();
content.add(child, BorderLayout.CENTER);
pack();
setLocationRelativeTo(getParent());
setVisible(true);
return result;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("Test ConfirmDialog");
final ConfirmDialog dialog = new ConfirmDialog(f);
final JTree tree = new JTree();
tree.setVisibleRowCount(5);
final JScrollPane treeScroll = new JScrollPane(tree);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton b = new JButton("Choose Tree Item");
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
int result = dialog.showConfirmDialog(
treeScroll, "Choose an item");
if (result==ConfirmDialog.OK_OPTION) {
System.out.println(tree.getSelectionPath());
} else {
System.out.println("User cancelled");
}
}
});
JPanel p = new JPanel(new BorderLayout());
p.add(b);
p.setBorder(new EmptyBorder(50,50,50,50));
f.setContentPane(p);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
});
}
}
回答2:
I guess you wait for the user to click some button by constantly checking what button is pressed.
"I need to make it wait for user clicking OK or Cancel without freezing the form/dialog window."
May be you should use evens to get notified, when the user clicks on something, not waiting for them to press the button - maybe there is some OnWindowExit event?
Or maybe something like this:
MyPanel panel = new MyPanel(...);
int answer = JOptionPane.showConfirmDialog(
parentComponent, panel, title, JOptionPane.YES_NO_CANCEL,
JOptionPane.PLAIN_MESSAGE );
if (answer == JOptionPane.YES_OPTION)
{
// do stuff with the panel
}
Otherwise you might see how to handle window events, especially windowClosing(WindowEvent)
here
来源:https://stackoverflow.com/questions/7009207/how-does-jfilechooser-return-the-exit-value