Как очистить jPanel перед следующим рисованием

Я искал в Интернете, и, предположительно, есть много способов очистить 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); */

}

Какой метод мне следует вызвать и где я должен его разместить, чтобы каждый раз, когда я нажимаю кнопку для рисования нового графика, он очищает панель перед рисованием

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
2 037
1

Ответы 1

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);
}    

Извините, я не понимаю, что делаю не так, не могли бы вы пояснить, что нужно / нужно изменить?

VinceSmithangura 07.08.2018 07:43

Не звоните paintComponent напрямую; Не вызывайте getGraphics, просто вызовите repaint для компонента, который вы хотите обновить. Не делайте предположений о том, как, по вашему мнению, работает API, прочтите связанную документацию и узнайте, как работает API / система и что вам нужно делать для работы с ней.

MadProgrammer 07.08.2018 07:47

Думаю, ваш ответ о вызове методов убрать все() и перекрасить () должен исправить его проблему :)

Kebab Programmer 07.08.2018 15:31

@ProgrammingNewb Я не знаю, здесь недостаточно контекста, чтобы дать однозначный ответ, и весь мой ответ - это всего лишь набор догадок

MadProgrammer 07.08.2018 21:36

Другие вопросы по теме