2013-07-05 55 views
2

我正在嘗試開發一個組件可以通過監聽器與其他組件通信的GUI界面。我所面對的問題是: -如何處理java swing組件事件而不會造成凌亂的課堂?

方法


  1. 實施聽衆
  2. 使用匿名方法
  3. 從實施聽衆
類增加聽衆將與聽衆方法聽衆

問題


  1. 實施聽衆造成混亂試圖用大量的對象
  2. 同1除了構造函數需要總決賽匿名方法
  3. 廣東話對象進行操作的聽力課之外打交道時對對象的操作而不訴諸於靜態引用。

這是因爲,我怎樣才能得到一個MouseListenerClass畫上一個JPanel是不通過的JPanel到mouseListenerClass做就可以操作一個獨立的JFrame類的角色真是令人沮喪。

我似乎工作的唯一方法是創建一個名爲MouseState的Enum,當鼠標事件MousePressed被觸發時,它將靜態Enum mouseStatus設置爲按下,然後JPanel paintComponent方法檢查Enum mouseStatus並繪製如果theres a按。

這似乎是錯誤的方式。

還有別的辦法嗎?

更新,以反映西里爾註釋: -

感謝@Cyrille我不得不用鑄造修改你的代碼,但前提仍然有效。 「 公共無效的mousePressed(的MouseEvent E){

PaintPanel p=(PaintPanel) getTargetPanel(); 
    p.setMousePressed(true); 
    p.setMouseCoords(e.getPoint()); 
} 


public void mouseReleased(MouseEvent e) { 
    PaintPanel p=(PaintPanel) getTargetPanel(); 
    p.setMousePressed(false); 

} 

public JPanel getTargetPanel() { 
    return targetPanel; 
}' 

回答

1

您不必使用任何類型的靜態變量。您應該創建JPanel的子類來處理噴漆,並提供此一等級方法爲聽衆與它通信:

public class MyPanel extends JPanel { 

    // status used for drawing, can be anything you want, but let's say you need to know if the mouse is pressed. 
    private boolean isMousePressed; 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     // do your stuff here, using isMousePressed 
    } 

    public void setMousePressed(boolean pressed) { 
     isMousePressed= pressed; 
    } 
} 

那麼你的鼠標監聽必須有一個MyPanel實例的引用和使用權方法與之通信。

public class PaintingMouseListener implements MouseListener { 

    private final JPanel targetPanel; 


    public PaintingMouseListener(JPanel targetPanel) { 
     this.targetPanel = targetPanel; 
    } 


    @Override 
    public void mousePressed(MouseEvent e) { 
     targetPanel.setMousePressed(true); 

    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     targetPanel.setMousePressed(false); 
    } 

    // other methods of the listener 
} 

然後,您創建鼠標偵聽器並引用您的面板。

MyPanel targetPanel = new MyPanel(); 
    // assign the mouse listener to whatever component needs it. 
    component.addMouseListener(new PaintingMouseListener(targetPanel)); 

這類似於一個MVC溶液,不同之處在於它把模型(可變isMousePressed)和視圖(MyPanel)在一起。對於這樣一個簡單的東西,將它們放在一起會更簡單,但隨着事情變得更加複雜,最好將它們分開,並將模型放在類中。

+0

謝謝@Cyrille我不得不通過使用cast來修改你的代碼,但前提仍然有效。 'code' \t公共無效的mousePressed(的MouseEvent E){ \t \t \t \t \t \t PaintPanel P =(PaintPanel)getTargetPanel(); \t \t p.setMousePressed(true); \t \t p.setMouseCoords(e.getPoint()); \t} \t \t 公共無效的mouseReleased(的MouseEvent E){ \t \t PaintPanel P =(PaintPanel)getTargetPanel(); \t \t p.setMousePressed(false); \t} \t公共的JPanel getTargetPanel(){ \t \t返回targetPanel; \t}' – user2054388

2

您的鼠標監聽不應該借鑑的JPanel。相反,你應該使用MVC(Model-View-Controll)模式。例如,您將設置3個類:面板,偵聽器和用於保存數據的類(模型類)。當監聽器被觸發時,它應該編輯模型。然後模型可以通知面板某些變化,面板可以檢查模型中的數據並繪製適當的像素。有關更多信息,請參見http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

順便說一下:這是大多數標準Swing組件工作的方式。只有非常簡單的(JPanel,JTextField等)不允許使用,並且基於這些構建一個複雜的組件,您應該使用MVC

+1

'JPanel'沒有內在模型,但'JTextField'有一個'Document',正如這裏討論的(http://www.oracle.com/technetwork/java/architecture-142923.html#separable)。另請參閱此相關的[答案](http://stackoverflow.com/a/3072979/230513)。 – trashgod