当前位置: 首页 > 知识库问答 >
问题:

如何专注于JButton实际上工作在Java?

赵嘉悦
2023-03-14

我在Java Swing中发现了一个奇怪的异常。按时间顺序添加到UI中的第一个JButton总是在用户按下空格键时触发,前提是他没有单击其他按钮。如果getRootPane(),甚至会发生这种行为。setDefaultButton(JButton)JButton。调用requestFocus()。当要求专注于一个按钮时,似乎至少有两种不同的“专注”。其中一个“焦点”或高亮显示是围绕按钮上文本的虚线矩形,而另一个是围绕指定按钮的较厚轮廓。

每当按下空格键时,带有虚线轮廓文本的按钮就会触发。每当按下回车键时,带有粗边框的按钮就会触发。

我准备了一个可编译的最小示例来说明这种行为。根本不涉及键映射/绑定。

import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class ButtonFocusAnomalyExample extends JFrame {
    public ButtonFocusAnomalyExample() {
        super();
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        int frameWidth = 300;
        int frameHeight = 300;
        setSize(frameWidth, frameHeight);
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (d.width - getSize().width) / 2;
        int y = (d.height - getSize().height) / 2;
        setLocation(x, y);
        setTitle("Any Frame");
        setResizable(false);
        Container cp = getContentPane();
        cp.setLayout(null);
        setVisible(true);
        new DialogMinimal(this, true); // Runs the Dialog
    }

    public static void main(String[] args) {
        new ButtonFocusAnomalyExample();
    }

    static class DialogMinimal extends JDialog {
        private final JTextField output = new JTextField();

        public DialogMinimal(final JFrame owner, final boolean modal) {
            super(owner, modal);
            setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            int frameWidth = 252;
            int frameHeight = 126;
            setSize(frameWidth, frameHeight);
            Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
            int x = (d.width - getSize().width) / 2;
            int y = (d.height - getSize().height) / 2;
            setLocation(x, y);
            setTitle("Minimal Button Focus Example");
            Container cp = getContentPane();
            cp.setLayout(null);
            JButton bYes = new JButton();
            bYes.setBounds(0, 0, 100, 33);
            bYes.setText("Yes (Space)");
            bYes.addActionListener(this::bYes_ActionPerformed);
            JPanel buttonPanel = new JPanel(null, true);
            buttonPanel.add(bYes);
            JButton bNo = new JButton();
            bNo.setBounds(108, 0, 120, 33);
            bNo.setText("No (Enter/Return)");
            getRootPane().setDefaultButton(bNo); // Set "No" as default button
            bNo.requestFocus(); // Get focus on "No" button
            bNo.addActionListener(this::bNo_ActionPerformed);
            buttonPanel.add(bNo);
            buttonPanel.setBounds(8, 8, 400, 92);
            buttonPanel.setOpaque(false);
            cp.add(buttonPanel);
            output.setBounds(8, 50, 220, 32);
            cp.add(output);
            setResizable(false);
            setVisible(true);
        }

        public void bYes_ActionPerformed(final ActionEvent evt) {
            output.setText("Yes"); // Still fires on every space bar press
        }

        public void bNo_ActionPerformed(final ActionEvent evt) {
            output.setText("No"); // Only fires on every return/enter press
        }
    }
}

这就是它看起来的样子:

可执行代码也可以在这里找到。

我现在的问题是:

  1. 这些不同的焦点是什么

共有1个答案

堵景天
2023-03-14

关于问题1:

没有两种“焦点”。这两种方法都按照各自的名称执行:

JButton。requestFocus()(更好的方法JButton.requestFocusInWindow())请求集中在按钮上,而getRootPane()。setDefaultButton(JButton)设置一个选定的按钮,LAF分别处理该按钮。

关于问题2:

对话的形式就是问题所在。

因此,可能的解决办法是:

  1. 创建对话框时,将模态设置为false,例如使用new DialogMinal(this, false);,并通过调用bNo.requestFocus usInWindow()而不是getRootPane(). setDefaultButton(bNo);和/或bNo.requestFocus();来获得焦点,但如果对话框必须是模态的,这不是解决方案。
  2. 实现用户camickr建议的对话框焦点中找到的请求焦点监听器。
public DialogMinimal(final JFrame owner, final boolean modal) {
    Button bNo = new JButton();
    [...]
    // bNo.requestFocusInWindow(); // obsolete now
    getRootPane().setDefaultButton(bNo); // To fire on enter key
    bNo.addAncestorListener(new RequestFocusListener()); // To fire on space bar
    [...]
}

 类似资料:
  • 问题内容: 编译器或OS如何区分sig_atomic_t类型和普通的int类型变量,并确保操作是原子的?两者都使用的程序具有相同的汇编代码。如何特别注意使操作原子化? 问题答案: 不是原子数据类型。仅仅是允许您在信号处理程序的上下文中使用的数据类型,仅此而已。因此最好将其名称理解为“相对于信号处理而言是原子的”。 为了保证与信号处理程序之间的通信,仅需要原子数据类型的属性之一,即读取和更新将始终看

  • 问题内容: 我有一个Applet,它使用URLConnection通过HTTP连接加载图像。我正在为所有连接设置setUseCaches(true),但仍然看不到任何缓存行为。我图像的HTTP标头具有合理的缓存设置。如果您查看错误4528599,则有一个相当神秘的陈述: Java插件的当前版本(1.3.1)仅检查浏览器缓存中名称以.jar或.class结尾的文件。我被告知,对于Java Plug-

  • 问题内容: 首先,我要说我知道它是什么,做什么以及如何使用它。这个问题关系到它在引擎盖下的工作方式,我不希望出现“这就是如何用” 循环数组”的答案。 很长时间以来,我一直认为该方法可用于数组本身。然后,我发现了很多关于它可以与数组 副本 一起使用的事实的引用,从那时起,我一直以为这是故事的结尾。但是我最近对此事进行了讨论,经过一番实验后发现这实际上并非100%正确。 让我表明我的意思。对于以下测试

  • 问题内容: 每当您尝试调用对象时,都会调用Python的magic方法。因此等于。 函数是Python中的一类对象,这意味着它们只是可调用的对象(使用)。但是,它本身是一个函数,因此它也具有,又具有自己的功能,又具有自己的功能。 因此,因此等于并再次等于等,依此类推。 这个无限循环如何结束?实际如何执行代码? 问题答案: 在幕后,Python中的所有调用都使用相同的机制,并且几乎所有调用都在CPy

  • 问题内容: 实际如何运作?是否可以对未指定的元素起作用?它是否偏向于具有指定元素的元素(即使它们位于顶部)? 这样的数字是否必须为负数? 或不?所有正数(以递增值表示)会以最后一个在顶部,中间在中间,第一个在底部为结尾吗? 问题答案: 允许使用负整数和正整数。 必须在元素上设置位置。 不过,在深入了解这些细节之前,让我从头开始进行解释。 每个网页都由所谓的堆栈上下文组成。从字面上看,您可以将它们视

  • 问题内容: 例如,当我有这样的字符串时: 当我像这样使用SQL时: 服务器到达JDK时会发生什么?它会停止并执行SQL,还是遍历字符串的其余部分然后执行SQL? 当我在与OR连接的SQL语句中有多个LIKE子句时,还会发生什么情况?它可能时会在第一个LIKE子句处停止吗? 编辑:我有这样的SQL。这可能是矫kill过正,但值得一提…每个变量都包含一个表列的LIKE子句循环。它们之间有“或”。我是否