动态图形对象绘画

时间:2012-05-17 00:30:42

标签: java swing graphics paint

试图找出实现这一目标的最佳方式(并且不会涉及任何具体内容而不是我不知道的事情。)

我正在以可视方式显示图形(各种节点,边缘连接它们),圆圈和线条代表这样。每个节点都将在运行时添加,我无法对其进行硬编码。根据我的理解,所有绘画都需要在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);
    }

}

编辑:(对安德鲁的回应)

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MyCanvas extends JPanel
{

    public MyCanvas() {

    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }

    public static void main(String[] args)
    { 
        int vertexes = 0;
        // Change this next part later to be dynamic.
        vertexes = 10;
        int canvasSize = vertexes * vertexes;

        JFrame frame = new JFrame();
        JLabel label = new JLabel();
        BufferedImage bImage = new BufferedImage(canvasSize, canvasSize, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = bImage.createGraphics();
        g2d.drawLine(50, 50, 300, 300);
        ImageIcon iIcon = new ImageIcon(bImage); 
        label.setIcon(iIcon);
        frame.add(label);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        g2d = drawNode(1,1,g2d);
        label.repaint();
    }

    public static Graphics2D drawNode(int x, int y,Graphics2D g2d)
    {
            // 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;
            g2d.setColor(Color.white);
            g2d.fillOval(xLoc, yLoc, 8, 8);
            g2d.drawOval(xLoc, yLoc, 8, 8);
            return g2d;
    }
    public static void drawArc(int x, int y, int xx, int yy)
    {
            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);
    }

}

1 个答案:

答案 0 :(得分:15)

您可能会采取各种策略。

  1. 如果完成后对象从未从绘图中删除,请使用BufferedImage,将其放入(ImageIconJLabel中。到了更新的时候:
    1. 获取图像的图形实例并绘制新元素。
    2. 处理图形对象。
    3. 在标签上拨打repaint()
  2. 保留所绘制元素的列表。在绘画方法中,将它们全部绘制。添加新元素后,请在渲染组件上调用repaint()

  3. 以下是第一种技术的示例:

    MyCanvas

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

    进一步提示

    您可能会注意到线条看起来很“锯齿”而且丑陋。 BufferedImageJComponent都可以访问更有用的Graphics2D对象(对于JComponent,必须将其投放到paintComponent()中)。 Graphics2D实例接受可用于平滑(抖动)绘制元素的渲染提示。