2012-05-10 9 views
5

Ich habe eine JButton und drücken Sie es öffnet einen modalen Dialog. Wenn ich den Dialog schließe, sieht die Schaltfläche immer noch so aus, als wäre sie noch gedrückt, bis ich die Maus bewege. Ich denke, das passiert, weil der JDialog über einer AWT-Komponente geöffnet wird (es ist eine Komponente von Drittanbietern, die einen AWT Canvas verwendet, und ich kann das nicht ändern). Wenn ich den Dialog öffne und ihn über eine Swing-Komponente schließe, funktioniert er richtig.Java Swing-Schaltfläche nicht ordnungsgemäß neu nach dem Schließen des Dialogfelds

Ich habe versucht, einen Fensterlistener dem Dialog hinzuzufügen und den gesamten Rahmen neu zu streichen (mit repaint und paintImmediately), wenn das Dialogfeld geschlossen wird, aber das funktioniert nicht. Irgendwelche Vorschläge, wie Sie das beheben können?

Hier ist ein SSCCE-Beispiel. Drücken Sie die Taste und schließen Sie den Dialog. Beachten Sie, dass sich der Fokusrahmen immer noch um die Schaltfläche befindet, bis Sie die Maus über den grünen Bereich bewegen.

import java.awt.BorderLayout; 
import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 

import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

public class DialogExample 
{ 

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

     final JFrame jf = new JFrame("AWT/Swing Dialog Test"); 
     jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JButton button = new JButton("show dialog"); 
     final Canvas canvas = new Canvas() { 
      @Override 
      public void paint(Graphics g) 
      { 
       g.setColor(Color.RED); 
       g.fillRect(0, 0, getWidth(), getHeight()); 
      } 
     }; 
     canvas.setPreferredSize(new Dimension(200,200)); 

     button.setAction(new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       JDialog dlg = new JDialog(jf,"modal"); 
       dlg.add(new JLabel("hello")); 
       dlg.setModal(true); 
       dlg.pack(); 
       dlg.setLocationRelativeTo(canvas); 
       dlg.setVisible(true); 
      }    
     }); 
     button.setText("press me"); 
     button.setFocusable(false); 
     JPanel panel = new JPanel(); 
     panel.setBackground(Color.GREEN);   
     panel.setPreferredSize(new Dimension(200, 200)); 
     jf.setLayout(new BorderLayout()); 
     panel.add(button); 
     jf.add(panel, BorderLayout.NORTH); 
     jf.add(canvas, BorderLayout.SOUTH); 
     jf.setSize(new Dimension(400,400)); 
     jf.setVisible(true); 
    }  
} 
+1

* „Ich denke, dies geschieht, weil die JDialog auf der Oberseite einer AWT-Komponente geöffnet wird“ * Warum nicht versuchen, es in einem [SSCCE] (http://sscce.org/) zu reproduzieren? –

+1

Ich habe AWT-Komponenten schon lange nicht mehr benutzt. Ich erinnere mich nur daran, dass Sie Ärger bekommen, wenn Sie es mit Swing mischen. Aber ich würde vorschlagen, eine [SSCCE] ( –

+1

) zu bringen. @Guillaume Das stimmt, obwohl es normalerweise nur für schwebende schwebende Elemente wie das Drop-Down einer 'JComboBox' oder eines Tool-Tips gilt . Ich habe nie gewusst, dass es passiert, wenn sich AWT-Komponenten in einem Fenster und Swing in einem anderen befinden. Java 7 bietet anscheinend ein Flag, das AWT & Swing Komponenten frei mischen soll. –

Antwort

5

Als sinnvoll, können Sie den Rollover-Status löschen, wenn der Dialog kehrt in actionPerformed():

@Override 
public void actionPerformed(ActionEvent e) { 
    JDialog dlg = new JDialog(jf, "modal"); 
    dlg.add(new JLabel("hello")); 
    dlg.setModal(true); 
    dlg.pack(); 
    dlg.setLocationRelativeTo(canvas); 
    dlg.setVisible(true); 
    button.getModel().setRollover(false); 
} 
+0

Danke, ich gebe das einen Versuch und poste die Ergebnisse zurück –

+1

scheint zu tun der Trick, danke –

+0

+1. Einfache Lösung –