为了账号安全,请及时绑定邮箱和手机立即绑定

动态图形对象绘画

/ 猿问

动态图形对象绘画

慕侠2389804 2019-10-21 15:23:10

试图找出最好的方法来做到这一点(在不交叉任何细节的情况下,请不要不要,我不知道)。


我正在视觉上显示带有圆圈和线的图形(各种节点,边缘连接在一起)。每个节点都将在运行时添加,我无法对此进行硬编码。据我了解,所有绘画都需要在paint(Graphics g)方法中完成-并没有什么帮助,因为我无法更改参数,而且似乎仅在初始创建时才调用它?


现在,我正在考虑让它调用各种其他方法,传递Graphics对象,并取决于其他变量-我将决定是否要调用它(因为paint()方法是我唯一可以调用的方法) )。


我要彻底解决这个问题吗?从来没有打扰过。


为了让您更好地了解最终的结果:我希望能够传递要为节点添加的形状的坐标,然后将其添加到到目前为止在图形上显示的任何内容。然后,与边缘相同,我希望能够通过该行的起点和终点,以在当时存在的所有内容之上进行重新绘制。


并非我现在想要的完全正确-但是您会从到目前为止我拼凑的内容中获得灵感:


import java.awt.*;

import javax.swing.*;

public class MyCanvas extends Canvas

{

    public MyCanvas()

    {

    }

    public void paint(Graphics graphics)

    {

        // Keep this until I figured out if it's painted on load or not.

        graphics.drawLine(10, 20, 350, 380);

    }

    public static void main(String[] args)

    {

        MyCanvas canvas = new MyCanvas();

        JFrame frame = new JFrame();

        int vertexes = 0;

        // Change this next part later to be dynamic.

        vertexes = 10;

        int canvasSize = vertexes * vertexes;

        frame.setSize(canvasSize, canvasSize);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(canvas);

        frame.setVisible(true);

    }

    public void drawNode(int x, int y, Graphics g)

    {

            // Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5 

            int xLoc = (x*10) - 5;

            int yLoc = (y*10) - 5;

            g.setColor(Color.white);

            g.fillOval(xLoc, yLoc, 8, 8);

            g.drawOval(xLoc, yLoc, 8, 8);

    }

    public void drawArc(int x, int y, int xx, int yy, Graphics g)

    {

            int xLoc = (x*10) - 5;

            int yLoc = (y*10) - 5;

            int xxLoc = (xx*10) - 5;

            int yyLoc = (yy*10) - 5;

            g.drawLine(xLoc, yLoc, xxLoc, yyLoc);

    }


}


查看完整描述

3 回答

?
HUH函数

您可以为此采取多种策略。

  1. 如果完成后从未将对象从图形中删除,请使用a BufferedImage并将其放在a ImageIconJLabel。需要更新的时间:

    1. 获取图像的图形实例并绘制新元素。

    2. 处置图形对象。

    3. 呼叫repaint()标签。

  2. 保留绘制元素的列表。在绘制方法中,将它们全部绘制。添加新元素后,调用repaint()渲染组件。


这是第一种技术的示例:

//img1.mukewang.com/5dad5d0000015b5006180445.jpg

import java.awt.image.BufferedImage;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.util.Random;


public class MyCanvas

{

    JLabel view;

    BufferedImage surface;

    Random random = new Random();


    public MyCanvas()

    {

        surface = new BufferedImage(600,400,BufferedImage.TYPE_INT_RGB);

        view = new JLabel(new ImageIcon(surface));

        Graphics g = surface.getGraphics();

        g.setColor(Color.ORANGE);

        g.fillRect(0,0,600,400);

        g.setColor(Color.BLACK);

        // Keep this until I figured out if it's painted on load or not.

        g.drawLine(10, 20, 350, 380);

        g.dispose();


        ActionListener listener = new ActionListener() {

            public void actionPerformed(ActionEvent ae) {

                addNewElement();

            }

        };

        Timer timer = new Timer(200, listener);

        timer.start();

    }


    public void addNewElement() {

        boolean drawArc = random.nextBoolean();

        int x = random.nextInt(60);

        int y = random.nextInt(40);

        Graphics g = surface.getGraphics();

        if (drawArc) {

            g.setColor(Color.BLUE);

            int xx = random.nextInt(60);

            int yy = random.nextInt(40);

            drawArc(x,y,xx,yy,g);

        } else {

            drawNode(x,y,g);

        }

        g.dispose();

        view.repaint();

    }


    public static void main(String[] args)

    {

        MyCanvas canvas = new MyCanvas();

        JFrame frame = new JFrame();

        int vertexes = 0;

        // Change this next part later to be dynamic.

        vertexes = 10;

        int canvasSize = vertexes * vertexes;

        frame.setSize(canvasSize, canvasSize);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setContentPane(canvas.view);

        frame.pack();

        frame.setLocationByPlatform(true);

        frame.setVisible(true);

    }


    public void drawNode(int x, int y, Graphics g)

    {

            // Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5

            int xLoc = (x*10) - 5;

            int yLoc = (y*10) - 5;

            g.setColor(Color.white);

            g.fillOval(xLoc, yLoc, 8, 8);

            g.drawOval(xLoc, yLoc, 8, 8);

    }


    public void drawArc(int x, int y, int xx, int yy, Graphics g)

    {

            int xLoc = (x*10) - 5;

            int yLoc = (y*10) - 5;

            int xxLoc = (xx*10) - 5;

            int yyLoc = (yy*10) - 5;

            g.drawLine(xLoc, yLoc, xxLoc, yyLoc);

    }

}

进一步的提示

您可能会注意到,这些行看起来很“参差不齐”且难看。两个BufferedImage或一个JComponent可以访问更有用Graphics2D对象(对于JComponent有必要将其丢在paintComponent())。甲Graphics2D实例接受渲染可用于平滑(抖动)绘制的元素的提示。


查看完整回答
反对 回复 2019-10-21
?
胡子哥哥

我通常会,尽管我今天觉得很懒。但是总的来说,人们认为如果代码足够短以至于无法发布到SO上,那么他们就会看它。否则)a)有些人担心“外部链接”(好的-对于pastebin来说不多)&b) pastebin消失了,我们将提供代码以供将来参考。如果问题是“自包含”且没有“外部依赖”,则更好。c)另见垃圾神的观点。

查看完整回答
反对 回复 2019-10-21
?
守着一只汪

不要混合使用Swing(例如JFrame)和AWT(例如Canvas)组件。而不是Canvas使用JPanel&替代paintComponent(Graphics)

查看完整回答
反对 回复 2019-10-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信