keyPressed не работает, если JButton не нажал первым - PullRequest
0 голосов
/ 11 декабря 2018

Я создал небольшое приложение, которое использует JButtons для увеличения чисел.Кнопки не должны быть активируемыми, а активироваться с помощью клавиатуры (т. Е. Числа в textField увеличиваются при нажатии на клавиатуру, а не при нажатии кнопки мыши).Моя проблема в том, что при первом запуске приложения клавиатура ничего не делает, пока я не нажму одну из кнопок - хотя нажатие на кнопку ничего не меняет.Я попытался заставить одну из кнопок requestFocusInWindow() подумать, что если бы она уже была сфокусирована, клавиши сработали бы, но, похоже, это не сработало, помещаю ли я ее в свой основной метод или класс контроллера.Я пытался выяснить, нужно ли мне делать KeyboardFocusManager или addFocusListener() (но я не хочу, чтобы что-то происходило всегда, если кнопка получает / теряет фокус).Я пробовал так много вещей, которые у меня кружатся, пытаясь добавить либо мой основной метод с помощью frame, либо мой класс контроллера.Ниже приведен мой текущий код:

Класс с основным

import javax.swing.JFrame;

public class Count {

    public static void main(String[] args) {
        CountController frame = new CountController();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(560, 150); 
        frame.setVisible(true); 
        //I've tried to add the button and requestFocusInWindow here
        //as well as tried a frame.addWindowFocusListener
    }
} // end class

Класс контроллера

imports ...
public class CountController extends JFrame implements KeyListener {
    private JLabel ...
    private JTextField ...
    private JButton ....
    int ...
    // no-argument constructor
    public CountController() {
        super("Title");
        setLayout(null); // position GUI components explicitly

        //set up JLabels in following manner
        label = new JLabel("some label");
        label.setBounds(47, 5, 45, 25);
        label.setHorizontalAlignment(JLabel.CENTER);
        add(label);

        //set up JTextFields in following manner
        textField = new JTextField("0");
        textField.setBounds(47, 30, 45, 25);
        textField.setHorizontalAlignment(JTextField.CENTER);
        textField.setBackground(Color.WHITE);
        textField.setEditable(false);
        add(textField);

        //set up JButtons in the following manner
        button = new JButton("some text");
        button.setBounds(15, 70, 110, 25);
        button.setBackground(Color.WHITE);
        add(button);
        button.addKeyListener(this);
        //I've tried adding requestFocusInWindow() here as well
    } // end constructor

    //begin KeyListener stuff
    @Override
    public void keyPressed(KeyEvent event){
        int keyCode = event.getKeyCode();
        switch(keyCode){
            case #: //# is ASCII #
                do some things;
                call a method();
                break;
        }
    }
    @Override
    public void keyReleased(KeyEvent event){
        button.setBackground(Color.WHITE);
    }
    @Override
    public void keyTyped(KeyEvent event){
        // nothing but this is needed for implementing KeyListener
    }

    //List of methods that are called from switch
        ...

    //I've tried to add a public void initialize(){}

}//end CountController class

Iбыл бы признателен за любой вклад, чтобы заставить это работать, чтобы мне не нужно было сначала нажимать кнопку, прежде чем мои ключи сработают.Спасибо!

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Для того, чтобы слушатель мог инициировать событие, компонент, на который он зарегистрирован, должен быть вначале сфокусирован и иметь фокус.Вместо этого используйте API связывания клавиш .

В следующем коде JComponent.WHEN_IN_FOCUSED_WINDOW используется для определения контекста, в котором будут генерироваться события клавиш.В этой конфигурации не имеет значения, что находится в фокусе, события все равно будут генерироваться, пока окно в данный момент сфокусировано

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;

public class Count {

  public static void main(String[] args) {
    CountController frame = new CountController();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(560, 150);
    frame.setVisible(true);
    //I've tried to add the button and requestFocusInWindow here
    //as well as tried a frame.addWindowFocusListener
  }

  public static class CountController extends JFrame {

    // no-argument constructor
    public CountController() {
      super("Title");
      setLayout(new GridBagLayout());
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridwidth = GridBagConstraints.REMAINDER;

      //set up JLabels in following manner
      JLabel label = new JLabel("some label");
      label.setHorizontalAlignment(JLabel.CENTER);
      add(label, gbc);

      //set up JTextFields in following manner
      JTextField textField = new JTextField("0", 20);
      textField.setHorizontalAlignment(JTextField.CENTER);
      textField.setBackground(Color.WHITE);
      textField.setEditable(false);
      add(textField, gbc);

      //set up JButtons in the following manner
      JButton button = new JButton("some text");
      add(button, gbc);

      InputMap im = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
      ActionMap am = button.getActionMap();

      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_3, KeyEvent.SHIFT_DOWN_MASK), "Pressed.#");
      am.put("Pressed.#", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
          textField.setText(textField.getText() + "#");
        }
      });

    } // end constructor

  }//end CountController class
} // end class

Хотя я бы зарегистрировал привязки к родительскому контейнеру, а некнопки, но это только я.

И причины не использовать null макеты ... это то, как ваш оригинальный код выглядит на моем ПК

Reasons for not using null layouts

0 голосов
/ 11 декабря 2018

Хотя мне не совсем ясно, что должен делать ваш код, ваша проблема в том, что вы addKeyListener(this) на button, но ваша кнопка не имеет фокуса, и клавиша ничего не делает при нажатии.Попробуйте добавить KeyListener() к другому компоненту графического интерфейса, например, к textfield, поскольку он является первым компонентом и ориентирован на запуск (из предоставленного вами кода), и посмотрите, работает ли он.

...