绘制动态图。

发布于 2024-12-24 23:03:13 字数 3013 浏览 0 评论 0原文

通过说动态图,我的意思是用户可以在屏幕上拖动顶点,然后删除等等。

我陷入了这一点,我想绘制多个顶点,并且试图避免在图形发生变化时让 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);
    }
}    

By saying dynamic graph i mean that the user can drag Vertices around the screen and later remove and more.

I am stuck at this point where i want to paint more then one Vertex, and am trying to avoid making JVM paint the whole graph all over again when the graph changes.

do i have to make it paint the whole graph or is there another way to do that?

here's my code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

記柔刀 2024-12-31 23:03:13

让我们考虑图形是椭圆形列表和直线列表。在 Graph 的 PaintComponent() 方法中,我们必须绘制所有列表的成员。

添加检查 g.getClipBounds 矩形是否与椭圆形(或直线)矩形相交。如果它们相交,我们就画椭圆形或直线。

当顶点移动到某个地方时,我们有旧的和新的位置,并且可以重新绘制矩形。

使用矩形位置和大小并传入图形面板的 repaint()。

这样,您将仅重新绘制更改的区域,并且仅在矩形中可见椭圆形和线条。

Let's consider graph is list of Ovals and list of Lines. IN the paintComponent() method of Graph we have to draw all the lists' members.

Add a check that g.getClipBounds rectangle intersects Oval (or Line) rectangle. If they intersect we draw oval or line.

When vertex is moved somewhere we have old and new position and can get rectangle to be repainted.

Use the rectangle location and size and pass in the graph panel's repaint().

That way you will repaint changed region only and only ovals and lines visible in the rectangle.

会傲 2024-12-31 23:03:13

示例可以轻松处理数千个顶点。使用 flyweight 模式 进行渲染可能会让更多人受益; 此处说明了一种方法。

This example can easily handle thousands of vertices. Larger numbers may benefit from using the flyweight pattern for rendering; one approach is illustrated here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文