2012-07-24 98 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();