I have a JButton and pressing it opens a modal dialog. When I close the dialog, the button still look like it is still in a pressed state until I move the mouse. I think this is happening because the JDialog is opened on top of an AWT component (it's a 3rd party component that uses an AWT Canvas, and I can't change that). If I open the dialog and close it over a swing component, then it works properly.
I've tried adding a window listener to the dialog and repainting the entire frame (using repaint and paintImmediately) when the dialog closes, but this doesn't work. Any suggestions on how to fix this?
Here is an SSCCE example. Press the button and then close the dialog. Notice the focus border is still around the button until moving the mouse over the green section.
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);
}
}
As an expedient, you can clear the rollover state when the dialog returns 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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With