2016-04-01 19 views
0

JPanelで作成されたボタンを使用してゲームを作成しようとしています。MouseListenerがランタイム中にエラーを出す

at java.awt.AWTEventMultiCaster.mouse[eventName](UnknownSource) 

それは私が見ることができないので、速く行く:しかし、プログラムの実行時にいくつかの点で、JPanelのボタンがマウスイベントは、次の形式で登録されるたびに一定の誤差を与えることから始まるために使用しました初期エラー、およびエラーは、実行中の途中のある時点でのみ開始されます。誰か助けてくれますか?私のJPanelのコードは次のとおりです。

JPanel trackPanel = new JPanel() { 
     int state = 0; 
     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponents(g); 

      addMouseListener(new MouseAdapter() { 
       public void mouseEntered(MouseEvent e) { 
        if (dragMe == null) { 
         state = 1; 
        } 
       } 
       public void mouseExited(MouseEvent e) { 
        if (dragMe == null) state = 0; 
        else state = 1; 
       } 
       public void mousePressed(MouseEvent e) { 
        if (dragMe == null && !e.isMetaDown()) 
        { 
         dragMe = new DragFrameThread(vTrack); 
         dragMe.start(); 
        } 
        state = 2; 
       } 
       public void mouseReleased(MouseEvent e) { 
        if (state == 2 && e.isMetaDown()) System.exit(0); 
        if (dragMe != null) { 
         dragMe.interrupt(); 
         dragMe = null; 
         state = 1; 
        } 
       } 
      }); 

      g.setColor(new Color(0, 127, 127, 255)); 
      g.drawRect(0, 0, getWidth()-1, getHeight()-1); 
      g.setColor(new Color(0, 127, 127, 223)); 
      g.drawRect(1, 1, getWidth()-3, getHeight()-3); 
      g.setColor(new Color(0, 127, 127, 191)); 
      g.drawRect(2, 2, getWidth()-5, getHeight()-5); 
      g.setColor(new Color(0, 127, 127, 159)); 
      g.fillRect(3, 3, getWidth()-6, getHeight()-6); 

      g.drawImage(BootAssets.VTScaledLogo, 0, 0, getWidth(), getHeight(), null); 

      if (state == 1) g.setColor(new Color(255, 255, 255, 127)); 
      if (state == 2) g.setColor(new Color(0, 0, 0, 127)); 
      if (state != 0) g.fillRect(0, 0, getWidth(), getHeight()); 

      repaint(); 
     } 
    }; 

ありがとうございました! 〜パラ

+4

私はここのコードに従っていないかもしれませんが、paintComponetは呼び出されるたびに新しいリスナーを登録しているようです。リスナーをtrackPanelに一度追加するのではなく、すべてのペイント呼び出しで追加するべきではありませんか? – KevinO

+0

これは正しい答えのようです@KevinO – beirtipol

+0

@ KevinOまあ、paintComponent以外の場所にリスナーを追加することができないという問題があります。 – pyrif

答えて

0

ウィジェットが描画されるときにpaintComponentメソッドが呼び出されるという問題があると思います。すべてのペイントコールでマウスリスナーを追加するのは間違っています。

addMouseListenerをpaintComponentメソッドから移動し、trackPanelに別々に追加します。 JPanelが定義されている状態で現在状態が設定され更新されているので、コードをリファクタリングする必要があります。

 private final AtomicInteger state = new AtomicInteger(0); 
     JPanel trackPanel = new JPanel() { 
     @Override 
     protected void paintComponent(Graphics g) 
     { 
      super.paintComponent(g); 

      g.setColor(new Color(0, 127, 127, 255)); 
      g.drawRect(0, 0, getWidth()-1, getHeight()-1); 
      g.setColor(new Color(0, 127, 127, 223)); 
      g.drawRect(1, 1, getWidth()-3, getHeight()-3); 
      g.setColor(new Color(0, 127, 127, 191)); 
      g.drawRect(2, 2, getWidth()-5, getHeight()-5); 
      g.setColor(new Color(0, 127, 127, 159)); 
      g.fillRect(3, 3, getWidth()-6, getHeight()-6); 

      g.drawImage(BootAssets.VTScaledLogo, 0, 0, getWidth(), getHeight(), null); 

      if (state.get() == 1) g.setColor(new Color(255, 255, 255, 127)); 
      if (state.get() == 2) g.setColor(new Color(0, 0, 0, 127)); 
      if (state.get() != 0) g.fillRect(0, 0, getWidth(), getHeight());     
     } 
    }; 

    trackPanel.addMouseListener(new MouseAdapter() { 
     public void mouseEntered(MouseEvent e) { 
      if (dragMe == null) { 
       state.set(1); 
      } 
     } 
     public void mouseExited(MouseEvent e) { 
      if (dragMe == null) state.set(0); 
      else state.set(1); 
     } 
     public void mousePressed(MouseEvent e) { 
      if (dragMe == null && !e.isMetaDown()) 
      { 
       dragMe = new DragFrameThread(vTrack); 
       dragMe.start(); 
      } 
      state.set(2); 
     } 
     public void mouseReleased(MouseEvent e) { 
      if (state.get() == 2 && e.isMetaDown()) System.exit(0); 
      if (dragMe != null) { 
       dragMe.interrupt(); 
       dragMe = null; 
       state.set(1); 
      } 
     } 
    }); 
+0

ありがとうございました!しかし、あなたの最初の返答の後、私はJPanelのコード内にプライベートブール値を作成し、それが真であるかどうかをテストする別の解決法を見つけました。そうでない場合は、リスナーを追加してtrueに設定しました。あなたが提供したソリューションはより効率的でしょうか? – pyrif

+0

@UnityParadox答えの解は、毎回リスナーを追加する必要があるかどうかをチェックしないので、わずかに効率的です。また、リスナーを追加してペイントコールバックを乱雑にしない、よりクリーンなコードです。リスナーを追加するのは混乱する場所です。可読性と保守性は、コードを機能させるだけでなく、重要な考慮事項です。リファクタリングする必要があるときはどうなりますか?塗装方法は塗装のみを扱うべきです。メソッドを、それが行うように設計された単一のものにします。ペイントコールバックの外側のパネルにマウスリスナーを追加します。 – KevinO

+0

助けてくれてありがとう!私は現時点ではできないので、これを後でチェックします。 – pyrif

関連する問題