我以前见过这种类型的东西,如果我没记错的话,它是为残疾用户提供功能(如果没有,那是我以前见过的地方)。
首先...永远不要从Thread
除事件调度线程之外的任何其他组件创建/修改任何 UI 组件。事实上,对于这个问题,我怀疑你是否真的需要任何线程。
查看Swing 中的并发以获取信息。
你也不应该需要任何类型的KeyListener
。在最坏的情况下,您可能需要提供Key Binding,但在大多数外观和感觉下,Space支持作为“默认”接受操作,例如Enter.
您真正想要做的只是将焦点移到突出显示的按钮上。
public class TestHelpButton {
public static void main(String[] args) {
new TestHelpButton();
}
public TestHelpButton() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton[] buttons = new JButton[]{
new JButton(new BasicAction("Don't Panic")),
new JButton(new BasicAction("Panic")),
new JButton(new BasicAction("Cup of Tea")),
new JButton(new BasicAction("Destory the world")),};
private int activeIndex = -1;
public TestPane() {
setLayout(new GridBagLayout());
for (JButton btn : buttons) {
add(btn);
}
updateSelection();
Timer timer = new Timer(3000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateSelection();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
protected void updateSelection() {
if (activeIndex >= 0) {
JButton btn = buttons[activeIndex];
btn.setBackground(UIManager.getColor("Button.background"));
}
activeIndex++;
if (activeIndex > buttons.length - 1) {
activeIndex = 0;
}
JButton btn = buttons[activeIndex];
btn.setBackground(Color.RED);
btn.requestFocusInWindow();
}
}
public class BasicAction extends AbstractAction {
public BasicAction(String text) {
putValue(NAME, text);
}
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, getValue(NAME), "Helper", JOptionPane.INFORMATION_MESSAGE);
}
}
}
我提供一个工作示例的唯一原因是基于我的假设,即这是为残疾用户提供额外支持。