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

将密钥绑定到JButton[重复]

唐焕
2023-03-14

我一直在寻找将键绑定附加到JButton的答案,但仍然没有成功。我有以下由两个类组成的简单程序。我尝试了几种方法使用getInputMap()和getActionMap(),但都没有成功。我希望它执行以下操作:当我按键盘上的键“1”时,它会按JButton btn1,当我按键“2”时,它会按JButton btn2(因此JLabel上会出现1或2)。

//类1://

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

public class event06 extends JFrame {

    event06b base = new event06b(this);

    JButton btn1 = new JButton("1");
    JButton btn2 = new JButton("2");
    JLabel label = new JLabel("");

    public event06() {
        super();
        setBounds(300,300, 200,150);
        setResizable(true);
        setTitle("Button with keybinding");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        btn1.addActionListener(base);
        btn2.addActionListener(base);

        FlowLayout flo = new FlowLayout(FlowLayout.CENTER);
        setLayout(flo);
        add(btn1);
        add(btn2);
        add(label);

        setVisible(true);
    }

    public static void main(String[] args) {
        event06 window = new event06(); 
    }
}


//class 2://
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class event06b implements ActionListener {
    event06 gui;

    public event06b (event06 in) {
        gui = in;
    }
        public void actionPerformed(ActionEvent pressed) {
            Object source = pressed.getSource();
            if (source == gui.btn1) {gui.label.setText("1");}
            else if (source == gui.btn2) {gui.label.setText("2");}
        }
}

更新:(我还没有15岁的名声,所以我不能回答自己的问题,据我所知,我不能在评论中发布代码或长答案,所以我正在修改我的问题)。

我发现,只有在没有按钮具有焦点的情况下,使用KeyListeners才有效。请参见以下示例:

 //in class 1:// 
FlowLayout flo = new FlowLayout(FlowLayout.CENTER);
    setLayout(flo);
    add(btn1);
    btn1.setEnabled(false);
    btn2.setEnabled(false);
    add(btn2);
    add(label);

    btn1.addActionListener(base);
    btn2.addActionListener(base);
    addKeyListener(base);

在这里,两个按钮btn1和btn2被禁用,因此它们没有焦点,而窗口处于焦点状态。这就是KeyListener可以工作的原因:

public void keyPressed (KeyEvent evt) {
    int keycode = evt.getKeyCode();
    gui.label.setText(Integer.toString(keycode));
}

public void keyReleased(KeyEvent txt) {}
public void keyTyped(KeyEvent txt) {}

在本例中,class1中的JLabel显示已按下的键的键代码。(请注意,您可以在keyPressed方法下获取keycode,而不是keyTyped方法下获取keycode——后者有助于通过使用getKeyChar获取关键字符。使用getKeyCode而不是getKeyChar也更好,因为特定的键有一个keycode,但不是keychar)。

对于按钮,我使用action执行方法:

public void actionPerformed(ActionEvent pressed) {
    Object source = pressed.getSource();
    if (source == gui.btn1) {gui.label.setText("1");}
    else if (source == gui.btn2) {gui.label.setText("2");}
}

由于这里禁用了按钮,这不起作用。到目前为止,我无法将keyCode连接到这个actionPerform方法。在Veluria提供的示例中,这个actionPerform方法是AbstractAction的一部分,并且在那里使用了InputMaps和ActionMaps。这似乎是这里的正确答案,尽管当我尝试使用建议:错误:预期标识符时,我得到了这个错误

是的,我找到了解决办法!!!:(首先我向您展示代码,然后我将解释我修改了什么)。

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

public class event06 extends JFrame {

    event06b base = new event06b(this);

    JButton btn1 = new JButton("1");
    JButton btn2 = new JButton("2");
    JLabel label = new JLabel("");


    public event06() {
        super();
        setBounds(300,300,250,75);
        setResizable(false);
        setTitle("Buttons with key");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        FlowLayout flo = new FlowLayout(FlowLayout.CENTER);
        setLayout(flo);
        add(btn1);
        btn1.setEnabled(true);
        btn2.setEnabled(true);
        add(btn2);
        add(label);

        btn1.addActionListener(base.act);       
        btn1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('1'), "pressed");
        btn1.getActionMap().put("pressed", base.act);

        btn2.addActionListener(base.act);
        btn2.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('2'), "pressed");
        btn2.getActionMap().put("pressed", base.act);


        setVisible(true);
    }

    public static void main(String[] args) {
        event06 window = new event06();
    }
}

类别2:

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

public class event06b {
    event06 gui;

    public event06b (event06 in) {
        gui = in;
    }

    Action act = new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent pressed) {
            Object source = pressed.getSource();
            if (source == gui.btn1) {gui.label.setText("1");}
            else if (source == gui.btn2) {gui.label.setText("2");}
        }
    };
}

因此,我做了以下工作:-在btn1和btn2的类1中添加了一个ActionListener:

btn1.addActionListener(base.act);

>

  • 我还使用了InputMap:

    btn1。getInputMap(JComponent.WHEN_IN_FOCUSED_窗口)。put(击键。getKeyStroke('1'),“按下”);

    这里要注意两件事:你必须把“JComponent.WHEN_IN_FOCUSED_WINDOW”文本放在圆括号里,这样即使按钮没有焦点,你也可以从键中获取输入。另一件事是,当你使用getKeyStroke('1')时,你必须给出一个字符,所以用“”代替 " ". (我看到很多例子中使用了“”)。

    然后我使用了动作图,就像这样:

    btn1.getActionMap().put("pressed", base.act);
    

    请注意,在这里,以及在ActionListener中,我使用base引用了另一个类。act(base指的是class2,act指的是里面的动作)

    在类2中,我将actionPerform方法放在AbstractAction中,并使用了@Overder。我不知道,为什么必须使用@Overder,因为它也可以在没有它的情况下工作。

    对不起,如果我误解了什么,没有给出正确的解释。我只是一个业余程序员,没有受过计算机科学教育。但我希望,这个问题和提供的答案可能会给其他同舟共济的人带来帮助。

  • 共有1个答案

    郭洋
    2023-03-14

    这里有一种方法:

    Action action = new AbstractAction("1") {
        @Override
        public void actionPerformed(ActionEvent e) {
            label.setText("1");
        }
    };
    action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("1"));
    btn1.setAction(action);
    btn1.getActionMap().put("setOneAction", action);
    btn1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
        (KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "setOneAction");
    
     类似资料:
    • 问题内容: 我正在编写NIO服务器,并希望根据用户请求进行响应,即将一些数据写入通道。 读取一些数据后,我想响应。这意味着我需要添加到键,然后将键添加到“ 选定键”集中 ,然后一旦键出现在选定集中,就将一些内容写入通道。 如何将密钥显式添加到所选集中? 问题答案: 你不能 从Javadoc: 键可能无法直接添加到所选键集中。 您只能从中删除密钥。 但是您不需要任何这些。如果要写,只需写,且 仅当

    • 所以,我正在制作一个应用程序,当你点击一个按钮(jButton1)时,它会打印“Hi”(例如) 现在,我还有一个文本框。在文本框中,您需要指定一个键。 当你按下你指定的键时,它会运行jButton1。doClick() 更新:这是一个自动点击器。所以,我有一个布尔启动如果我键入k(从应用程序中),我希望它将布尔启动设置为true。如果我再次键入k,并且布尔启动为真,则将其设置为假。 太谢谢你了!

    • 我有一个在NeoVim中没有按预期发射的关键命令。下面是我neovim配置的摘录: 来自:nmap的适用条目显示绑定尚未被覆盖。 但按

    • 有没有一种方法可以直接将memcached绑定到它下面的本地存储?将用一个例子来解释。假设hbase被用作分布式的后端。memcached的一层被用作缓存层,它可以被认为是hbase的一个完全副本(在某种意义上)。假设系统中有4个节点,其中3个用于hbase并在其顶部有一个memcached层,1个节点用于计算。通常的规范是查找memcached是否有某个键。如果有,取出来并用于计算。如果没有,则

    • 我正在尝试使用带有多绑定的Dagger2创建我的ViewModel的依赖注入,但我收到了这个错误,我无法使其工作,我尝试了几个答案(如下),但没有一个对我有帮助。 这是我收到的错误: 这是我的密码 此外,以下是我的应用程序依赖项版本: 我知道这个问题有几个问题,但我试了几个,没有一个对我有效。 以下是我尝试阅读和检查的解决方案链接: https://github.com/android/archi

    • 问题内容: 我是Redis的新手,我想知道是否有一种方法可以 通过键的值来获取值,直到键存在为止。最小代码: 如你所知,如果这种犯规存在,它的。但是由于在我的项目中,将键值对与redis绑定发生在另一个应用程序中,因此我希望redis_connection 方法能够阻止直到key存在。这样的期望是否有效? 问题答案: 如果不在客户端上实现某种池化 redis GET, 就无法做您想做的事情。在这种