2011-10-16 58 views
5

正如您从上述主题中看到的那样,
我想知道如何解除由于另一个JOptionPane而变得不相关的JOptionPane,并且因为用户,出于某种原因,并没有通过他自己点击确定按钮来解除第一个按钮(例如)。如何在GUI中出现另一个JOptionPane时关闭一个JOptionPane

我已经看到了在其他网站类似的问题的一些洁具,人们建议简单地做:

JOptionPane.getRootFrame().dispose(); 

但我怎么能存储每个JOptionPane的我,并能够只辞退参考想要一个。
感谢

编辑:
代码示例:

package Gui; 

import javax.swing.JOptionPane; 
import java.awt.*; 

/** 
* 
* @author 
*/ 
public class JpanelMainView extends javax.swing.JPanel { 

    /** Creates new form JpanelMainView */ 
    public JpanelMainView() { 
     initComponents(); 
    } 

    /** This method is called from within the constructor to 
    * initialize the form. 
    * WARNING: Do NOT modify this code. The content of this method is 
    * always regenerated by the Form Editor. 
    */ 
    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code">       
    private void initComponents() { 

     jButton1 = new javax.swing.JButton(); 

     jButton1.setText("jButton1"); 
     jButton1.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       jButton1ActionPerformed(evt); 
      } 
     }); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 
     this.setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addGap(149, 149, 149) 
       .addComponent(jButton1) 
       .addContainerGap(178, Short.MAX_VALUE)) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addGap(77, 77, 77) 
       .addComponent(jButton1) 
       .addContainerGap(200, Short.MAX_VALUE)) 
     ); 
    }// </editor-fold>       

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)           
    {            
     JOptionPane.showMessageDialog(this, "Board was sent for validation check\n Please wait...","Board Sent",JOptionPane.INFORMATION_MESSAGE); 

     //Please note that this OptionPane is coming in my real program always after the first JoptionPane 
     //I want that if I've reached the line in the code that need to show this second JoptionPane, I will first close the first JoptionPane 
     //Else you will dismiss the last JoptionPane and then the first one and I don't want to give the user two JoptionPane to close, it's annoying. 
     JOptionPane.showMessageDialog(this, "Set your move now please","Game started",JOptionPane.INFORMATION_MESSAGE); 
    }           

    // Variables declaration - do not modify      
    private javax.swing.JButton jButton1; 
    // End of variables declaration     

} 
+1

一个JOptionPane的通常模态(当然有例外),所以我不知道用户如何甚至能够打开第二JOptionPane的时候,第一个是可见的?您是否可以创建并发布一个小型可编译和可运行的程序来演示您的问题,并且可以测试,修改和更正[sscce](http://sscce.org)? –

+0

好吧我已经生成了真正简单的工作示例,我应该在哪里上传它? – JavaSa

+1

@JavaSa:编辑您的文章并加入。 –

回答

7

我会建议ŧ帽子你

  • 创建一个JDialog你的JOptionPane(该JOptionPane API会告诉你怎么做),
  • 然后使用的SwingWorker不管什么后台任务要做到这一点应该关闭主Swing线程来完成, EDT,
  • 然后在后台任务完成时调用的SwingWorker的done()方法中,处理JDialog。
  • 然后将立即调用下一个JOptionPane。

例如,以下代码使用Thread.sleep(3000)进行3秒睡眠以模仿需要3秒的后台任务。然后,它会关闭第一个对话框并显示第二:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
     JOptionPane messagePane = new JOptionPane(
      "Board was sent for validation check\n Please wait...", 
      JOptionPane.INFORMATION_MESSAGE); 
     final JDialog dialog = messagePane.createDialog(this, "Board Sent"); 

     new SwingWorker<Void, Void>() { 

     @Override 
     protected Void doInBackground() throws Exception { 
      // do your background processing here 
      // for instance validate your board here 

      // mimics a background process that takes 3 seconds 
      // you would of course delete this in your actual progam 
      Thread.sleep(3000); 

      return null; 
     } 

     // this is called when background thread above has completed. 
     protected void done() { 
      dialog.dispose(); 
     }; 
     }.execute(); 

     dialog.setVisible(true); 

     JOptionPane.showMessageDialog(this, "Set your move now please", 
      "Game started", JOptionPane.INFORMATION_MESSAGE); 
    } 
+0

我想我不需要摆动工作者,因为我的后台任务被保存在我的服务器,它验证董事会后它返回一个ok确定客户端桂和游戏自动开始 – JavaSa

+0

我不太确定,你不会需要一个SwingWorker或某种后台线程。你的GUI代码如何告诉服务器验证电路板?它是以阻挡的方式进行还是以非阻塞的方式进行? GUI如何等待服务器的响应?它是如何通知的?所有这些东西都可以绑定你的Swing事件线程。但是,这是你的应用程序,所以你认为合适。 –

+0

好吧我试图让事情更清楚,当我的Gui首先连接到我的服务器时,它通过在m_InputStream上简单调用readInt函数,在等待DataInputStream中的即将到来的命令的客户端中打开新的监听线程(可运行实现)会员。桂告诉服务器验证董事会在一个特殊的董事会建设屏幕上点击一个摇摆按钮“验证板”它阻止,因为我需要表的第二个玩家建立自己的董事会的对手,然后到 – JavaSa

4

简单的答案,那不可能的,因为只有一个JOptionPane可以在当前的时间存在,如果你想解决您的问题,那么你必须创建JDialog#ModalityType(Aplications???)JWindow,那么你就能够显示JOptionPane

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class ClosingFrame extends JFrame { 

    private JMenuBar MenuBar = new JMenuBar(); 
    private JFrame frame = new JFrame(); 
    private static final long serialVersionUID = 1L; 
    private JMenu File = new JMenu("File"); 
    private JMenuItem Exit = new JMenuItem("Exit"); 
    private JFrame frame1 = new JFrame(); 

    public ClosingFrame() { 
     File.add(Exit); 
     MenuBar.add(File); 
     Exit.addActionListener(new ExitListener()); 
     WindowListener exitListener = new WindowAdapter() { 

      @Override 
      public void windowClosing(WindowEvent e) { 
       int confirm = JOptionPane.showOptionDialog(frame, 
         "Are You Sure to Close this Application?", 
         "Exit Confirmation", JOptionPane.YES_NO_OPTION, 
         JOptionPane.QUESTION_MESSAGE, null, null, null); 
       if (confirm == 0) { 
        System.exit(1); 
       } 
      } 
     }; 
     frame.addWindowListener(exitListener); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.setJMenuBar(MenuBar); 
     frame.setPreferredSize(new Dimension(400, 300)); 
     frame.setLocation(100, 100); 
     frame.pack(); 
     frame.setVisible(true); 

     frame1.addWindowListener(exitListener); 
     frame1.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame1.setPreferredSize(new Dimension(400, 300)); 
     frame1.setLocation(500, 100); 
     frame1.pack(); 
     frame1.setVisible(true); 
    } 

    private class ExitListener implements ActionListener { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      int confirm = JOptionPane.showOptionDialog(frame, 
        "Are You Sure to Close this Application?", 
        "Exit Confirmation", JOptionPane.YES_NO_OPTION, 
        JOptionPane.QUESTION_MESSAGE, null, null, null); 
      JOptionPane.showMessageDialog(null, "Whatever", "Whatever", 
        JOptionPane.ERROR_MESSAGE); 
      int confirm1 = JOptionPane.showOptionDialog(frame1, 
        "Are You Sure to Close this Application?", 
        "Exit Confirmation", JOptionPane.YES_NO_OPTION, 
        JOptionPane.QUESTION_MESSAGE, null, null, null); 
      if (confirm == 0) { 
       //System.exit(1); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ClosingFrame cf = new ClosingFrame(); 
      } 
     }); 
    } 
} 
+0

好的谢谢,但如何使用一些操作像在接受的答案后http://stackoverflow.com/questions/4542924/getting-hold-of-a-reference-to-the-object-created-by-joptionpane - 静态方法,它能解决我的问题吗? – JavaSa

+0

我猜是因为只有一个JoptionPane可以存在,帖子无法帮助 – JavaSa

+1

@JavaSa'1)'基本上可以隐藏JOptionPane,'2)'无法保证哪个代码块将被隐藏的JOptionPane执行当前或前一个, '3)'这个组件是用于代码执行的bloking(用作信号量),block user_input,'4)'最后一个属性是调用(自定义JOptionPane手动添加JButton(s))myButton.doClick();然后JOptionPane走了'5)'我认为解决什么都没有(链接,你张贴):-) – mKorbel

3

对不起,我不明白你的问题很好,你的意思是你想从另外一个关闭一个JOptionPane的?

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 

public class GUIProgram extends JFrame implements ActionListener 
{ 
    private JButton btn1, btn2, btn3; 
    private static final String BUTTON1_COMMAND = "Press it!"; 
    private static final String BUTTON2_COMMAND = "show new JOptionPane!"; 
    private static final String BUTTON3_COMMAND = "close old JOptionPane!"; 
    private JOptionPane pane1, pane2; 

    public GUIProgram() 
    { 
     super("The title"); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     btn1 = new JButton(BUTTON1_COMMAND); 
     btn1.addActionListener(this); 
     btn1.setActionCommand(BUTTON1_COMMAND); 

     btn2 = new JButton(BUTTON2_COMMAND); 
     btn2.addActionListener(this); 
     btn2.setActionCommand(BUTTON2_COMMAND); 

     btn3 = new JButton(BUTTON3_COMMAND); 
     btn3.addActionListener(this); 
     btn3.setActionCommand(BUTTON3_COMMAND); 

     pane1 = new JOptionPane(); 
     pane2 = new JOptionPane(); 

     getContentPane().add(btn1); 
     setSize(200, 100); 
     setVisible(true); 
    } 

    public static void main(String args[]) 
    { 
     new GUIProgram(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     if(e.getActionCommand().equals(BUTTON1_COMMAND)) 
     { 
      JPanel panel = new JPanel(); 
      panel.add(btn2); 
      pane1.showOptionDialog(null, panel, "JOptionPane #1", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, new Object[]{}, null); 
     } 

     else if(e.getActionCommand().equals(BUTTON2_COMMAND)) 
     { 
      JPanel panel = new JPanel(); 
      panel.add(btn3); 
      pane2.showOptionDialog(null, panel, "JOptionPane #2", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, new Object[]{}, null); 
     } 

     else if(e.getActionCommand().equals(BUTTON3_COMMAND)) 
     { 
      pane1.getRootFrame().dispose(); 
     } 
    } 
} 
+0

不,我的意思是说,如果用户不够快点击一个JoptionPane上的确定,它会保持在后台,过了一段时间将获得另一个选项Pane,然后他将需要关闭两个JoptionPanes,因此如果第二个JoptionPane已经进入(并且用户没有关闭第一个JoptionPane),我希望能够取消先前的JoptionPane。 – JavaSa