Прокрутка JPanel очищает его графику

Я новичок в программировании на Java, и у меня есть проблема. Я использую JPanel в JScrollPane, все они содержатся в JFrame.

Я использую метод paintComponent() для рисования определенной кривой, и это сделано правильно. Проблема в том, что когда я прокручиваю свою панель, я вижу, что изображение очищается. Я искал и узнал о мерцании, но я еще не совсем уверен, что это значит и является ли это проблемой, с которой я столкнулся. Я также заметил, что когда вызывается перерисовка, изображение очищается.

Вот мой код, может ли кто-нибудь сообщить мне, если я делаю что-то не так?

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.QuadCurve2D;
import javax.swing.JFrame;
import java.lang.Math;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.LineBorder;

public class DrawCurve extends JPanel {

    class MyAdjustmentListener implements AdjustmentListener {

        public MyAdjustmentListener() {
        }

        public void adjustmentValueChanged(AdjustmentEvent evt) {
            setFocusable(true);
            jScroll.setFocusable(false);
            //repaint();
            //revalidate();
        }
    }

    Graphics gr;
    Stroke drawingStroke = new BasicStroke(0.5f);
    double x;
    int y = 0;
    static String seq = "AAGTCGACCTGTAGCTAGATCGGATCATAGCTCGATCCAGAGATT";
    QuadCurve2D curve;
    char s;
    int a = 0;
    int c = 0;
    int g = 0;
    int t = 0;
    int af = 0;
    int cf = 0;
    int gf = 0;
    int tf = 0;
    int h = 0;
    int flag = 0;
    final JScrollPane jScroll = new JScrollPane();
    final JFrame parFrame;
    Vector<Double> xrand = new Vector<Double>();

    public DrawCurve() {
        super();
        parFrame = new JFrame();
        parFrame.pack();
        jScroll.setFocusable(false);
        setFocusable(true);
        parFrame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent we) {
                System.exit(0);
            }
        });

        this.setBackground(Color.WHITE);
        jScroll.setViewportView(this);
        jScroll.getHorizontalScrollBar().addAdjustmentListener(new MyAdjustmentListener());
        jScroll.getVerticalScrollBar().addAdjustmentListener(new MyAdjustmentListener());
        if (checkSequence(seq) == 0) {
            jScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
            jScroll.setViewportBorder(new LineBorder(Color.WHITE));
            setFocusable(true);
            setPreferredSize(new Dimension(1000, 300));
            setBackground(Color.magenta);
            parFrame.add(jScroll, BorderLayout.CENTER);
            parFrame.setSize(600, 320);
            parFrame.setVisible(true);
        } else {
            JOptionPane.showMessageDialog(null, "invalid input", "Warning!", JOptionPane.PLAIN_MESSAGE);
        }
    }

    public int checkSequence(String sequ) {
        int f = 0;
        for (int i = 0; i < sequ.length(); i++) {
            if (sequ.charAt(i) != "A".charAt(0) && sequ.charAt(i) != "C".charAt(0) && sequ.charAt(i) != "G".charAt(0) && sequ.charAt(i) != "T".charAt(0)) {
                f = 1;
                break;
            }
            xrand.add(Math.random() * 300 - 200);
        }
        return f;
    }

    public void paintComponent(Graphics gr) {
        super.paintComponent(gr);
        Graphics2D ga = (Graphics2D) gr;
        System.out.println("in");
        ga.setStroke(drawingStroke);
        for (int i = 0; i < seq.length(); i++) {
            s = seq.charAt(i);
            if (s == "A".charAt(0)) {
                ga.setColor(Color.RED);
                a = 1;
                af = 1;
                cf = 0;
                gf = 0;
                tf = 0;
                h = -1;
            } else if (s == "C".charAt(0)) {
                ga.setColor(Color.YELLOW);
                c = 1;
                af = 0;
                cf = 1;
                gf = 0;
                tf = 0;
                h = -3;
            } else if (s == "G".charAt(0)) {
                ga.setColor(Color.GREEN);
                g = 1;
                af = 0;
                cf = 0;
                gf = 1;
                tf = 0;
                h = 1;
            } else if (s == "T".charAt(0)) {
                ga.setColor(Color.BLUE);
                t = 1;
                af = 0;
                cf = 0;
                gf = 0;
                tf = 1;
                h = 3;
            } else {
                af = 0;
                cf = 0;
                gf = 0;
                tf = 0;
                h = 0;
            }
            x = Math.random() * 300 - 200;
            curve = new QuadCurve2D.Double(y, 250 + h, y + 10, xrand.elementAt(i), y + 20, 250 + h);
            ga.draw(curve);
            if (a == 1 && af == 0) {
                ga.setColor(Color.RED);
                h = -1;
                ga.drawLine(y, 250 + h, y + 20, 250 + h);
            }
            if (c == 1 && cf == 0) {
                ga.setColor(Color.YELLOW);
                h = -3;
                ga.drawLine(y, 250 + h, y + 20, 250 + h);
            }
            if (g == 1 && gf == 0) {
                ga.setColor(Color.GREEN);
                h = 1;
                ga.drawLine(y, 250 + h, y + 20, 250 + h);
            }
            if (t == 1 && tf == 0) {
                ga.setColor(Color.BLUE);
                h = 3;
                ga.drawLine(y, 250 + h, y + 20, 250 + h);
            }
            y += 20;

        }
    }

    public static void main(String[] args) {
        final DrawCurve panel = new DrawCurve();        
    }
}

person Sarah Morgan    schedule 11.06.2012    source источник
comment
Кроме того, вы можете заменить "A".charAt(0) на 'A'   -  person Tharwen    schedule 11.06.2012
comment
1) Я никогда не вижу нарисованных четырехугольных кривых, панель «чисто пурпурного цвета». Я думал, что это размер штриха, но проблема не в этом.. 2) В чем смысл MyAdjustmentListener? Оба вызова setFocusable выполняются для компонентов при их инициализации.   -  person Andrew Thompson    schedule 11.06.2012
comment
@Tharwen Хорошее замечание (в комментарии) и отличное предложенное редактирование. Я просто не мог удержаться от того, чтобы немного подкорректировать редактирование.   -  person Andrew Thompson    schedule 11.06.2012
comment
@AndrewThompson, если это чистый пурпурный цвет, это потому, что после запуска программы paintComponent выполнялся дважды, что иногда случается. когда он выполняется дважды, кривая не рисуется, я не знаю, почему это происходит также   -  person Sarah Morgan    schedule 11.06.2012


Ответы (1)


Я разобрался, что не так с этим кодом, оказалось, что в своем цикле я забыл инициализировать, где должна начинаться кривая каждый раз при вызове paintComponent. Добавление у=0; в начале paintComponent решит это

person Sarah Morgan    schedule 11.06.2012