我正在尝试构建一个显示随机形状和随机文本的程序。这是我的类中的代码,它扩展了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()自己不会添加额外的标签,比如调整窗口大小呢?
答案 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。