Java模态对话框不会阻止代码执行

CC *_*Inc 2 java swing jdialog

基本上..我使用swing制作了一个JDialog.现在我希望它将一个值返回给调用它的JFrame.问题是,每当我调用JDialog的构造函数时,即使我已经设置它也不会阻塞线程setModal(true).我错过了一些明显的东西吗?

private final JPanel contentPanel = new JPanel();
private File chosenFile = null;
private JList list;
private File[] files;

public File getInformation()
{
    return chosenFile;      
}

/**
 * Create the dialog.
 */
public PatientPicker(JFrame parent)
{
    super(parent);
    setModal(true);
    setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    setLocationRelativeTo(parent);

    setBounds(100, 100, 450, 396);
    getContentPane().setLayout(new BorderLayout());
    contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
    getContentPane().add(contentPanel, BorderLayout.CENTER);

    files = new File(ClientInfo.GetAppData() + "/patients").listFiles(new TextFileFilter());

    {
        JPanel buttonPane = new JPanel();
        buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
        getContentPane().add(buttonPane, BorderLayout.SOUTH);
        {
            JButton okButton = new JButton("OK");
            okButton.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent arg0) {
                    if(files.length != 0)
                        chosenFile = files[list.getSelectedIndex()];
                    dispose();
                }
            });
            okButton.setActionCommand("OK");
            buttonPane.add(okButton);
            getRootPane().setDefaultButton(okButton);
        }
        {
            JButton cancelButton = new JButton("Cancel");
            cancelButton.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent arg0) {
                    dispose();
                }
            });
            cancelButton.setActionCommand("Cancel");
            buttonPane.add(cancelButton);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来是我创建它的方式:

PatientPicker patientPicker = new PatientPicker(frmReportGenerator);
File dataFile = patientPicker.getInformation();
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 5

你说:

问题是,每当我调用JDialog的构造函数时,即使我设置了setModal(true),它也不会阻塞线程.我错过了一些明显的东西吗?

构造函数永远不会阻塞事件线程.模态意味着只有在模态对话框中调用setVisible(true)时才会阻止事件线程(根据api).


不相关的问题:你不应该在JButtons上使用MouseListeners,而应该使用ActionListeners.否则你现在会遇到重大问题,例如当你通过空格键按下文件时,当它按下时,没有任何反应,并且在以后的代码中,例如当你禁用按钮时,它仍然是功能,即使看起来已禁用.


现在,如果您仍然遇到问题,那么您可能希望发布更多代码,这是一个最小的代码示例程序,可以让我们理解并体验您的问题.


编辑
你说:

是.用户在JDialog中选择一个文件,我希望它返回到调用它的JFrame.

为什么不直接使用JFileChooser模式对话框?


编辑2
使用JOptionPane的示例:

import java.awt.event.*;

import javax.swing.*;

@SuppressWarnings("serial")
public class SwingFoo extends JPanel {
   private JTextField fileField = new JTextField(20);
   private JButton showDialog = new JButton(new ShowDialogAction("Show Dialog",
         KeyEvent.VK_D, this));

   public SwingFoo() {
      fileField.setEditable(false);
      fileField.setFocusable(false);
      add(new JLabel("File Selected:"));
      add(fileField);
      add(showDialog);
   }

   public void setFileFieldText(String text) {
      fileField.setText(text);
   }

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

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

@SuppressWarnings("serial")
class ShowDialogAction extends AbstractAction {
   private SwingFoo swingFoo;

   public ShowDialogAction(String name, int mnemonic, SwingFoo swingFoo) {
      super(name);
      putValue(MNEMONIC_KEY, mnemonic);
      this.swingFoo = swingFoo;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      PatientPicker patientPicker = new PatientPicker();
      int result = JOptionPane.showConfirmDialog(swingFoo, patientPicker,
            "Select Something", JOptionPane.OK_CANCEL_OPTION);
      if (result == JOptionPane.OK_OPTION) {
         swingFoo.setFileFieldText(patientPicker.getSelectedItem());
      }
      patientPicker.setVisible(true);
   }
}

@SuppressWarnings("serial")
class PatientPicker extends JPanel {
   private static final String[] ITEMS = {"Sunday", "Monday", "Tuesday", "Wednesday",
         "Thursday", "Friday", "Sunday", "Fubar", "Snafu", "DILLIGAF", "BOHICA"};
   private JList<String> selectionList = new JList<>(ITEMS);

   public PatientPicker() {
      add(new JScrollPane(selectionList));
      selectionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
   }

   public String getSelectedItem() {
      return selectionList.getSelectedValue();
   }

}
Run Code Online (Sandbox Code Playgroud)