为什么repaint()导致不同的结果导致与调整窗口大小不同的结果? (JAVA)

时间:2013-10-07 12:51:59

标签: java swing

我正在尝试构建一个显示随机形状和随机文本的程序。这是我的类中的代码,它扩展了JPanel。

@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()自己不会添加额外的标签,比如调整窗口大小呢?

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

这会在每次重绘时向面板添加一个新标签:

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

相反,您应该在面板中添加一个标签一次,也许在您的类的构造函数中。按下按钮后再setText(aRandomSentence)修改paintComponent()中的组件。

答案 2 :(得分:2)

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

当你调用repaint()时;你自己,不需要调用所有组件的paintComponent。但是当你调整大小时,由于一切都会有所不同。

答案 3 :(得分:1)

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