对话框关闭后,Java Swing 按钮无法正确重绘

标签 java swing awt modal-dialog repaint

我有一个 JButton,按下它会打开一个模式对话框。当我关闭对话框时,按钮看起来仍然处于按下状态,直到我移动鼠标。我认为发生这种情况是因为 JDialog 是在 AWT 组件之上打开的(它是使用 AWT Canvas 的第 3 方组件,我无法更改它)。如果我打开对话框并通过 swing 组件关闭它,那么它会正常工作。

我试过向对话框添加一个窗口监听器,并在对话框关闭时重新绘制整个框架(使用重绘和立即绘制),但这不起作用。有关如何解决此问题的任何建议?

这是一个 SSCCE 示例。按下按钮,然后关闭对话框。请注意,在将鼠标移到绿色部分上方之前,焦点边框仍围绕按钮。

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);
    }    
}

最佳答案

作为权宜之计,您可以在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);
}

关于对话框关闭后,Java Swing 按钮无法正确重绘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10543273/

相关文章:

Java读取文件夹和子文件夹中的文件

java - 使用线程以不同间隔输出消息

java - 如何将 SwingWorker 与 Swing 同步?

java - 使用方法和多个类的一副纸牌

java - 使用 Spring Web MVC 自定义处理 405 错误

java - GridLayout 删除 JPanel 之间的填充

java - JTextPane,文本/html 内容 : nested HTML element do not inherit font size?

java - 按下按钮时渲染矩形时遇到问题

java - 我想简化我的 Java 程序中的事情

java - 如何在 Java 中的 for 循环中的每个 update() 之后强制执行 repaint()?