Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
单独类中的Java KeyListener_Java_Swing_Key_Listener_Key Bindings - Fatal编程技术网

单独类中的Java KeyListener

单独类中的Java KeyListener,java,swing,key,listener,key-bindings,Java,Swing,Key,Listener,Key Bindings,我在这里有一个主类,它基本上创建了一个新的jframe并向其中添加了一个world对象。世界对象基本上是所有绘图和键盘监听的地方 public class Blobs extends JFrame{ public Blobs() { super("Blobs :) - By Chris Tanaka"); setVisible(true); setResizable(false); setSize(1000, 1000);

我在这里有一个主类,它基本上创建了一个新的jframe并向其中添加了一个world对象。世界对象基本上是所有绘图和键盘监听的地方

public class Blobs extends JFrame{

    public Blobs() {
        super("Blobs :) - By Chris Tanaka");
        setVisible(true);
        setResizable(false);
        setSize(1000, 1000);
        setIgnoreRepaint(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        add(new World());
    }

    public static void main(String[] args) {
        new Blobs();
    }
}
您将如何获得世界级的关键输入? (到目前为止,我有我的世界级扩展了一个jpanel并实现了一个keylistener。在构造函数中我添加了keylistener(这个)。我也有这些方法,因为它们是自动实现的:

public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_W)
        System.out.println("Hi");
}

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

但是,这似乎不起作用?

如果您的Worls类实现了KeyListener,那么您尝试执行的一种方法就是像这样更改Blob构造函数

 public Blobs() {
        super("Blobs :) - By Chris Tanaka");
        setVisible(true);
        setResizable(false);
        setSize(1000, 1000);
        setIgnoreRepaint(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        World world = new World();
        getContentPane().add(world);
        this.addKeyListener(world);
        setVisible(true);
 }

它不起作用,因为默认情况下JPanel不获取焦点。可以通过将其focusable属性设置为true并请求焦点来解决


尽管如此,我认为JPanel类不实现侦听器接口是很重要的,因为您最好使用匿名内部类作为侦听器。您甚至可以使用键绑定而不是键侦听器,但根据目前提供的数据,我无法判断。

这是一个很好的技术如果您想通知“观察类”在您的世界级中发生按键事件,请允许我使用观察者。结构如下所示:

public interface Observer
{ 
   public void update(KeyEvent keyEvent);
}

public interface Observable
{
   public void NotifyObservers(KeyEvent keyEvent);
}

public class World implements KeyListener, Observable
{
   private ArrayList<Observer> obsList;

   public World()
   {
      obsList = new ArrayList();
   }

   public void keyPressed(KeyEvent e) 
   {
      NotifyObservers(e);
   }

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

   public void NotifyObservers(KeyEvent keyEvent)
   {
       for(Observer obs : obsList)
       {
           obs.update(keyEvent);
       }
   }

   public void AddObserver(Observer obs)
   {
       if (obs != null)
          obsList.add(obs);
   }

   public void DelObserver(Observer obs)
   {
       if (obs != null)
          obsList.remove(obs);
   }
}

public class Blobs extends JFrame implements Observer
{

    public Blobs() 
    {
        super("Blobs :) - By Chris Tanaka");

        //Register this instance of Blobs as an observer that is stored in the World's
        //obsList ArrayList field
        World world = new World();
        world.addObserver(this);

        setResizable(false);
        setSize(1000, 1000);
        setIgnoreRepaint(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        getContentPane().add(world);
        this.addKeyListener(world);
        setVisible(true);
    }

    public static void main(String[] args) {
        new Blobs();
    }

    public void update(KeyEvent keyEvent)
    {
       //do whatever here when key event occurs
    }
}
你只需要在某个时刻,像我在Blobs中做的那样,以观察员的身份为你的世界级加入战斗

worldInstance.addObserver(new Battle());
此外,如果希望使用标志仅允许某些类处理keyevents,则可以简单地更新接口,以允许将标志传递给update方法,如下所示:

public interface Observer
{
   public void update(object isFor, KeyEvent e);
}
然后,您的观察者更新方法将具有这种流:

public class Battle 
{
   public void update(object flag, KeyEvent e)
   {
        if (flag instanceof Battle)
        {
            //now do your work
        }
   }
}

这也意味着更新Observable接口和实现者中的notify方法,我们可以看到世界级吗?并确保
World
是可聚焦的。(不知道默认情况下是否是)@Chris如果你对整个过程的工作原理有任何疑问,请让我知道。一旦你理解了其中的一些细节,这一切都是有意义的,并且使将事件驱动逻辑传递给其他类进行处理变得更加容易。我一直在看这段代码,我的理解是,如果使用你的解决方案,我将不会o将处理按键的所有代码放在我的主Blobs类中?更具体地说,我想要的是让我的世界类处理我角色的所有世界移动(绘制和按键处理)还有一个单独处理键处理和绘图的battle类。换句话说,我希望能够完成battle battle=new battle()在我的世界级中,一旦战斗结束,控制权就会恢复到世界上。@Chris关于所有键处理都在Blobs类中处理的假设是错误的。观察者的优点是可以有多个。请看上面的编辑。
public class Battle 
{
   public void update(object flag, KeyEvent e)
   {
        if (flag instanceof Battle)
        {
            //now do your work
        }
   }
}