Рисование динамического графика. - PullRequest
2 голосов
/ 06 января 2012

Говоря о динамическом графике, я имею в виду, что пользователь может перетаскивать вершины по экрану, а затем удалять и т. Д.

Я застрял в этой точке, когда хочу нарисовать более одной вершины и пытаюсьне заставляйте JVM заново рисовать весь график заново, когда он меняется.

мне нужно, чтобы он нарисовал весь график, или есть другой способ сделать это?

вот мой код:

class GraphPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private Vector<Vertex> V=new Vector<Vertex>();
    private Vertex v;
    private int R = 20;

    public GraphPanel() {
        V.add(new Vertex(70,70));
        V.add(new Vertex(10,50));
        paintGraph();
        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                for (int i=0;i<V.size();i++) {
                    if ((V.get(i).getX()<=e.getX() && V.get(i).getX()+R>=e.getX()) && ( V.get(i).getY()<=e.getY() && V.get(i).getY()+R>=e.getY())) {
                        v=V.get(i);
                        moveVertex(e.getX(),e.getY());
                        v.changeState();
                    }
                }
            }
            public void mouseReleased(MouseEvent e) {
                v.changeState();
            }
        });

        addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent e) {
                if (v.isPressed()) moveVertex(e.getX(),e.getY());
            }
        });
    }

    private void paintGraph() {
        int OFFSET = 1;
        for (int i=0;i<V.size();i++) {
            v=V.get(i);
            repaint(v.getX(),v.getY(),R+OFFSET,R+OFFSET);
        }

    }

    private void moveVertex(int x, int y) {
        int OFFSET = 1;
        if ((v.getX()!=x) || (v.getY()!=y)) {
            repaint(v.getX(),v.getY(),R+OFFSET,R+OFFSET);
            v.setLocation(x-10, y-10);
            repaint(v.getX(),v.getY(),R+OFFSET,R+OFFSET);
        }
    }

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

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (v!=null) {
            g.setColor(Color.RED);
            g.fillOval(v.getX(),v.getY(),R,R);
            g.setColor(Color.BLACK);
            g.drawOval(v.getX(),v.getY(),R,R);
        }
    }
}

public class Vertex {
    private int x,y;
    boolean isPressed;
    Vertex(int x0,int y0) {x=x0;y=y0;isPressed=false;}
    public void setLocation(int x0,int y0) {x=x0;y=y0;}
    public int getX() {return x;}
    public int getY() {return y;}
    public boolean isPressed() {return isPressed;}
    public boolean changeState() {return isPressed=!isPressed;}

}

public class Tester {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI() {
        JFrame f = new JFrame("Swing Paint Demo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new GraphPanel());
        f.pack();
        f.setVisible(true);
    }
}    

Ответы [ 2 ]

2 голосов
/ 06 января 2012

Этот пример может легко обрабатывать тысячи вершин.Большим числам может быть полезно использовать шаблон веса для рендеринга;один подход иллюстрируется здесь .

2 голосов
/ 06 января 2012

Рассмотрим график - это список овалов и список линий.В методе Graph класса paintComponent () мы должны нарисовать все элементы списков.

Добавьте проверку, что прямоугольник g.getClipBounds пересекает овальный (или линейный) прямоугольник.Если они пересекаются, мы рисуем овал или линию.

Когда вершина перемещается куда-то, у нас есть старая и новая позиции, и мы можем получить перекрашиваемый прямоугольник.

Используйте расположение и размер прямоугольника и передайте вrepaint () графической панели ().

Таким образом, вы будете перекрашивать только измененную область и только овалы и линии, видимые в прямоугольнике.

...