2011-10-16 9 views
5

Come hai visto dall'argomento sopra,
Mi piacerebbe sapere come posso eliminare un JOptionPane che è diventato irrilevante a causa di un altro JOptionPane e perché l'utente , per qualche ragione, non ha eliminato il primo da solo facendo clic sul pulsante OK (ad esempio).Come posso cancellare un JOptionPane all'emergenza di un altro JOptionPane nella GUI

Ho visto alcuni articoli in altro sito simile domanda, e la gente ha suggerito di fare semplicemente:

JOptionPane.getRootFrame().dispose(); 

ma come posso memorizzare un riferimento per ogni JOptionPane che ho e di essere in grado di licenziare solo voluto uno.
Grazie

Modificato:
Esempio di codice:

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

Un JOptionPane di solito è modale (ci sono eccezioni, naturalmente), quindi mi chiedo come l'utente è stato anche in grado di portare una seconda JOptionPane quando il primo è visibile? Puoi creare e pubblicare un piccolo programma compilabile e eseguibile che mostri il tuo problema e che possiamo testare, modificare e possibilmente correggere, [sscce] (http://sscce.org)? –

+0

ok ho generato un esempio di lavoro molto semplice dove dovrei caricarlo? – JavaSa

+1

@ JavaSa: modifica il tuo post e includilo. –

risposta

7

Suggerirei t cappello che

  • creare un JDialog con il JOptionPane (la JOptionPane API vi mostrerà come)
  • quindi utilizzare uno SwingWorker per qualsiasi attività in background che si desidera fare questo dovrebbe essere fatto fuori del filo swing principale, il EDT,
  • Quindi, nel metodo done() di SwingWorker chiamato quando l'attività in background è completa, eliminare JDialog.
  • Quindi il prossimo JOptionPane verrà chiamato immediatamente.

Ad esempio il seguente codice utilizza un Thread.sleep (3000) per un riposo di 3 secondi per simulare un'attività in background che impiega 3 secondi. Sarà quindi chiudere la prima finestra di dialogo e mostrare il secondo:

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

Immagino di non aver bisogno dello swing worker perché il mio task in background è tenuto nel mio Server, dopo che ha convalidato la Board che ritorna ok Ack al client Gui e il gioco inizia automaticamente – JavaSa

+0

Non sono sicuro che non occorrerà uno SwingWorker o una sorta di thread in background. In che modo il tuo codice GUI comunica al server di convalidare la scheda? Lo fa in un modo bloccante o è in un modo non bloccante? In che modo la GUI attende la risposta del server? Come viene notificato? Tutte queste cose possono legare il thread dell'evento Swing. Ma ... è la tua applicazione, quindi fallo come meglio credi. –

+0

Okay Sto cercando di rendere le cose più chiare, quando il mio Gui si connette in un primo momento al mio server apre un nuovo thread di ascolto (esecuzione eseguibile) nel client che attende il comando in arrivo nel DataInputStream con una semplice chiamata alla funzione readInt su m_InputStream membro. Il Gui dice al server di convalidare il tabellone su una speciale schermata di costruzione della board dopo aver cliccato su un pulsante di swing "validate board" sta bloccando perché ho bisogno del secondo giocatore del tavolo per costruire la sua board per l'avversario e solo a – JavaSa

4

risposta semplice, che non è possibile, perché solo una JOptionPane può esistere nel tempo corrente, se si vuole risolvere il problema, allora dovete creare JDialog#ModalityType(Aplications???) o JWindow allora ti grado di spettacoli 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

ok grazie, ma che dire dell'utilizzo di alcune manipolazioni come nella risposta accettata del post http://stackoverflow.com/questions/4542924/getting-hold-of-a-reference-to-the-object-created-by-joptionpane -statici-metodi, risolverà il mio problema? – JavaSa

+0

Immagino perché può esistere solo un JoptionPane che post non può aiutare – JavaSa

+1

@JavaSa '1)' fondamentalmente è possibile nascondere JOptionPane, '2)' nessuno per garantire che quale blocco di codice verrà eseguito corrente o precedente da parte di JOptionPane, '3)' questo componente è lì per esecuzioni di codice bloking (funziona come semaforo), blocco user_input, '4)' ultima proprietà è quella di chiamare (personalizzato JOptionPane con JButton (s) aggiunti manualmente) myButton.doClick() ;, quindi JOptionPane andato via '5)' Penso che non risolvi nulla (link che hai postato) :-) – mKorbel

3

dispiace non capisco bene la tua domanda, vuoi dire che si desidera chiudere un JOptionPane da un altro?

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

No, volevo dire che se l'utente non è abbastanza veloce da fare clic su ok su un JoptionPane, rimarrà sullo sfondo, dopo un po 'di tempo otterrà un altro optionPane e quindi dovrà chiudere due JoptionPanes, quindi voglio essere in grado di cancellare il precedente JoptionPane se quel secondo JoptionPane è già arrivato (e l'utente non ha eliminato il primo) – JavaSa

Problemi correlati