gpt4 book ai didi

java - 自 Java 1.7 以来的助记符行为(在 1.8.0.121 中仍然存在)

转载 作者:行者123 更新时间:2023-12-02 08:02:17 27 4
gpt4 key购买 nike

我们有一个在 Java 1.6 上运行的旧软件。当我们最终获准将其升级到 Java 1.8 时,出现了以下问题。

我们有一组带有加速键的单选按钮。如果任何类型的 JTextComponent 具有焦点,并且您按下单选按钮加速器之一(例如 ALT-s),并且在释放 ALT 之前释放“s”,则 UIManager 将激活菜单栏。 (这只发生在 Windows 外观和感觉中)

看起来像一个错误,我一直在考虑通过在这些情况下“消耗”ALT 版本来编写解决方法,但也许有人有更好的主意?使用不同的外观和感觉不是一种选择,也不能在 UI 管理器中关闭标准 Alt 行为。

这是一个简短的代码示例。请注意,不存在任何类型的加速器/助记符冲突。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.UIManager;

public class MnemonicTest extends JFrame {

public MnemonicTest() {
super("MnemonicTest");
init();
}

public static void main(String[] args) throws Exception {
MnemonicTest test = new MnemonicTest();
test.setVisible(true);
}

private void init() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e1) {
e1.printStackTrace();
}

setSize(new Dimension(500,400));
JButton stopButton = new JButton("Stop");
stopButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}});

this.getContentPane().setLayout(new BorderLayout());

this.getContentPane().add(stopButton, BorderLayout.SOUTH);

JMenuBar jMenuBar = new JMenuBar();
JMenu menu = new JMenu("XXX");

JMenuItem a1 = new JMenuItem("a1", 'A');
JMenuItem b1 = new JMenuItem("b1", 'B');
JMenuItem c1 = new JMenuItem("c1", 'C');

menu.add(a1);
menu.add(b1);
menu.add(c1);

jMenuBar.add(menu);
this.setJMenuBar(jMenuBar);

JPanel p = new JPanel();
ButtonGroup group = new ButtonGroup();
p.add(new JTextField("XXXXXXXXXX"), BorderLayout.CENTER);
JRadioButton but1 = new JRadioButton("test");
but1.setMnemonic('s');
JRadioButton but2 = new JRadioButton("2222");
p.add(but1);
p.add(but2);
group.add(but1);
group.add(but2);

getContentPane().add(p, BorderLayout.CENTER);
}
}

最佳答案

我确实找到了一个有效的解决方案,即使它并不是选美比赛的获胜者。如果你有更好的,请留言!!

问题似乎是 KeyEvent 被发送到单选按钮而不是 Pane 或文本字段。当系统发现 ALT 键已释放时,它会调用默认操作。

当然,当单选按钮获得焦点时,普通的 Alt 仍然应该执行它应该执行的操作:激活菜单栏。

如果您按下 Alt-S(我们的加速器),单选按钮将收到:keyPressed(Alt) -> keyPressed("S") -> keyReleased("S") -> keyReleased(Alt)。

因此,如果我们保存最后按下的键的值,我们将消耗最后一个事件 (keyReleased(Alt)),除非最后按下的键也是 Alt。

这是一种解决方法,虽然不是一个漂亮的方法,但它确实有效。代码如下(我在代码中留下了调试语句):

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.UIManager;

public class MnemonicTest extends JFrame {
int codeLast = 0;

private final class RadioButtonKeyAdapter extends KeyAdapter {
private static final int NO_CODE = 0;
private int lastCode = 0;

@Override
public void keyPressed(KeyEvent e) {
System.out.println("pressed source: " + e.getSource() + "\n" + e.getKeyCode());
this.setLastCode(e.getKeyCode());
}

@Override
public void keyReleased(KeyEvent e) {
System.out.println("released source: " + e.getSource() + "\n" + e.getKeyCode());
if (e.getKeyCode() == KeyEvent.VK_ALT && this.getLastCode() != e.getKeyCode()) {
e.consume();
}

this.setLastCode(NO_CODE);
}

private int getLastCode() {
return lastCode;
}

private void setLastCode(int lastCode) {
this.lastCode = lastCode;
}
}

private static final long serialVersionUID = 1L;

public MnemonicTest() {
super("MnemonicTest");
init();
}

public static void main(String[] args) throws Exception {
MnemonicTest test = new MnemonicTest();
test.setVisible(true);
}

private void init() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e1) {
e1.printStackTrace();
}

setSize(new Dimension(500,400));
JButton stopButton = new JButton("Stop");
stopButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}});

this.getContentPane().setLayout(new BorderLayout());

this.getContentPane().add(stopButton, BorderLayout.SOUTH);

JMenuBar jMenuBar = new JMenuBar();
JMenu menu = new JMenu("XXX");

JMenuItem a1 = new JMenuItem("a1", 'A');
JMenuItem b1 = new JMenuItem("b1", 'B');
JMenuItem c1 = new JMenuItem("c1", 'C');

menu.add(a1);
menu.add(b1);
menu.add(c1);

jMenuBar.add(menu);
this.setJMenuBar(jMenuBar);

JPanel p = new JPanel();
ButtonGroup group = new ButtonGroup();
JTextField textField = new JTextField("XXXXXXXXXX");
p.add(textField, BorderLayout.CENTER);
JRadioButton but1 = new JRadioButton("test");
but1.setMnemonic('s');
JRadioButton but2 = new JRadioButton("2222");
p.add(but1);
p.add(but2);
group.add(but1);
group.add(but2);

getContentPane().add(p, BorderLayout.CENTER);

but1.addKeyListener(new RadioButtonKeyAdapter());
but2.addKeyListener(new RadioButtonKeyAdapter());
}
}

关于java - 自 Java 1.7 以来的助记符行为(在 1.8.0.121 中仍然存在),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41891317/

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