Я искал в Интернете, и, предположительно, есть много способов очистить jPanel перед началом нового рисунка, однако после всех попыток у меня все еще нет успеха - результаты либо панель не очищается вообще, а следующий рисунок просто перекрывается исходный или мой paintComponent()
просто не сработает.
Изображение проблемы (перекрытие)
Код для выполнения рисования из графического интерфейса:
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); */
}
Какой метод мне следует вызвать и где я должен его разместить, чтобы каждый раз, когда я нажимаю кнопку для рисования нового графика, он очищает панель перед рисованием
I've searched up online and there are supposedly many ways to clear a jPanel before starting a new drawing however
Да, не делай того, что делаешь. НИКОГДА нет необходимости вызывать paintComponent
вручную, и вы НИКОГДА не должны вызывать getGraphics
, кроме возможности вернуть null
, это НЕ то, как следует выполнять индивидуальную раскраску.
Paint должен рисовать только текущее состояние компонента. Итак, если вы хотите «очистить» панель, очистите состояние, которое она использует, чтобы решить, что и как она должна быть окрашена.
Вы можете инициировать запрос на выполнение нового прохода отрисовки, вызвав 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
, почему бы просто не добавить его в текущий пользовательский интерфейс?
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);
}
Не звоните paintComponent
напрямую; Не вызывайте getGraphics
, просто вызовите repaint
для компонента, который вы хотите обновить. Не делайте предположений о том, как, по вашему мнению, работает API, прочтите связанную документацию и узнайте, как работает API / система и что вам нужно делать для работы с ней.
Думаю, ваш ответ о вызове методов убрать все() и перекрасить () должен исправить его проблему :)
@ProgrammingNewb Я не знаю, здесь недостаточно контекста, чтобы дать однозначный ответ, и весь мой ответ - это всего лишь набор догадок
Извините, я не понимаю, что делаю не так, не могли бы вы пояснить, что нужно / нужно изменить?