gpt4 book ai didi

java - 专注于 JButtons 是如何在 Java 中实际工作的?

转载 作者:行者123 更新时间:2023-12-01 13:45:20 25 4
gpt4 key购买 nike

我在 Java Swing 中发现了一个奇怪的异常。
第一个按时间顺序添加到 UI 的 JButton 总是在用户按下空格键时触发,假设他在这样做之前没有单击另一个按钮。如果 getRootPane().setDefaultButton(JButton)JButton.requestFocus()被称为。
当请求关注 JButton 时,似乎至少有两种不同的“焦点”。
“焦点”或突出显示之一是按钮上文本周围的虚线矩形,而另一个是指定按钮周围的较粗轮廓。
每当按下空格键时,带有虚线轮廓文本的按钮就会触发。
每当按下回车键时,带有粗边框的按钮就会触发。
我准备了一个可编译的最小示例来说明这种行为。根本不涉及键映射/绑定(bind)。

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
}
}
}
这是它的样子:
Button Focus Example
可执行代码也可以找到 here .
我现在的问题是:
  • 这些不同的焦点是什么?
  • 有人如何更改在按钮文本周围显示为虚线轮廓的焦点,以便空格键 回车键会触发“否”按钮的事件吗?
  • 最佳答案

    关于问题1:
    没有两种“焦点”。两种方法都按照各自的名称执行:JButton.requestFocus() (更好的是 JButton.requestFocusInWindow() )请求关注按钮,而 getRootPane().setDefaultButton(JButton)设置一个选定的按钮,LAF 单独处理该按钮。

    关于问题2:
    对话框的方式是问题所在。
    因此,可能的解决方案是

  • 创建对话框时将modal设置为false,例如与 new DialogMinimal(this, false);并通过调用 bNo.requestFocusInWindow() 获得焦点而不是 getRootPane().setDefaultButton(bNo);和/或 bNo.requestFocus(); ,但如果对话框必须是模态的,这不是解决方案。
  • 实现RequestFocusListener发现于 Dialog Focus正如用户 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
    [...]
    }

    关于java - 专注于 JButtons 是如何在 Java 中实际工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62821608/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com