【问题标题】:Request focus for keylistener, not sure if i have focus or not?为 keylistener 请求焦点,不确定我是否有焦点?
【发布时间】:2015-01-06 00:18:27
【问题描述】:

我不知道为什么当我按下 w 时,我的矩形没有相应地调整。我的重点设置是否正确,还是需要从单独的班级申请?我应该在我的drawingComponent 班级还是在我的“核心”班级中这样做?

package scratch;


import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.*;

public class drawingComponent extends JComponent implements KeyListener {

    Rectangle hello = new Rectangle(300, 100, 50, 50);

    public void paintComponent(Graphics g){
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(new Color(255,25,0));
        g2.setFont(new Font("monospace", Font.BOLD+Font.ITALIC, 30));
        g2.drawString("nothing yet",300,320);
        g2.fill(hello);

    }


    @Override
    public void keyPressed(KeyEvent e) {

        if(e.getKeyCode() == KeyEvent.VK_W){

             hello.setLocation(hello.x-50, hello.y);
             repaint();

        }


    }

    @Override
    public void keyReleased(KeyEvent e) {


    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

}

我通过将以下内容添加到我的 drawingComponent 类中解决了这个问题。

setFocusable(true);
requestFocus();
addKeyListener(this);

【问题讨论】:

  • 1) 为此使用键绑定,而不是 KeyListener。 2)如果您仍然卡住,请考虑创建并发布Minimal, Complete, and Verifiable Example Program
  • 3) 在你的 override 中调用 super 的 paintComponent 方法,以免你不擦除旧图像。

标签: java swing


【解决方案1】:

您想使用Key Bindings,而不是 KeyListener 有几个原因,但其中一个原因是您不必太担心 Key Bindings 的焦点。此外,您将来会希望发布一个minimal example program,我们可以测试、运行和修改,如下所示:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class DrawingComponent extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = 600;
   private static final Color RECT_COLOR = new Color(255,25,0);
   private Rectangle rect = new Rectangle(300, 100, 50, 50);

   public DrawingComponent() {
      setUpKeyBindings();
   }

   private void setUpKeyBindings() {
      int condition = WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);
      ActionMap actionMap = getActionMap();

      KeyStroke wStroke = KeyStroke.getKeyStroke(KeyEvent.VK_W, 0);
      inputMap.put(wStroke, wStroke.toString());
      actionMap.put(wStroke.toString(), new WAction());
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setColor(RECT_COLOR);
      g2.fill(rect);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class WAction extends AbstractAction {
      @Override
      public void actionPerformed(ActionEvent e) {
         rect.setLocation(rect.x-50, rect.y);
         repaint();
      }
   }

   private static void createAndShowGui() {
      DrawingComponent mainPanel = new DrawingComponent();

      JFrame frame = new JFrame("DrawingComponent");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

另外,在你的覆盖中调用 super 的 paintComponent 方法,否则你的 JPanel 不会删除旧图像。

【讨论】:

  • 谢谢您的回答,先生。我没想到我的问题这么复杂。感谢您的洞察力,但现在将继续使用 keylistener,直到我了解它是如何工作的。
  • @wilkers:您当前提出的问题本质上是"why isn't the code that I'm not showing you not working",因为您不知道错误的确切位置,因此您发布的代码没有显示它。如果您仍想了解您的 KeyListener 为何不起作用,那么您需要创建并发布您的 MCVE。但无论如何,如果您想解决问题并正确编码,请阅读我上面提供的关于如何使用键绑定的链接。
  • @wilkers:请不要冒犯,但我敢打赌,我比你更熟悉何时使用 KeyListeners 和何时使用 Key Bindings,并且在使用 Key Bindings 时,焦点问题变成了非问题。但我不是在这里强迫你相信我或听从我的建议。相反,我在这里只是为了提供我的建议,您可以根据自己的选择遵循或不遵循的建议。如果你想看看你的代码为什么不工作,我仍然坚定地建议你创建一个 MCVE 帖子。
  • 完全没有冒犯。例如,设置此特定代码以适用于无法接受通用键绑定的较大代码。我不需要设置 MCVE,而且您的 cmets 没有帮助。谢谢
  • @wilkers 我必须同意 HovercraftFullOfEels,键绑定是解决方案,将解决您的焦点相关问题,而无需在不同平台和系统上可能会或可能不会工作的讨厌的黑客或变通方法
猜你喜欢
  • 2011-09-09
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 2013-07-09
  • 1970-01-01
  • 2023-03-05
相关资源
最近更新 更多