【问题标题】:KeyListener doesn't work after dispose()在 dispose() 之后 KeyListener 不起作用
【发布时间】:2013-11-07 20:12:27
【问题描述】:

在我的程序中,我有在普通窗口和全屏状态之间切换的方法:

public void setFullScreen(boolean enableFullScreen) {
    Frame.fullScreen = enableFullScreen;
    dispose();
    if ( enableFullScreen ) {
        getContentPane().setPreferredSize(resFull);
        setSize(resFull);
        setBounds(Frame.graphicsDev.getConfigurations()[0].getBounds().x, Frame.graphicsDev.getConfigurations()[0].getBounds().y, resFull.width, resFull.height);
        //code for resizing components
        setUndecorated(true);
        setResizable(false);
    } else {
        getContentPane().setSize(resNormal);
        getContentPane().setPreferredSize(resNormal);
        //code for resizing components
        setUndecorated(false);
        setResizable(true);
    }
    pack();
    setVisible(true);
}

resFullresNormal 是维度变量。

当我在打开的普通窗口中单击 F11 时,它会更改全屏状态 (setFullScreen(!Frame.fullScreen)),但更改后它通常不会收到任何信号 - 我必须切换到其他应用程序然后返回此窗口 -然后就可以了。

【问题讨论】:

  • 您要处理什么以及为什么要处理它? Dispose 用于删除您调用的任何内容。
  • @Radiodef:实际上 dispose 不是为了“删除”,而是为了释放原生资源。您绝对不想在显示顶级窗口之前对其进行处置,但调用 pack()setVisible(true) 应该会重新构成原生资源。
  • 我不得不这样做,因为我想打电话给setUndecorated()
  • 我忘了补充,这个方法在Frame类中。
  • MarPiRK:我没有听说过创建未装饰窗口的要求,但我通常也不创建这些。无论如何,您可能会遇到焦点问题,因为 KeyListener 要求它们侦听焦点组件。我自己,我尽量避免使用 KeyListeners 并尝试支持使用 Key Bindings。

标签: java awt fullscreen keylistener


【解决方案1】:

您的问题可能是由于 JButton 在按下时窃取了焦点,导致您的 KeyListener 正在侦听未获得焦点的组件。还有一个解决方案是使用键绑定。

我的sscce 证明 KeyListeners 和 Key Bindings 在您尝试实现的转换后可以正常工作:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.*;

import javax.swing.*;

@SuppressWarnings("serial")
public class TestUndecoratedKeyListener {
   protected static final int PREF_W = 400;
   protected static final int PREF_H = PREF_W;

   private static void createAndShowGui() {
      final JFrame frame = new JFrame("TestUndecoratedKeyListener");

      final JPanel mainPanel = new JPanel() {
         @Override
         public Dimension getPreferredSize() {
            return new Dimension(PREF_W, PREF_H);
         }
      };

      JToggleButton toggleButton = new JToggleButton("Full Screen");
      toggleButton.setFocusable(false);
      toggleButton.setMnemonic(KeyEvent.VK_F);
      toggleButton.addItemListener(new ItemListener() {

         @Override
         public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
               frame.dispose();
               frame.setUndecorated(true);
               frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
               frame.setVisible(true);
            } else {
               frame.dispose();
               frame.setUndecorated(false);
               frame.setExtendedState(JFrame.NORMAL);
               frame.pack();
               frame.setLocationRelativeTo(null);
               frame.setVisible(true);
            }
         }
      });
      mainPanel.add(toggleButton);
      final JLabel keyListenerLabel = new JLabel();
      final JLabel keyBindingLabel = new JLabel();

      mainPanel.add(new JLabel("Press Right or Left Arrow Key To Test"));
      mainPanel.add(keyListenerLabel);
      mainPanel.add(keyBindingLabel);

      keyListenerLabel.setBorder(BorderFactory.createLineBorder(Color.black));
      keyBindingLabel.setBorder(BorderFactory.createLineBorder(Color.black));

      mainPanel.addKeyListener(new KeyAdapter() {

         @Override
         public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_LEFT) {
               keyListenerLabel.setText("KeyListener: left pressed");
            } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
               keyListenerLabel.setText("KeyListener: right pressed");
            }
         }
      });

      int condition = JPanel.WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = mainPanel.getInputMap(condition);
      ActionMap actionMap = mainPanel.getActionMap();

      KeyStroke leftArrowStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);
      KeyStroke rightArrowStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
      inputMap.put(leftArrowStroke, leftArrowStroke.toString());
      inputMap.put(rightArrowStroke, rightArrowStroke.toString());
      actionMap.put(leftArrowStroke.toString(), new AbstractAction() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            keyBindingLabel.setText("Key Bindings: left Arrow Pressed");
         }
      });
      actionMap.put(rightArrowStroke.toString(), new AbstractAction() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            keyBindingLabel.setText("Key Bindings: right Arrow Pressed");
         }
      });


      mainPanel.setFocusable(true);
      mainPanel.requestFocusInWindow();

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

【讨论】:

  • mainPanel.requestFocusInWindow(); 甚至对 KeyListener 也有效。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多