2013-11-25 31 views
1

我有一個帶paintComponent()的JLabel覆蓋。我希望它被強制調用,因爲更新我的標籤UI的代碼就是這個事件。我可以如何強制其調用和更新UI? (順便說一下,重繪不工作!)如何強制調用paintComponent?

這裏是我的代碼:

BufferedImage background; 
String Uri; 

public CustomClockLabel(String Uri){ 
    init(Uri); 
    this.Uri = Uri; 
} 

public void init(String Uri){ 
    try { 
     URL inp = CustomClockLabel.class.getResource(Uri); 
     background = ImageIO.read(inp); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

@Override 
protected void paintComponent(Graphics g){ 
    Graphics2D g2 = (Graphics2D) g.create(); 
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

    if(background != null){ 
     g2.drawImage(background, 0, 0,getWidth(),getHeight(), this); 
    } 
    g2.dispose(); 
    super.paintComponent(g); 
} 

這裏是更新標籤的代碼,它被遞歸調用:

lblHour1 = new CustomClockLabel("/icons/noa_en/"+Hour.charAt(0)+".png"); 
lblHour1.repaint(); 
lblHour2 = new CustomClockLabel("/icons/noa_en/"+Hour.charAt(1)+".png"); 
lblHour2.repaint(); 
lblMin1 = new CustomClockLabel("/icons/noa_en/"+Minute.charAt(0)+".png"); 
lblMin1.repaint(); 
lblMin2 = new CustomClockLabel("/icons/noa_en/"+Minute.charAt(1)+".png"); 
lblMin1.repaint(); 

回答

2

你可能是假象,創造新的標籤將更新有什麼屏幕,這樣對下...

lblHour1 = new CustomClockLabel("/icons/noa_en/"+Hour.charAt(0)+".png"); 
lblHour2 = new CustomClockLabel("/icons/noa_en/"+Hour.charAt(1)+".png"); 
lblMin1 = new CustomClockLabel("/icons/noa_en/"+Minute.charAt(0)+".png"); 
lblMin2 = new CustomClockLabel("/icons/noa_en/"+Minute.charAt(1)+".png"); 

會改變變量的引用,所以它們將不再是與添加到屏幕中的變量相同的變量。

假設上面的變量已經被添加到屏幕上,您可以簡單地使用類似...

lblHour1.init(new ImageIcon("/icons/noa_en/"+Hour.charAt(0)+".png")); 
lblHour2.init(new ImageIcon("/icons/noa_en/"+Hour.charAt(1)+".png")); 
lblMin1.init(new ImageIcon("/icons/noa_en/"+Minute.charAt(0)+".png")); 
lblMin2.init(new ImageIcon("/icons/noa_en/"+Minute.charAt(1)+".png")); 
revalidate(); 
repaint(); 

如果失敗了,你應該嘗試設置一個標籤邊框的屬性,所以你可以看到,如果它實際上被添加到屏幕上。

更新

一些實驗用的小東西,你的代碼,你已提供,這裏有更多的建議後...

  1. 正如已經被提及,請確保您所呼叫super.paintComponent首先,作爲這種方法的一個工作是清除圖形準備繪畫...
  2. 確保你提供一個合適的尺寸提示給組件,所以佈局經理有一些想法,你有多大mig ht喜歡組件。這確保了組件沒有尺寸0x0

下面的例子很簡單,但需要你提供的(什麼小)的代碼,並建立從它可運行的例子...

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.URL; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class PaintComponentTest { 

    public static void main(String[] args) { 
     new PaintComponentTest(); 
    } 

    private int time = 0; 

    public PaintComponentTest() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       final CustomClockLabel counter = new CustomClockLabel("/icons/0.png"); 
       Timer timer = new Timer(1000, new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         time++; 
         if (time > 9) { 
          time = 0; 
         } 
         counter.init("/icons/" + Integer.toString(time) + ".png"); 
         counter.repaint(); 
        } 
       }); 
       timer.start(); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(counter); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class CustomClockLabel extends JPanel { 

     BufferedImage background; 
     String Uri; 

     public CustomClockLabel(String Uri) { 
      init(Uri); 
      this.Uri = Uri; 
     } 

     public void init(String Uri) { 
      try { 
       URL inp = getClass().getResource(Uri); 
       background = ImageIO.read(inp); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(100, 100); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2 = (Graphics2D) g.create(); 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

      if (background != null) { 
       g2.drawImage(background, 0, 0, getWidth(), getHeight(), this); 
      } 
      g2.dispose(); 
     } 
    } 

} 
2

上調用repaint()有問題的組件將強制它再次繪製。

您的問題似乎沒有重新繪製,因爲您實際上正在更改面板上的標籤。確保您刪除舊標籤並添加新標籤,並致電revalidate()。 (您發佈的代碼看起來像只是更新標籤引用,並未實際更改它們在面板上。)

總的來說,設計可以通過使您的CustomClockLabel類帶入一個參數來改變圖像因此可以讓你調用repaint()。

+0

沒有它不,嘗試它沒有工作 – armin

+0

多數民衆贊成在工作.... – mKorbel

+0

你如何嘗試'repait()'你的標籤?它必須爲你工作。 – alex2410

2
lblHour1 = new CustomClockLabel("/icons/noa_en/"+Hour.charAt(0)+".png"); 

上面的代碼不會做任何事情。一切都是創建一個新的組件。但該組件不會添加到GUI中,因此顯然不會重新繪製。

你的課沒有什麼會導致它需要重新粉刷,所以你的問題沒有意義。你有一個設計問題。我沒有看到任何理由來創建自定義標籤。

如果您想更改圖像,那麼只需使用帶有圖標的標準JLabel即可。然後要更改圖像,只需使用setIcon(...)方法,標籤將自動重新繪製。

+0

setIcon不是一個選項,因爲設計選擇made.also看到我對代碼 – armin

+0

@armin所做的更改什麼設計選擇?爲什麼你不能「重新思考」他們...... – MadProgrammer

+0

@armin,你看過我的回答嗎?我告訴過你問題是什麼。 '不要創建一個新組件。這是一個資源浪費,根據你的代碼,你已經有一個參考標籤。相反,您應該更新現有組件的屬性。所以你需要一個像「changeImage(...)'這樣的方法,在該方法內部保存圖像,然後在方法內部調用repaint(),外部代碼不應該調用repaint()。請對你的設計選擇發表評論,但MadProgramer打我吧。 – camickr

2

(!順便說一下,重繪不工作)

如果不是,那麼我可以懷疑的唯一的事情,故障是在你的畫順序:你在哪裏打電話super.paintComponent(g);在您繪製圖像後。如果您的標籤不透明且具有背景顏色,則不會看到圖像,因爲後面的繪畫super.paintComponent(g)將繪製在上一幅繪畫上方。

嘗試改變順序:

super.paintComponent(g); 

Graphics2D g2 = (Graphics2D) g.create(); 
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

if(background != null){ 
    g2.drawImage(background, 0, 0,getWidth(),getHeight(), this); 
} 
g2.dispose(); 
+0

+1好起來... – MadProgrammer

+0

好久不見。你好嗎? – Sage

+0

假期.....;) – MadProgrammer