0

我做了一个SSCCE。请注意,它必须是 Windows Look&Feel。

import java.awt.*;
import javax.swing.*;

public class DefaultButtonBug {
private static final String LAF_WINDOWS = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";

public static void main(String[] args) {

    try {
        UIManager.setLookAndFeel(LAF_WINDOWS);
    } catch (Exception ex) {
        System.out.println("Setting the L&F failed so I cannot reproduce the bug.");
        System.exit(1);
    }

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            JPanel content = new JPanel();
            JButton defaultButton = new JButton("Default");

            content.add(defaultButton);

            JFrame frame = new JFrame();

            frame.getRootPane().setDefaultButton(defaultButton);
            frame.setContentPane(content);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);                
        }
    });
}
}
  • 启动这个
  • 按钮应该是焦点。如果没有,请单击它。
  • 单击任何其他窗口,以确保当前窗口失去焦点
  • 即使此窗口不再有焦点,该按钮仍以蓝色调显示动画!

按钮“脉冲”动画在标准 Java L&F 中是不存在的。

注意当这个按钮不再是默认按钮时(去掉代码中的相应行),窗口失去焦点后按钮会变灰,没有任何动画。

我的问题是:这被认为是一个错误吗?因为当窗口也隐藏在另一个窗口后面时,这使得 EDT 继续做事而不是空闲(我做了一些分析)。事实上,这是最困扰我的事情:隐藏窗口不会让 EDT 闲置。

4

1 回答 1

2

getRootPane() 默认按钮 - 这是一个错误吗?

  • 不像@Guillaume Polet 的评论中描述的那样

  • 但我倾向于使用 KeyBindings,因为ENTER对于所有 JButtons

  • 焦点可以通过getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT/*.WHEN_FOCUSED*/)

  • 注意 (Win OS) JButton 也将 TAB 实现为 KeyBindings 中的加速器。

从代码

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class DefaultButtonBug {

    private static final String LAF_WINDOWS = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(LAF_WINDOWS);
        } catch (Exception ex) {
            System.out.println("Setting the L&F failed so I cannot reproduce the bug.");
            System.exit(1);
        }
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JPanel content = new JPanel();
                JButton focusedButton1 = new JButton("Focused");
                focusedButton1.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("Focused pressed");
                    }
                });
                content.add(focusedButton1);
                final JButton defaultButton2 = new JButton("Default");
                defaultButton2.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
                defaultButton2.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("Default pressed");
                    }
                });
                defaultButton2.getModel().addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        ButtonModel model = (ButtonModel) e.getSource();
                        if (model.isRollover()) {
                            defaultButton2.setIcon(UIManager.getIcon("OptionPane.errorIcon"));
                        } else {
                            defaultButton2.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
                        }
                    }
                });
                content.add(defaultButton2);
                JFrame frame = new JFrame();
                frame.getRootPane().setDefaultButton(defaultButton2);
                frame.getRootPane().getInputMap(
                        JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT/*.WHEN_FOCUSED*/)
                        .put(KeyStroke.getKeyStroke("ENTER"), "clickButton");
                frame.getRootPane().getActionMap().put("clickButton", new AbstractAction() {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        defaultButton2.doClick();
                    }
                });
                frame.getRootPane().setDefaultButton(defaultButton2);
                frame.setContentPane(content);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

一天的学习项目

  • 在 Win7/8 (Java6/7) 上允许在 un_focused Java 窗口上发生鼠标事件(对于所有标准 L&F),可以从添加到 ButtonModel 的 ChangeListener 监听

  • 在 WinXP 上不起作用

专注

在此处输入图像描述

在此处输入图像描述

un_fosused 触发相同的事件

在此处输入图像描述

编辑

在 JDK7_011 编译的 Win7 中以蓝色闪烁 JButtons(集中在 Java 窗口中)

  • 在第二个周期以蓝色闪烁

在此处输入图像描述

在此处输入图像描述

于 2013-03-21T14:19:13.427 回答