2012-07-24 90 views
0

以下是我正在構建的應用程序https://github.com/chrisbramm/LastFM-History-GraphJava updateUI只能工作一次

下面是src/lastfmhistoryclasses控制器類的一部分。當創建OutputGUIView時,它創建三個組件,一個JPanel graphPanel,將其添加到JScrollPane graphScrollPanel和另一個JPanel autocompletePanel。這些都被添加到JFrame OutputGUIView。下面的聽衆,然後改變graphPanel首選大小並在第一時間按下按鈕的UI更新,以顯示該graphPanel規模增加和graphScrollPanel滾動條有變化的。

但是現在,如果你按下另一個按鈕,首選大小的變化,但用戶界面不會更新,它會如果更改窗口尺寸爲讓說,它最大限度地做到這一點。

class Zoom2000 implements ActionListener{ 
    public void actionPerformed(ActionEvent e){ 
     outputGUIView.graphPanel.setPreferredSize(new Dimension(screenWidth, 2000)); 
     outputGUIView.graphScrollPanel.updateUI(); 

    } 
} 
class ZoomDefault implements ActionListener{ 
    public void actionPerformed(ActionEvent e){ 
     outputGUIView.graphPanel.setPreferredSize(new Dimension(screenWidth, screenHeight)); 
     outputGUIView.graphScrollPanel.updateUI(); 


    } 
} 
class Zoom6000 implements ActionListener{ 
    public void actionPerformed(ActionEvent e){ 
     outputGUIView.graphPanel.setPreferredSize(new Dimension(screenWidth, 6000)); 
     outputGUIView.graphScrollPanel.updateUI(); 

    } 
} 

我已經嘗試不同的東西上的各種組件,以及諸如invalidate/validate/revalidate(和重繪)所有,而graphPanel只是坐在那裏,只有當您更改窗口尺寸重新繪製。

任何想法我做錯了什麼?

EDIT UPDATE: 這裏是GraphPanel類:

package lastfmhistoryguis; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.geom.Line2D; 
import java.awt.geom.Rectangle2D; 
import javax.swing.*; 

import de.umass.lastfm.*; 
import lastfmhistoryclasses.*; 

SuppressWarnings("serial") 
public class GraphPanel extends JPanel { 

private LastFMHistory graphData; 
private int graphHeight; 
private int graphWidth; 
private int zoom; 
private final int PAD = 20; 

public GraphPanel(LastFMHistory model, int zoom){ 
    this.graphData = model; 
    if (zoom != 1){ 
     this.zoom = zoom; 
    }else{ 
     this.zoom = 1; 
     System.out.println("getHeight() returning:" + getHeight()); 
    } 
    System.out.println("Width" + getWidth() + "Height" + getHeight()); 

} 

protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    System.out.println("Drawing"); 
    Graphics2D graph = (Graphics2D) g; 

    if (graphData == null) { 
     System.err.println("No data found"); 
    } else { 
     System.out.println("paintComponent Width" + getWidth() + "Height" + getHeight()); 
     graphWidth = getWidth() - 5 * PAD; 
     //graphHeight = getHeight() - 2 * PAD; 
     graphHeight = 6000 - 2* PAD; 
     System.out.println(graphWidth + ", " + graphHeight); 

     int x0 = graphWidth + PAD; 
     graph.draw(new Rectangle2D.Double(PAD, PAD, graphWidth, graphHeight)); 
     double xInc = (double) (graphWidth)/(graphData.dayMax); 
     double secondHeight = (double) (graphHeight)/86400; 

     for (int i = 0; i <= 86400; i++) { 
      if (i % 3600 == 0) { 
       graph.draw(new Line2D.Double(x0, (i * secondHeight) + PAD, 
         x0 + 10, (i * secondHeight) + PAD)); 
       String hour = Integer.toString(i/3600); 
       graph.drawString(hour, x0 + 15, 
         (int) ((i * secondHeight) + PAD)); 
      } 
     } 

     for (Track t : graphData.history) { 
      if (t.getPlayedWhen() != null) { 

       Color color = t.getColour(); 

       int duration = t.getDuration(); 
       int day = Math.abs(t.getDay()); 
       double dayOrigin = x0 - ((day + 1) * xInc); 
       double timeOrigin = t.getGraphHeight() * secondHeight + PAD; 
       double trackHeight = duration * secondHeight; 
       graph.setColor(color); 
       // System.out.println("PLOTTING TRACK, " + day + ", " + 
       // dayOrigin + ", " + t.getGraphHeight() + ", " + timeOrigin 
       // + ", " + trackHeight); 
       // graph.draw(new Rectangle2D.Double(dayOrigin, timeOrigin, 
       // xInc, trackHeight)); 
       graph.fillRect((int) dayOrigin, (int) timeOrigin, 
         (int) xInc, (int) trackHeight); 
      } 

     } 

     for (int i = 0; i < graphData.dayMax;){ 
      graph.draw(new Line2D.Double(x0 - i * xInc, PAD, x0 - i * xInc, graphHeight + PAD)); 
      i = i + 7; 
     } 

    } 
} 
public void zoom(int zoom){ 
    this.zoom = zoom; 
    repaint(); 
} 

}然後

它創建在其上大勾畫輪廓繪製矩形Graphics2D對象和每個軌道矩形被繪製到某處此Graphics2D圖形對象。現在我已經刪除了使用了setPreferredSize as recommended here,但現在我有,當我手動設置GraphPanel到graphHeight的高度的問題說6000,graphScrollPanel並沒有意識到graphPanel它含有實際上是更大的,因爲所有graphHeight是做的是繪製一個〜6000px高的矩形。所以在這種情況下,我應該使用setPreferredSize還是有另一種方法來設置Graphics2D對象的大小?

+0

我多一點信息,就不會誤入歧途。像組件佈局(什麼是佈局)以及使用的佈局管理器 – MadProgrammer 2012-07-24 23:40:07

+0

聽起來像對prefSize屬性有一個稍微不正確的期望:它是由佈局管理器使用的大小提示 - 不是自動奇蹟觸發的手段像「zoom」這樣的應用程序屬性:換句話說:實現自定義面板以支持zoom屬性並通知視圖層次結構需要重新佈局 – kleopatra 2012-07-25 10:00:55

回答

4

不要叫updateUI這是關係到用戶界面外觀和感覺API並沒有什麼與重繪。

什麼佈局管理器你嘗試/使用?

調用invalidate(),repaint()應該會影響父容器佈局管理器,並導致它們相應地重新佈局組件,但是您需要記住,佈局管理器僅使用min/max/pref大小信息作爲指南。

從你的例子我最好的客人是你應該嘗試調用其中

outputGUIView.graphPanel.invalidate(); 
outputGUIView.graphPanel.repaint(); 

和/或

outputGUIView.invalidate(); 
outputGUIView.repaint(); 

滾動窗格調用Invalidate很可能不會實現很多因爲視口負責佈局內容,而不是滾動窗格。

如果你真的絕望了,你可以嘗試

outputGUIView.graphScrollPanel.getViewport().invalidate(); 
outputGUIView.graphScrollPanel.getViewport().repaint();