进过测试发现,鼠标点击页面中非applet的部分就会使applet无法接受键盘事件.

解决方案 »

  1.   

    即使不用keyListener,改用InputMap,问题也依旧>你提供的这个例子同样存在此问题,有办法解决吗?
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;class SketchPanel extends JPanel
      implements KeyListener
    {
    InputMap mapaEntrada;
    ActionMap mapaAction ;
    HandlerKey hkLeft = new HandlerKey("LeftKey",KeyEvent.VK_LEFT);
    HandlerKey hkRight = new HandlerKey("RightKey",KeyEvent.VK_RIGHT);
    HandlerKey hkPageUp = new HandlerKey("PageUp",KeyEvent.VK_PAGE_UP);
    HandlerKey hkPageDown = new HandlerKey("PageDown",KeyEvent.VK_PAGE_DOWN);
    public SketchPanel()
      {  addKeyListener(this);
      mapaEntrada= getInputMap(WHEN_IN_FOCUSED_WINDOW);
      mapaAction = getActionMap();
      mapaEntrada.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0),"LeftKey");
      mapaEntrada.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0),"RightKey");
      mapaEntrada.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,0),"PageUp");
      mapaEntrada.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,0),"PageDown");
      mapaAction.put("LeftKey",hkLeft);
      mapaAction.put("RightKey",hkRight);
      mapaAction.put("PageUp",hkPageUp);
      mapaAction.put("PageDown",hkPageDown);
      }  public void keyPressed(KeyEvent evt)
      {  int keyCode = evt.getKeyCode();
          int d;
          if (evt.isShiftDown())
            d = 5;
          else
            d = 1;
          if (keyCode == KeyEvent.VK_LEFT) add(-d, 0);
          else if (keyCode == KeyEvent.VK_RIGHT) add(d, 0);
          else if (keyCode == KeyEvent.VK_UP) add(0, -d);
          else if (keyCode == KeyEvent.VK_DOWN) add(0, d);
      }  public void keyReleased(KeyEvent evt)
      {}  public void keyTyped(KeyEvent evt)
      {  char keyChar = evt.getKeyChar();
          int d;
          if (Character.isUpperCase(keyChar))
          {  d = 5;
            keyChar = Character.toLowerCase(keyChar);
          }
          else
            d = 1;
          if (keyChar == 'h') add(-d, 0);
          else if (keyChar == 'l') add(d, 0);
          else if (keyChar == 'k') add(0, -d);
          else if (keyChar == 'j') add(0, d);
      }  public boolean isFocusTraversable() { return true; }  public void add(int dx, int dy)
      {  end.x += dx;
          end.y += dy;
          Graphics g = getGraphics();
          g.drawLine(start.x, start.y, end.x, end.y);
          g.dispose();
          start.x = end.x;
          start.y = end.y;
      }  private Point start = new Point(50, 50);
      private Point end = new Point(50, 50);
    }public class Sketch extends JApplet
    {  public void init()
    {
    Container contentPane = getContentPane();
          contentPane.add(new SketchPanel());
          FocusManager.getCurrentManager().focusNextComponent(contentPane);
        }
    }
    class HandlerKey extends AbstractAction
    {//LEFT,RIGHT,PAGEUP,PAGE DOWN will travel the images
    int nKeyCode=0;
    public HandlerKey(String s)
    {
    super(s);
    }
    public HandlerKey(String s,int keycode)
    {
    super(s);
    nKeyCode=keycode;
    }
    public void actionPerformed(ActionEvent e)
    {System.out.println(nKeyCode);
    if(nKeyCode==KeyEvent.VK_LEFT)
    {return;
    }
    if(nKeyCode==KeyEvent.VK_RIGHT)
    {return;
    }
    if(nKeyCode==KeyEvent.VK_PAGE_DOWN)
    {
    return;
    }
    if(nKeyCode==KeyEvent.VK_PAGE_UP)
    {
    return;
    }
    }
    }//end of HandlerKey 
      

  2.   

    鼠标点在别的地方,applet失去输入焦点,当然接受不到键盘事件。我用一个线程隔一段时间执行FocusManager.getCurrentManager().focusNextComponent(contentPane);还是没有成功。
    可能要用DHTML把document的click事件转移到applet上来。我正在试验,你也可以试一下。    
      

  3.   

    鼠标点在别的地方以后,applet失去输入焦点.我再用鼠标点页面中的applet,好象它无法重新接受焦点,从而接受不到键盘事件.
    但是,如果我不点击页面中的非applet区域,切换到其它应用程序,再切换回来,applet仍然能接受键盘事件,在这个过程中applet算失去过输入焦点吗?
    能否把IE窗口的大小固定为applet的大小,使用户在ie中的鼠标点击都落在applet上?
    www.chinaren.com 戏栏目中的俄罗斯方块就不存在这个问题,不知它是怎么解决的?
    我的程序放在 51play6.yeah.net 可以来看看
      

  4.   

    要把IE窗口的大小固定为applet的大小,你用JS开一个新窗口,在里面指定不就行了……
      

  5.   

    <html>
    <HEAD></HEAD>
    <BODY>
    <form id="hide">
    <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
    WIDTH = 400 HEIGHT = 400 NAME = "TestApplet"
    codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
    <PARAM NAME="SCRIPTABLE" VALUE="true">
    <PARAM NAME= CODE VALUE= "Sketch.class" >
    <PARAM NAME= CODEBASE VALUE= "." >
    <PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
    </OBJECT>
    <INPUT style="border: 0px;" ReadOnly id=xx maxLength=0
    name="xx" type=text notab>
    </form>
    <SCRIPT LANGUAGE="JavaScript">
    function focusToApplet ()
    {
    // This pulls focus away from the applet so the next stuffcan
    // put it back. It seems without this every second try doesnot
    // restore focus to the applet
    hide.xx.focus();
    document.TestApplet.jsForceFocus();
    document.TestApplet.requestFocus();
    }
    window.onfocus = focusToApplet;
    </SCRIPT>
    <p>something here</P>
    </body>
    </html>
      

  6.   

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;class SketchPanel extends JPanel
      implements KeyListener
    {
    InputMap mapaEntrada;
    ActionMap mapaAction ;
    HandlerKey hkLeft = new HandlerKey("LeftKey",KeyEvent.VK_LEFT);
    HandlerKey hkRight = new HandlerKey("RightKey",KeyEvent.VK_RIGHT);
    HandlerKey hkPageUp = new HandlerKey("PageUp",KeyEvent.VK_PAGE_UP);
    HandlerKey hkPageDown = new HandlerKey("PageDown",KeyEvent.VK_PAGE_DOWN);
    public SketchPanel()
      {  addKeyListener(this);
      mapaEntrada= getInputMap(WHEN_IN_FOCUSED_WINDOW);
      mapaAction = getActionMap();
      mapaEntrada.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0),"LeftKey");
      mapaEntrada.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0),"RightKey");
      mapaEntrada.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,0),"PageUp");
      mapaEntrada.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,0),"PageDown");
      mapaAction.put("LeftKey",hkLeft);
      mapaAction.put("RightKey",hkRight);
      mapaAction.put("PageUp",hkPageUp);
      mapaAction.put("PageDown",hkPageDown);
      requestDefaultFocus();
      }  public void keyPressed(KeyEvent evt)
      {  int keyCode = evt.getKeyCode();
          int d;
          if (evt.isShiftDown())
            d = 5;
          else
            d = 1;
          if (keyCode == KeyEvent.VK_LEFT) add(-d, 0);
          else if (keyCode == KeyEvent.VK_RIGHT) add(d, 0);
          else if (keyCode == KeyEvent.VK_UP) add(0, -d);
          else if (keyCode == KeyEvent.VK_DOWN) add(0, d);
      }  public void keyReleased(KeyEvent evt)
      {}  public void keyTyped(KeyEvent evt)
      {  char keyChar = evt.getKeyChar();
          int d;
          if (Character.isUpperCase(keyChar))
          {  d = 5;
            keyChar = Character.toLowerCase(keyChar);
          }
          else
            d = 1;
          if (keyChar == 'h') add(-d, 0);
          else if (keyChar == 'l') add(d, 0);
          else if (keyChar == 'k') add(0, -d);
          else if (keyChar == 'j') add(0, d);
      }  public boolean isFocusTraversable() { return true; }  public void add(int dx, int dy)
      {  end.x += dx;
          end.y += dy;
          Graphics g = getGraphics();
          g.drawLine(start.x, start.y, end.x, end.y);
          g.dispose();
          start.x = end.x;
          start.y = end.y;
      }  private Point start = new Point(50, 50);
      private Point end = new Point(50, 50);
    }public class Sketch extends JApplet implements FocusListener, WindowListener
    {
    private Frame parentFrame;
    public Sketch()
    {
    addFocusListener(this);
    parentFrame = JOptionPane.getFrameForComponent(this);
    parentFrame.addWindowListener(this);

    }
    public void jsForceFocus()
    {

    WindowEvent e = new WindowEvent(parentFrame,
    WindowEvent.WINDOW_ACTIVATED);
    parentFrame.dispatchEvent(e);

    }
    public void init()
    {
    Container contentPane = getContentPane();
          contentPane.add(new SketchPanel());
            FocusManager.getCurrentManager().focusNextComponent(contentPane);
        }
        public void focusLost(FocusEvent e)
        {
            FocusManager.getCurrentManager().focusNextComponent(getContentPane()); }
    public void focusGained(FocusEvent e)
    {
            FocusManager.getCurrentManager().focusNextComponent(getContentPane()); }
    public void windowOpened(WindowEvent e) {
    //System.out.println("windowOpened");
    }public void windowClosing(WindowEvent e) {
    //System.out.println("windowClosing"); 
    }public void windowClosed(WindowEvent e) {
    //System.out.println("windowClosed");
    }public void windowIconified(WindowEvent e) {
    //System.out.println("windowIconified");
    }public void windowDeiconified(WindowEvent e) {
    //System.out.println("windowDeiconified");
    }public void windowActivated(WindowEvent e) {
    //System.out.println("windowActivated");if (parentFrame.getFocusOwner() != null ) {
    parentFrame.getFocusOwner().requestFocus();
    }}public void windowDeactivated(WindowEvent e) {
    //System.out.println("windowDeactivated");
    }
    }
    class HandlerKey extends AbstractAction
    {//LEFT,RIGHT,PAGEUP,PAGE DOWN will travel the images
    int nKeyCode=0;
    public HandlerKey(String s)
    {
    super(s);
    }
    public HandlerKey(String s,int keycode)
    {
    super(s);
    nKeyCode=keycode;
    }
    public void actionPerformed(ActionEvent e)
    {
    System.out.println(nKeyCode);
    }
    }//end of HandlerKey
      

  7.   

    to masterz(),谢谢
    虽然有些代码现在还看不懂,但依葫芦画瓢还是把自己俄罗斯方块的问题给解决了.