2013-10-07 37 views
1

我正在尝试构建一个显示随机形状和随机文本的程序。这是我的类中扩展JPanel的代码。为什么repaint()会导致与调整窗口大小不同导致不同的结果? (Java)

@Override 
protected void paintComponent(Graphics g) { 
    // draw all shapes   
    super.paintComponent(g);  // clears the background  

    this.add(new JLabel(new RandomText().getRandomSentence())); 
    for (RandomShape shape : shapes) { 
     shape.draw(g); 
    }   
} 

我使用JPanel而不是g.drawString()来在将来显示HTML代码。我还有一个通过调用repaint()方法“重新生成”窗口的按钮。但是,当我按下再生按钮,因此调用repaint()方法时,形状会发生变化(就像它们应该那样),但是文本不会。我觉得更奇怪的是,当我调整窗口的大小时,新的标签会不断添加到我的面板中(像他们应该看到的随机文本)。

是否super.paintCompnent(g)不清楚添加到面板的组件?如果是这样,为什么调用repaint()我自己不会添加额外的标签,如调整窗口大小呢?

回答

2

调整窗口大小还会强制调用validate(),它会重新放置面板上的组件 - 只是重新绘制不会。

但是,在您的绘画方法中,您每次都添加一个新的JLabel,而不是删除任何,这几乎肯定不是您想要做的。您应该将JLabel跟踪到一个单独的变量中,并且在重新绘制(最好)时更改它的位置,或者在添加新的变量之前将其删除。

+1

好的,如果我正确理解了你,如果我自己调用repaint(),那么组件仍然会添加到JPanel中,但是我不能看到它们,因为它们没有通过validate()方法进行布局? super.paintComponent(g)实际上清除了包含exrta JLabel的窗口,但是每次JPanel重绘时它们都会自动重新绘制,因为它们已经“永久”添加到JPanel中了? (注意:我知道添加paintcomponent方法内的组件是错误的,我只是好奇它显示的行为) – Henk

1

发生这种情况是因为您不断向JPanel添加新的JLabel。 跟踪您的JLabel并更改它的文本而不是添加新的JLabel。

2

这在每次重绘增加了一个新的标签,面板:

this.add(new JLabel(new RandomText().getRandomSentence())); 

相反,你应该一个标签一次添加到面板上,也许在你的类的构造函数。然后setText(aRandomSentence)为它,当按下按钮时。做不是修改组件paintComponent()

2

当调用super.paintComponent(..);时,它将清除图形元素。但它不会更改已添加到其中的对象。每次调用repaint时,都会在面板上添加一个新标签。

当您调用repaint();你自己,它不保证调用所有组件的paintComponent。但是当你调整它的大小时,因为一切都会有所不同。

相关问题