2012-02-27 165 views
1

我需要一個聽衆,如果靜態布爾值已經改變,這樣我可以重繪一幀上的組件,將不斷檢查。有人能幫助我我真的不太瞭解聽衆,並且沒有和他們一起工作太多嗎?幫助將不勝感激。布爾值變化監聽的Java

編輯(更清晰):我有兩個單獨的類,其中在類是「主幀」第二類是一個JLabel的擴展並實現MouseListner用於「可點擊照片」。 「主幀」創建照片並當光被點擊「主幀」應該畫在面板上的照片的描述的實例。這是「主框架」

MenuBar menuBar; 
static AnnotationVisual a; 
Picture pic; 
Picture pic2; 

GalleryScreen(int rows, int columns){ 
    this.setBorder(BorderFactory.createEmptyBorder(500,500,0,0)); 
    pic = new Picture("pic1", "Z:/My Documents/Downloads/Ball.jpg", new Coordinate(0,0)); 
    pic2 = new Picture("pic2", "Z:/My Documents/Downloads/hoop.jpg" , new Coordinate(1,0)); 

    this.add(pic); 
    this.add(pic2); 
    a = new AnnotationVisual(); 
} 

public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    if(a.shouldAnnotate()){ 
     FontMetrics size= g.getFontMetrics(); 
     if(getWidth()>=(a.dispX()+size.stringWidth(a.annotationText()))){ 
      g.setColor(Color.white); 
      g.fillRect(a.dispX()-3,a.dispY()-12,size.stringWidth(a.annotationText())+5,15); 
      g.setColor(Color.black); 
      g.drawRect(a.dispX()-3,a.dispY()-12,size.stringWidth(a.annotationText())+5,15); 
      g.drawString(a.annotationText(), a.dispX(), a.dispY()); 
     }else{ 
      String sub=""; 
      int letters=0; 
      g.setColor(Color.white); 
      g.fillRect(a.dispX()-3,a.dispY()-12,getWidth(),15); 
      g.setColor(Color.black); 

      for(int i=0;i<a.annotationText().length();i++){ 
       if(a.dispX()+letters+16<=getWidth()){ 
        sub+=a.annotationText().substring(i,i+1); 
        letters=size.stringWidth(sub); 
       }else{ 
        sub=sub+"..."; 
        i=a.annotationText().length(); 
       } 
      } 
      g.drawRect(a.dispX()-3,a.dispY()-12,size.stringWidth(sub)+3,15); 
      g.drawString(sub,a.dispX(),a.dispY()); 
     } 
    } 
} 

public static AnnotationVisual getA() 
{ 
    return a; 
} 

這是「可點擊圖片」

import java.awt.Dimension; 
import java.awt.Toolkit; 
import java.awt.event.*; 
import javax.swing.*; 

public class Picture extends JLabel implements MouseListener 
{ 
    String myAnnotation; 
    String filePath; 
    Coordinate imageCoord; 
    private boolean wasDoubleClick; 
    private Timer timer; 
    EditAnnotation newEdit; 
    AnnotationVisual newVisual; 

    public Picture(String annotation, String filePath, Coordinate coord) 
    { 
     super(new ImageIcon(filePath)); 
     this.addMouseListener(this); 
     myAnnotation=annotation; 
     this.filePath = filePath; 
     imageCoord = coord; 
     newEdit = new EditAnnotation(annotation); 
     newVisual = new AnnotationVisual(); 
    } 
    public Picture(String filePath) 
    { 
     super(new ImageIcon(filePath)); 
     this.addMouseListener(this); 
     this.filePath = filePath; 
     newEdit = new EditAnnotation(); 
     newVisual = new AnnotationVisual(); 
    } 
    public String getAnnotation() 
    { 
     return myAnnotation; 
    } 
    public AnnotationVisual getAnnotationVisual() 
    { 
     return newVisual; 
    } 
    public void setAnnotation(String annotation) 
    { 
     myAnnotation=annotation; 
    } 
    public Coordinate getCoordinate() 
    { 
     return imageCoord; 
    } 
    public void setCoordinate(Coordinate coord) 
    { 
     imageCoord = coord; 
    } 
    public Dimension getSize() 
    { 
     return new Dimension(super.getIcon().getIconWidth(), super.getIcon().getIconHeight()); 
    } 
    public void mouseClicked(MouseEvent e) 
    { 
     final int scrLocX = (int)e.getLocationOnScreen().getX(); 
     final int scrLocY = (int)e.getLocationOnScreen().getY(); 

     if (e.getClickCount() == 2) 
     { 
      wasDoubleClick = true; 
     } 
     else if(e.getClickCount() == 1) 
     { 
      Integer timerinterval = (Integer) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval"); 

      timer = new Timer(timerinterval.intValue(), new ActionListener() 
      { 
       public void actionPerformed(ActionEvent evt) 
       { 
        if (wasDoubleClick) 
        { 
         GalleryScreen.getA().deleteAnnotation(); 
         myAnnotation = newEdit.getAnnotation(); 
         newEdit.show(myAnnotation); 
         wasDoubleClick = false; 
        } 
        else 
        { 
         GalleryScreen.getA().deleteAnnotation(); 
         GalleryScreen.getA().showAnnotation(scrLocX, scrLocY , myAnnotation); 
        } 
       } 
      }); 
      timer.setRepeats(false); 
      timer.start(); 
     } 
    } 
    public void mouseEntered(MouseEvent e) 
    { 

    } 
    public void mouseExited(MouseEvent e) 
    { 

    } 
    public void mousePressed(MouseEvent e) 
    { 

    } 
    public void mouseReleased(MouseEvent e) 
    { 

    } 
} 

AnnotationVisual是應該彈出一個點擊時

+0

腫塊。需要幫助,請! – 2012-02-27 22:07:26

回答

1

您不會在Java中的字段上設置偵聽器,而是將其設置爲屬性。雖然性能(根據JavaBeans規範)即可領域,他們通常做的方法對(一個消氣,一個二傳手;後者不需要只讀域)的,可以讓你在鉤額外的邏輯是在訪問屬性時調用。如觸發一個監聽器回調來表示值已經改變。 (你可以使用一個線程來監視這種事情,但這真的很糟糕,而且很容易出錯。)浪費太多了。

但有一點需要注意:你不知道該線程的值是多少被修改了。調用回擺時要小心......

+0

我想到了線程,但這太複雜了爲了我。你可以看看附加的代碼,因爲setter和getters不使用我的代碼。 – 2012-02-27 22:06:30

4

你可能會更好過製造的東西boolean private,並且只允許通過setter方法更改它。 setter方法在調用時應該重新繪製組件。

+0

對不起,我只是添加了代碼,也許它使它更清晰。因爲我是第一次在一個組中進行編程,因此值的發送和接收不太好,所以我不能使用你的方法來做到這一點,但這很有意義 – 2012-02-27 22:02:03

3

聽衆的點是反轉的邏輯。你不會經常檢查一個值是否改變。您在更改值時通知監聽者。

所以,與其Foo.bar = 5,你調用Foo.setBar(5),其中除分配,你叫barListener.valueChanged(value)

一點題外話 - 避免在靜態變量存儲狀態。

+0

對不起,我只是添加了代碼,也許它使它更清晰。因爲我是第一次編程在一個組中,所以值的發送和接收都不是很好,所以我不能用你的方法去做,但這很有意義 – 2012-02-27 22:03:41