【问题标题】:JOptionPane.showMessageDialog wait until OK is clicked?JOptionPane.showMessageDialog 等到单击确定?
【发布时间】:2012-06-13 11:26:05
【问题描述】:

这可能是我忽略的一件非常简单的事情,但我似乎无法弄清楚。

我有以下更新 JTable 的方法:

class TableModel extends AbstractTableModel {    
        public void updateTable() {
            try {
                // update table here
             ...
    } catch (NullPointerException npe) {
                isOpenDialog = true;
                JOptionPane.showMessageDialog(null, "No active shares found on this IP!");
                isOpenDialog = false;
            }
        }
    }

但是,在按下消息对话框上的 OK 按钮之前,我不希望将 isOpenDialog boolean 设置为 false,因为如果用户按下 Enter,它将在文本字段上激活 KeyListener 事件并触发如果将其设置为false,则再次使用整个代码块。

部分KeyListener代码如下:

public class KeyReleased implements KeyListener {
        ...

    @Override
    public void keyReleased(KeyEvent ke) {
        if(txtIPField.getText().matches(IPADDRESS_PATTERN)) {
            validIP = true;
        } else {
            validIP = false;
        }

        if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
            if (validIP && !isOpenDialog) {
                updateTable();
            }
        }
    }
}

JOptionPane.showMessageDialog() 是否有某种机制可以防止在按下 OK 按钮之前执行下一行?谢谢。

【问题讨论】:

    标签: java swing jtable keylistener joptionpane


    【解决方案1】:
    You can get acces to the OK button if you create optionpanel and custom dialog. Here's an example of this kind of implementation:
    
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    
    /**
     *
     * @author OZBORN
     */
    public class TestyDialog {
        static JFrame okno;
        static JPanel panel;
        /**
         * @param args the command line arguments
         */
    
        public static void main(String[] args) {
            zrobOkno();
            JButton przycisk =new JButton("Dialog");
            przycisk.setSize(200,200);
            panel.add(przycisk,BorderLayout.CENTER);
            panel.setCursor(null);
            BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
            przycisk.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(
                                cursorImg, new Point(0, 0), "blank cursor"));
            final JOptionPane optionPane = new JOptionPane(
                    "U can close this dialog\n"
                    + "by pressing ok button, close frame button or by clicking outside of the dialog box.\n"
                    +"Every time there will be action defined in the windowLostFocus function"
                    + "Do you understand?",
                    JOptionPane.INFORMATION_MESSAGE,
                    JOptionPane.DEFAULT_OPTION);
    
            System.out.println(optionPane.getComponentCount());
            przycisk.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e) {
                    final JFrame aa=new JFrame();
                    final JDialog dialog = new JDialog(aa,"Click a button",false);
                    ((JButton)((JPanel)optionPane.getComponents()[1]).getComponent(0)).addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            aa.dispose();
                        }
                    });
                    dialog.setContentPane(optionPane);
                    dialog.pack();
    
                    dialog.addWindowFocusListener(new WindowFocusListener() {
                        @Override
                        public void windowLostFocus(WindowEvent e) {
                            System.out.println("Zamykam");        
                            aa.dispose();
                        }
                        @Override public void windowGainedFocus(WindowEvent e) {}
                    });
    
                    dialog.setVisible(true);    
                }
            });
        }
        public static void zrobOkno(){
            okno=new JFrame("Testy okno");
            okno.setLocationRelativeTo(null);
            okno.setSize(200,200);
            okno.setPreferredSize(new Dimension(200,200));
            okno.setVisible(true);
            okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            panel=new JPanel();
            panel.setPreferredSize(new Dimension(200,200));
            panel.setLayout(new BorderLayout());
            okno.add(panel);
        }
    }
    

    【讨论】:

      【解决方案2】:

      满足您的需求的一个简单解决方法是使用showConfirmDialog(...),而不是showMessageDialog(),这使您可以从用户那里获取输入,然后继续进行。请查看此示例程序以进行澄清:-)

      import javax.swing.*;
      
      public class JOptionExample
      {
          public static void main(String... args)
          {
              SwingUtilities.invokeLater(new Runnable()
              {
                  public void run()
                  {
                      int selection = JOptionPane.showConfirmDialog(
                                      null
                              , "No active shares found on this IP!"
                              , "Selection : "
                              , JOptionPane.OK_CANCEL_OPTION
                              , JOptionPane.INFORMATION_MESSAGE);
                      System.out.println("I be written" +
                           " after you close, the JOptionPane");      
                      if (selection == JOptionPane.OK_OPTION)
                      {
                          // Code to use when OK is PRESSED.
                          System.out.println("Selected Option is OK : " + selection);
                      }
                      else if (selection == JOptionPane.CANCEL_OPTION)
                      {
                          // Code to use when CANCEL is PRESSED.
                          System.out.println("Selected Option Is CANCEL : " + selection);
                      }
                  }           
              });
          }
      }
      

      【讨论】:

        【解决方案3】:

        JOptionPane 创建一个模态对话框,因此在处理对话框之前(按下按钮之一或按下关闭菜单按钮),设计上不会调用超出它的行。

        更重要的是,您不应该将 KeyListener 用于此类事情。如果你想让 JTextField 监听 Enter 键的按下,添加一个 ActionListener 到它。

        【讨论】:

          【解决方案4】:

          试试这个,

          catch(NullPointerException ex){
               Thread t = new Thread(new Runnable(){
          
                                      public void run(){
          
                                            isOpenDialog = true;
          
                                            JOptionPane.setMessageDialog(Title,Content);
                                          }
                                        });
          
               t.start();
          
               t.join(); // Join will make the thread wait for t to finish its run method, before
                            executing the below lines
          
               isOpenDialog = false;
          
             }
          

          【讨论】:

          • Swing 操作(例如打开对话框)应该发生在 EventDispatchThread 中
          • 同意噪音:这种代码不属于 Swing 应用程序,因为它完全忽略了 Swing 线程规则。
          • 即使我同意 Swing 操作必须发生在 Event Dispatcher Thread 中,因为 Swing 应用程序中的 main() 方法会在 Event Dispatcher Thread 中安排 GUI 的构建并退出。但是书中描述的规则是针对理想世界的,有时需要成为叛逆者才能完成工作。
          • 你的意识形态有缺陷,@KumarVivekMitra。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-03-15
          • 1970-01-01
          • 2011-10-21
          • 2019-06-29
          • 1970-01-01
          • 1970-01-01
          • 2011-01-23
          相关资源
          最近更新 更多