2014-01-11 35 views
0

我有單獨的類來處理鼠標監聽器。但是當我從另一個班級使用它時,它不工作,我不知道如何解決這個問題。在這裏我Handler類:MouseListener在單獨的類不工作

some import stuff 

public class Handler implements MouseListener, MouseMotionListener { 
private final Canvas canvas; 

public Handler(Canvas targetCanvas) { 
    this.canvas = targetCanvas; 
} 

// recasting exception 
public Canvas getTargetCanvas() { 
    return canvas; 
} 
... 
... 
@Override 
public void mouseDragged(MouseEvent e) { 
    // recasting exception 
    DrawingCanvas dC = (DrawingCanvas) getTargetCanvas(); 
    dC.setMouseDragged(true); 
} 

@Override 
public void mouseMoved(MouseEvent e) { 
    // recasting exception 
    DrawingCanvas dCanvas = (DrawingCanvas) getTargetCanvas(); 
    dCanvas.setMouseClicked(true); 
    dCanvas.setMouseCoordinates(e.getPoint()); 
} 
} 

DrawingCanvas類:

some import stuff 

public class DrawingCanvas extends Canvas { 
private boolean isMouseDragged, isMouseMoved; 
private Point mouseCoordinates; 

public DrawingCanvas() { 
    this.setPreferredSize(new Dimension(790, 500)); 
    this.setBackground(Color.WHITE); 
} 

public Point getMouseCoordinates() { 
    return mouseCoordinates; 
} 

public boolean isIsMouseDragged() { 
    return isMouseDragged; 
} 

public boolean isIsMouseMoved() { 
    return isMouseMoved; 
} 
... 
... 
public void setMouseDragged(boolean dragged) { 
    isMouseDragged = dragged; 
} 

public void setMouseMoved(boolean moved) { 
    isMouseMoved = moved; 
} 

public void setMouseCoordinates(Point coordinates) { 
    mouseCoordinates = coordinates; 
} 
} 

狀態欄類:

some import stuff 

public class StatusBar extends JPanel { 
private JLabel statusBar; 

public StatusBar() { 
    statusBar = new JLabel(); 

    this.setPreferredSize(new Dimension(500, 30)); 
    this.setBackground(new Color(242,241,240)); 
    this.add(statusBar, new BorderLayout(5,0)); 

} 

public JLabel getStatusBar() { 
    return statusBar; 
} 

public void setStatusBar(JLabel statusBar) { 
    this.statusBar = statusBar; 
} 
} 

而且MouseEventGUI類:

some import stuff 

public class MouseEventGUI extends JFrame { 
private DrawingCanvas drawingCanvas; 
private StatusBar statusBar; 
private MenuBar menuBar; 

public MouseEventGUI() { 
    super("Learn Mouse Event"); 

    drawingCanvas = new DrawingCanvas(); 
    statusBar = new StatusBar(); 
    menuBar = new MenuBar(); 

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setPreferredSize(new Dimension(750, 560)); 

    this.add(menuBar, BorderLayout.NORTH); 
    this.add(drawingCanvas, BorderLayout.CENTER);  
    this.add(statusBar, BorderLayout.SOUTH); 
    this.addMouseListener(new Handler(drawingCanvas)); 
    this.addMouseMotionListener(new Handler(drawingCanvas)); 

    if(drawingCanvas.isIsMouseMoved()){ 
     statusBar.getStatusBar().setText(String.format("%d, %d", 
       drawingCanvas.getMouseCoordinates().x, 
       drawingCanvas.getMouseCoordinates().y)); 
    } else { 
     statusBar.getStatusBar().setText("Mouse is not listened."); 
    }  
} 
} 

當我運行該程序,在狀態欄顯示「鼠標沒有被監聽「(見MouseEventGUI類),我希望它顯示鼠標光標的座標,如果我在畫布中移動它。

[更新]

如果在相同的類,它工作以及經過一些修改。這裏DrawingCanvas類的代碼:

public class DrawingCanvas extends JPanel { 
private boolean isMouseClicked, 
     isMouseMoved; 
private Point mouseCoordinates; 
protected StatusBar statusBar; 
protected MenuBar menuBar; 


public DrawingCanvas(StatusBar st) { 
    setPreferredSize(new Dimension(790, 500)); 
    setBackground(Color.WHITE); 
    statusBar = st; 
    Handlers handlers = new Handlers(); 
    addMouseListener(handlers); 
    addMouseMotionListener(handlers); 
} 

**// inner class** 
protected class Handlers extends MouseAdapter implements MouseListener, MouseMotionListener { 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     statusBar.getStatusBar().setText("Mouse clicked."); 
    } 

    @Override 
    public void mouseMoved(MouseEvent e) {    
     statusBar.getStatusBar().setText(String.format("%d, %d", e.getX(),e.getY())); 

    } 

} 
} 

和這裏MouseEventGUI類:

public class MouseEventGUI extends JFrame { 
private DrawingCanvas drawingCanvas; 
private StatusBar statusBar; 
private MenuBar menuBar; 

public MouseEventGUI() { 
    super("Learn Mouse Event"); 

    statusBar = new StatusBar(); 
    menuBar = new MenuBar(); 
    drawingCanvas = new DrawingCanvas(statusBar); 

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setPreferredSize(new Dimension(750, 560)); 
    this.add(menuBar, BorderLayout.NORTH); 
    this.add(drawingCanvas, BorderLayout.CENTER);  
    this.add(statusBar, BorderLayout.SOUTH); 
} 
} 

不過,我計劃把它在不同的類可重複使用的原因。

+1

請定義我們你所說的 「它不工作」 是什麼意思?你已經拋棄了很多代碼,並提供了很少的描述。請幫助我們更好地瞭解您的代碼和問題,以便我們能夠更好地幫助您。順便說一句:爲什麼是AWT而不是Swing?此外,你的MouseListener似乎沒有做任何可衡量的事情。 –

+0

@Hovercraft:我已經約會了我的貼子 –

+1

爲了更好地幫助,請發佈[MCVE](http://stackoverflow.com/help/mcve)。如果它在***相同類中,它是否工作?這是你應該首先檢查的東西。 KeyListener類因失敗而臭名昭着。而且,對於Swing,通常使用基於AWT的較低級別的KeyListener上的鍵綁定。有關如何使用它們的詳細信息,請參見[如何使用鍵綁定](http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html)。 –

回答

2

建議:

  • 是,使處理器完全獨立的獨立的階級。
  • 是的,通過MouseEvent的getSource()方法獲取您的聽取組件。您可以使用instanceof運算符在投射前檢查它是否是正確類型的對象,但如果您始終只將它添加到一種類型的對象,則這不是問題。
  • 是的,正如Camickr和其他人所建議的,不要使用AWT的Canvas,而應該使用Swing的JPanel。如果將AWT和Swing組件混合在一起,會出現陷阱,如果使用AWT而不是Swing,則會失去很多功能,並且不需要使用Canvas。
  • 我會有MouseListener(在我的代碼中,我使用了一個MouseAdapter,因爲它可以允許稍微更緊湊的代碼和更少的不必要的代碼,比如空方法)通過調用setter方法來更改組件的狀態。
  • 通過讓setter方法更改「綁定」屬性的狀態,我通過通知任何PropertyChangeListener對其更改感興趣的任何PropertyChangeListeners,我已經有了這項工作。
  • 我想這樣做 - 使用MouseListener向JPanel添加PropertyChangeListener,如果發生鼠標事件,則更改狀態JPanel的狀態。

例如:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class HandlerTester extends JPanel { 
    public HandlerTester() { 
     Handler handler = new Handler(); 
     final MyPanel myPanel = new MyPanel(); 
     myPanel.addMouseListener(handler); 
     myPanel.addMouseMotionListener(handler); 

     final StatusPanel statusPanel = new StatusPanel(); 

     myPanel.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent pcEvt) { 
      if (MyPanel.MOUSE_PRESSED.equals(pcEvt.getPropertyName())) { 
       statusPanel.setMousePressed(((Boolean)pcEvt.getNewValue()).booleanValue()); 
      } 
     } 
     }); 

     setLayout(new BorderLayout()); 
     add(myPanel, BorderLayout.CENTER); 
     add(statusPanel, BorderLayout.PAGE_END); 
    } 

    private static void createAndShowGUI() { 
     HandlerTester handlerTester = new HandlerTester(); 

     JFrame frame = new JFrame("HandlerTester"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(handlerTester); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

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

class Handler extends MouseAdapter { 
    @Override 
    public void mousePressed(MouseEvent mEvt) { 
     Object src = mEvt.getSource(); 
     if (src instanceof MyPanel) { 
     MyPanel myPanel = (MyPanel) src; 
     myPanel.setMousePressed(true);   
     } 
    } 

    @Override 
    public void mouseReleased(MouseEvent mEvt) { 
     Object src = mEvt.getSource(); 
     if (src instanceof MyPanel) { 
     MyPanel myPanel = (MyPanel) src; 
     myPanel.setMousePressed(false);   
     } 
    } 
} 

@SuppressWarnings("serial") 
class MyPanel extends JPanel { 
    public static final String MOUSE_PRESSED = "mouse pressed"; 
    private static final int PREF_W = 600; 
    private static final int PREF_H = 400; 
    private boolean mousePressed = false; 

    public boolean isMousePressed() { 
     return mousePressed; 
    } 

    public void setMousePressed(boolean mousePressed) { 
     boolean oldValue = this.mousePressed; 
     boolean newValue = mousePressed; 
     this.mousePressed = mousePressed; 
     firePropertyChange(MOUSE_PRESSED, oldValue, newValue); 
    } 

    public Dimension getPreferredSize() { 
     return new Dimension(PREF_W, PREF_H); 
    } 
} 

@SuppressWarnings("serial") 
class StatusPanel extends JPanel { 
    private static final String MOUSE_PRESSED = "Mouse Pressed"; 
    private static final String MOUSE_NOT_PRESSED = "Mouse Not Pressed"; 
    private JLabel label = new JLabel(MOUSE_NOT_PRESSED); 

    public StatusPanel() { 
     setLayout(new FlowLayout(FlowLayout.LEADING)); 
     add(label); 
     setBorder(BorderFactory.createEtchedBorder()); 
    } 

    public void setMousePressed(boolean mousePressed) { 
     String text = mousePressed ? MOUSE_PRESSED : MOUSE_NOT_PRESSED; 
     label.setText(text); 
    } 
} 
+0

我在試着學習你的代碼。你能否給我一些線索如何讓你的代碼中使用myPanel協調器?我想在myPanel中移動時顯示鼠標光標。 –

+0

使用我的想法,但寫下你的代碼。 MouseEvent參數提供了座標,getX(),getY()和getPoint()可用。 –

+0

好的,我會試試看。謝謝。 –

相關問題