Java 使ActionHandler忽略箭头键

Java 使ActionHandler忽略箭头键,java,swing,user-interface,Java,Swing,User Interface,如何使操作处理程序忽略箭头键?当前,当我尝试使用箭头键导航组合框时,组合框会向下/向上移动一次,更改选择,然后触发操作处理程序将焦点移动到按钮。 我希望能够用箭头键导航组合框,并在准备好进入下一个组件时按Enter键 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class test { JFrame window = new JFrame("testGUI"); JPanel windowP

如何使操作处理程序忽略箭头键?当前,当我尝试使用箭头键导航组合框时,组合框会向下/向上移动一次,更改选择,然后触发操作处理程序将焦点移动到按钮。 我希望能够用箭头键导航组合框,并在准备好进入下一个组件时按Enter键

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

public class test {

JFrame window = new JFrame("testGUI");
JPanel windowPanel = new JPanel();

public static JLabel labelSize;
public static JComboBox<String> comboSize;

public static JLabel labelButton;
public static JButton buttonButton;

public test () {
    super();

    labelSize = new JLabel("Monster Size:");
    String[] sizeChoices = { "None", "Tiny", "Small", "Medium", "Large", "Huge", "Colossal"};
    comboSize = new JComboBox<String>(sizeChoices);
    comboSize.setToolTipText("The creature's size.");
    comboSize.addKeyListener(new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ENTER){
                comboSize.showPopup();
            }
        }
        @Override
        public void keyReleased(KeyEvent e) {
            comboSize.showPopup();
        }
        @Override
        public void keyPressed(KeyEvent e) {
        }
    });

    labelButton = new JLabel("Button:");
    buttonButton = new JButton();
    buttonButton.addKeyListener(new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ENTER)
                buttonButton.doClick();
        }
        @Override
        public void keyReleased(KeyEvent e) {
        }
        @Override
        public void keyPressed(KeyEvent e) {
            buttonButton.doClick();
        }
    });


    windowPanel.setLayout(new FlowLayout());
    windowPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    windowPanel.add(labelSize);
    windowPanel.add(comboSize);
    windowPanel.add(labelButton);
    windowPanel.add(buttonButton);
    windowPanel.setVisible(true);

    window.setSize(500, 500);
    window.setLayout(new FlowLayout());
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);
    window.add(windowPanel);

    comboSize.addActionListener(handler);
    buttonButton.addActionListener(handler);
}

ActionHandler handler = new ActionHandler();
public class ActionHandler implements ActionListener {
    public void actionPerformed(ActionEvent eventFocus){
        if (eventFocus.getSource() == comboSize){
            buttonButton.requestFocusInWindow();
        }
        if (eventFocus.getSource() == buttonButton){
            comboSize.requestFocusInWindow();
        }
    }
}

@SuppressWarnings("unused")
public static void main(String[] args) {
    test GUITest = new test();
}
}
组合框向下/向上移动一次,更改选择,然后触发操作处理程序将焦点移动到按钮。我希望能够用箭头键导航组合框,并在准备好进入下一个组件时按Enter键

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

public class test {

JFrame window = new JFrame("testGUI");
JPanel windowPanel = new JPanel();

public static JLabel labelSize;
public static JComboBox<String> comboSize;

public static JLabel labelButton;
public static JButton buttonButton;

public test () {
    super();

    labelSize = new JLabel("Monster Size:");
    String[] sizeChoices = { "None", "Tiny", "Small", "Medium", "Large", "Huge", "Colossal"};
    comboSize = new JComboBox<String>(sizeChoices);
    comboSize.setToolTipText("The creature's size.");
    comboSize.addKeyListener(new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ENTER){
                comboSize.showPopup();
            }
        }
        @Override
        public void keyReleased(KeyEvent e) {
            comboSize.showPopup();
        }
        @Override
        public void keyPressed(KeyEvent e) {
        }
    });

    labelButton = new JLabel("Button:");
    buttonButton = new JButton();
    buttonButton.addKeyListener(new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ENTER)
                buttonButton.doClick();
        }
        @Override
        public void keyReleased(KeyEvent e) {
        }
        @Override
        public void keyPressed(KeyEvent e) {
            buttonButton.doClick();
        }
    });


    windowPanel.setLayout(new FlowLayout());
    windowPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    windowPanel.add(labelSize);
    windowPanel.add(comboSize);
    windowPanel.add(labelButton);
    windowPanel.add(buttonButton);
    windowPanel.setVisible(true);

    window.setSize(500, 500);
    window.setLayout(new FlowLayout());
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);
    window.add(windowPanel);

    comboSize.addActionListener(handler);
    buttonButton.addActionListener(handler);
}

ActionHandler handler = new ActionHandler();
public class ActionHandler implements ActionListener {
    public void actionPerformed(ActionEvent eventFocus){
        if (eventFocus.getSource() == comboSize){
            buttonButton.requestFocusInWindow();
        }
        if (eventFocus.getSource() == buttonButton){
            comboSize.requestFocusInWindow();
        }
    }
}

@SuppressWarnings("unused")
public static void main(String[] args) {
    test GUITest = new test();
}
}
通过使用以下命令,可以在组合框上设置一个属性,使其仅在按下Enter键时生成ActionEvent:

comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
完整示例:

/*
    This works on non editable combo boxes
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
import javax.swing.text.*;

public class ComboBoxAction extends JFrame implements ActionListener
{
    public ComboBoxAction()
    {
        JComboBox<String> comboBox = new JComboBox<String>();
        comboBox.addActionListener( this );

        comboBox.addItem( "Item 1" );
        comboBox.addItem( "Item 2" );
        comboBox.addItem( "Item 3" );
        comboBox.addItem( "Item 4" );

        //  This prevents action events from being fired when the
        //  up/down arrow keys are used on the dropdown menu

        comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);

        getContentPane().add( comboBox );
        getContentPane().add( new JTextField(), BorderLayout.SOUTH );
    }

    public void actionPerformed(ActionEvent e)
    {
        System.out.println( e.getModifiers() );

        JComboBox comboBox = (JComboBox)e.getSource();
        System.out.println( comboBox.getSelectedItem() );

        //  make sure popup is closed when 'isTableCellEditor' is used

//      comboBox.hidePopup();
    }

    public static void main(String[] args)
    {
        ComboBoxAction frame = new ComboBoxAction();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible( true );
     }
}

有关更多信息,请参阅。

您可以在KeyListener中实现焦点。将ActionListener添加到JComboBox,与JButton相同,JButtondoClick是关于在不使用鼠标或键盘的情况下通过编程触发事件。除此之外,还可以使用KeyListener吗?当我在代码中使用组合框尝试此操作时,按箭头键不会触发动作事件,但随后箭头键会立即撤消。例如,它将向下突出显示Tiny,然后立即返回None。按住箭头键可以进一步向下移动列表,但它仍然会回到最初开始的位置。噢,哇,我真不敢相信我没想到会这样做。我不需要使用KeyListener,甚至不需要为组合框按任何键。我可以让动作处理程序在焦点转移到组合框时自动显示弹出窗口。