2017-02-24 5 views
0

J'ai une application simple avec une barre de menu. Dans la barre de menu se trouve un bouton (JMenu) pour ouvrir un fichier. Cliquez sur ce bouton pour ouvrir un JOptionPane avec un champ de saisie et les boutons "OK" et "Annuler".Java: Windows 7 look-and-feel (ou MouseListener?) Nécessite de cliquer deux fois sur JOptionPane

Cependant, vous devez cliquer au moins une fois sur le JOptionPane pour interagir (avec la souris) avec n'importe quel composant (les boutons ou le champ de saisie). Ce qui signifie que si vous entrez le chemin, vous devez cliquer deux fois sur le bouton "OK".

Je pense que c'est un problème de mise au point, mais l'entrée au clavier fonctionne correctement. Ce qui est étrange, c'est que l'apparence de l'interface utilisateur par défaut ne cause pas ce bug, mais mon JOptionPane a bien fonctionné avant (et j'avais l'apparence de l'interface utilisateur du système, ainsi que le MouseListener), donc Honnêtement, je ne sais pas du tout ce qui cause ce bug.

code

est ici:

import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import javax.swing.JFrame; 
import javax.swing.JMenu; 
import javax.swing.JMenuBar; 
import javax.swing.JOptionPane; 
import javax.swing.UIManager; 

public class Classe1 { 

public static void main(String[] args) throws Exception { 

    JFrame jf = new JFrame(); 

    //Commenting this line makes it behave correctly 
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 

    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    jf.setSize(new Dimension(400, 200)); 
    jf.setVisible(true); 
    jf.setLocationRelativeTo(null); 

    JMenuBar mb = new JMenuBar(); 
    JMenu test = new JMenu("Open file"); 
    test.addMouseListener(new MouseListener() { 
     @Override 
     public void mousePressed(MouseEvent arg0) { 

      JOptionPane jop = new JOptionPane(); 
      jop.requestFocus(); 

      //There is a warning, but if you do "JOptionPane.showInputDialog(...)" it doesn't do anything. 
      Object input = jop.showInputDialog(jf, "Enter path", "Title", JOptionPane.PLAIN_MESSAGE, null, null, ""); 

     } 
     @Override 
     public void mouseEntered(MouseEvent arg0) { 
     } 
     @Override 
     public void mouseExited(MouseEvent arg0) { 
     } 
     @Override 
     public void mouseClicked(MouseEvent arg0) { 
     } 
     @Override 
     public void mouseReleased(MouseEvent arg0) { 
     } 
    }); 
    mb.add(test); 
    jf.add(mb); 

} 
} 

Répondre

4

Le JMenu a le focus jusqu'à ce que la souris est relâché, mais la boîte de dialogue s'ouvre sur la souris enfoncé.

Utilisez le code ActionListener (recommandé) ou exécutez la logique de la souris.


Dans tous les cas, une action sur une souris enfoncée a généralement une mauvaise utilisation. Les utilisateurs s'attendent à ce que rien ne se produise s'ils éloignent la souris du bouton alors que le bouton de la souris est enfoncé (sorte de "pressé par erreur"). This post va plus en détail de l'UX des événements de la souris.

+0

Je ne peux pas utiliser ActionListener, JMenu ne tient pas compte tout droit et un MenuListener ne se comporte pas comme je le veux (avec plusieurs éléments, planant sur un élément après avoir cliqué sur un élément le sélectionne). Mettre le JOptionPane dans le main(), et mettre 'jop.requestFocus()' dans 'mouseReleased()' ne fait rien. – Zezombye

+1

* "ne se comporte pas comme je le veux" * Il semble que cette interface graphique ne se comporte pas comme l'utilisateur le souhaite. Une bonne règle générale pour les interfaces graphiques est de suivre le «chemin de la moindre surprise». –

+0

@Zezombye Vous ne devriez pas faire quoi que ce soit basé sur l'interaction de l'utilisateur avec un JMenu en premier lieu. Ajoutez un JMenuItem à votre JMenu et ajoutez votre ActionListener à ce JMenuItem. Ou, mieux encore, [définir une action] (http://docs.oracle.com/javase/8/docs/api/javax/swing/AbstractButton.html#setAction-javax.swing.Action-) sur le JMenuItem. – VGR

0

essayer ce que je suppose que ça marche Pour Double Cliquez

public void mouseClicked(MouseEvent arg0) 
{ 
    if(arg0.getClickCount() == 2) 
    { 
     // your code to execute 
    } 
} 

De même, vous pouvez essayer seul clic

public void mouseClicked(MouseEvent arg0) 
    { 
     if(arg0.getClickCount() == 1) 
     { 
      // your code to execute 
     } 
    }