如何在下一次绘图前清除jPanel



我在网上搜索过,在开始新的绘图之前,应该有很多方法可以清除jPanel。然而,在尝试了所有方法之后,我仍然没有成功——结果要么是面板根本不清楚,下一个绘图只是与初始绘图重叠,要么是我的paintComponent()根本无法执行。

问题图像(重叠(

从GUI执行绘图的代码:

private void BTCGraphActionPerformed(java.awt.event.ActionEvent evt) {                                         
Graphics2D gfx = (Graphics2D) jPanel2.getGraphics();
WebScraper WSBTC = new WebScraper();
float[] HBTC = WSBTC.HScrapeBTC();
Graph graphExecute = new Graph();
graphExecute.CurrentValues(HBTC);
graphExecute.IndexLarge(HBTC);
graphExecute.IndexSmall(HBTC);
graphExecute.Plotter(HBTC);
graphExecute.paintComponent(gfx);
}                                        
private void LTCGraphActionPerformed(java.awt.event.ActionEvent evt) {                                         
Graphics2D gfx = (Graphics2D) jPanel2.getGraphics();
WebScraper WSLTC = new WebScraper();
float[] HLTC = WSLTC.HScrapeLTC();
Graph graphExecute = new Graph();
graphExecute.CurrentValues(HLTC);
graphExecute.IndexLarge(HLTC);
graphExecute.IndexSmall(HLTC);
graphExecute.Plotter(HLTC);
graphExecute.paintComponent(gfx);
}                                        
private void ETHGraphActionPerformed(java.awt.event.ActionEvent evt) {                                         
Graphics2D gfx = (Graphics2D) jPanel2.getGraphics();
WebScraper WSETH = new WebScraper();
float[] HETH = WSETH.HScrapeETH();
Graph graphExecute = new Graph();
graphExecute.CurrentValues(HETH);
graphExecute.IndexLarge(HETH);
graphExecute.IndexSmall(HETH);
graphExecute.Plotter(HETH);
graphExecute.paintComponent(gfx);
}                                        

paintComponent():的代码

protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
int DotSize = 10;
int width = g2.getFontMetrics().stringWidth("Today");
int middle = width / 2;
g2.setColor(Color.BLACK);
/* g2.drawLine(10, 10, 10, 410); //Frame Boundaries
g2.drawLine(410, 10, 10, 10); //Frame Boundaries
g2.drawLine(410, 10, 410, 410); //Frame Boundaries
g2.drawLine(410, 410, 10, 410); //Frame Boundaries */
//Axis
g2.drawLine(30, 30, 30, 370);
g2.drawLine(370, 370, 30, 370);
//Points & Connections
PlotPoints(g2, 98, DistanceDay1, DotSize);
g2.drawLine(98, DistanceDay1, 166, DistanceDay2);
PlotPoints(g2, 166, DistanceDay2, DotSize);
g2.drawLine(166, DistanceDay2, 234, DistanceDay3);
PlotPoints(g2, 234, DistanceDay3, DotSize);
g2.drawLine(234, DistanceDay3, 302, DistanceDay4);
PlotPoints(g2, 302, DistanceDay4, DotSize);
g2.drawLine(302, DistanceDay4, 370, DistanceDay5);
PlotPoints(g2, 370, DistanceDay5, DotSize);
//Labels
g2.drawString("Today", 370 - middle, 390);
/*  g2.drawString("Test", 98 - middle, 40);
g2.drawString("Test", 146, 25); */
}

我应该调用什么方法,我必须把它放在哪里,这样每次我按下按钮绘制新图形时,它都会在绘制之前清除面板

我在网上搜索过,据说有很多方法可以在开始新绘图之前清除jPanel,但

是的,不要做你正在做的事情。永远不需要手动调用paintComponent,也不应该调用getGraphics,除了能够返回null之外,这不是自定义绘制的方式。

绘制应仅绘制组件的当前状态。所以,如果你想";清除";面板,明确它用来决定应该画什么和如何画的状态。

通过对要更新的组件调用repaint,可以触发执行新绘制过程的请求。作为绘制过程的一部分,组件的Graphics上下文将是";制备";,通常通过在其上绘制组件的背景色。

首先看一下AWT和Swing 中的自定义绘画和绘画

已更新

一个可运行的例子会让这变得容易得多。让我们从…开始。。。

private void LTCGraphActionPerformed(java.awt.event.ActionEvent evt) {                                         
Graphics2D gfx = (Graphics2D) jPanel2.getGraphics();
WebScraper WSLTC = new WebScraper();
float[] HLTC = WSLTC.HScrapeLTC();
Graph graphExecute = new Graph();
graphExecute.CurrentValues(HLTC);
graphExecute.IndexLarge(HLTC);
graphExecute.IndexSmall(HLTC);
graphExecute.Plotter(HLTC);
graphExecute.paintComponent(gfx);
}    

Graphics2D gfx = (Graphics2D) jPanel2.getGraphics();是个坏主意。getGraphics可以返回null,并且只提供组件的快照。在下一个绘制循环中,它将被更新。

graphExecute.paintComponent(gfx);是个坏主意,没有任何理由应该直接调用任何paint方法。绘制系统会告诉您何时需要绘制组件,以及需要在什么上下文中使用。

然后。。。

Graph graphExecute = new Graph();
graphExecute.CurrentValues(HLTC);
graphExecute.IndexLarge(HLTC);
graphExecute.IndexSmall(HLTC);
graphExecute.Plotter(HLTC);
graphExecute.paintComponent(gfx);

等等,什么!?你创建了一个组件Graph,你给它播种了一些信息,然后你手动绘制它…

好吧,假设它是某种JComponent,为什么不把它添加到当前的UI 中呢

jPanel2.removeAll();
jPanel2.add(graphExecute);
jPanel2.invalidate();
jPanel2.repaint();

如果Graph不是某种JComponent,那么我们就有一个更大的问题,因为你需要把它传给一个可以画它的东西……也许是。。。

public class RenderPane extends JPanel {

private Graph graph;

public RenderPane() {
}
public void setGraph(Graph graph) {
this.graph = graph;
repaint();
}
public Graph getGraph() {
return graph;
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graph grap = getGraph();
if (grap != null) {
grap.paintComponent(g);
}
}

}

然后你也许可以做一些事情,比如。。。

private void LTCGraphActionPerformed(java.awt.event.ActionEvent evt) {                                         
jPanel2.removeAll();
WebScraper WSLTC = new WebScraper();
float[] HLTC = WSLTC.HScrapeLTC();
Graph graphExecute = new Graph();
graphExecute.CurrentValues(HLTC);
graphExecute.IndexLarge(HLTC);
graphExecute.IndexSmall(HLTC);
graphExecute.Plotter(HLTC);
RenderPane renderer = new RenderPane();
renderer.setGraph(graphExecute.Plotter);
jPanel.add(renderer);
}    

最新更新