Динамическая графика объекта Живопись

Попытка выяснить лучший способ сделать это (и без пересечения каких-либо особенностей НЕ делаю того, о чем я не знаю).

Я работаю над визуальным отображением графика (различные узлы, с ребрами, соединяющими их) с кругами и линиями, чтобы представить их. Каждый узел будет добавлен во время выполнения, и я не могу это жестко закодировать. Из того, что я понимаю, все рисование должно быть выполнено в методе 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);
    }

}
 Andrew Thompson17 мая 2012 г., 02:35
Не смешивайте Swing (например,JFrame) и AWT (например,Canvas) составные части. ВместоCanvas, использоватьJPanel & переопределитьpaintComponent(Graphics).

Ответы на вопрос(1)

Решение Вопроса

Если объекты никогда не удаляются из чертежа, используйтеBufferedImage, положи в ImageIcon в)JLabel. Когда придет время обновлять: Получите графический экземпляр изображения и нарисуйте новый элемент. Утилизация графического объекта.Вызовrepaint() на этикетке. Сохранить список нарисованных элементов. В методе краски, нарисуйте их все. Когда добавляется новый элемент, звонитеrepaint() на компоненте рендеринга.

Вот пример 1-й техники:

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()). AGraphics2D instance принимает подсказки рендеринга, которые можно использовать для сглаживания (сглаживания) нарисованных элементов.

 Andrew Thompson17 мая 2012 г., 03:11
Не буду переходить по ссылке. Если он достаточно короткий, добавьте его в качестве правки.
 Andrew Thompson17 мая 2012 г., 03:21
Обычно, хотя сегодня мне лень. Тем не менее, в целом, люди считают, что если код достаточно короткий, чтобы публиковать его в SO - они будут смотреть на него, если нет .. Также a) некоторые люди боятся «внешних ссылок» (хорошо - не так уж много с pastebin) & b) Если pastebin исчезнет, у нас будет код для дальнейшего использования. Лучше, если вопрос будет «самодостаточным» без «внешних зависимостей». в) См. также точку зрения Трашго
 TJ Biddle17 мая 2012 г., 03:09
Вау, ладно, ты буквально отредактировал его 12 секунд назад, но собирался спросить, действительно ли ты это имел в виду: Pastebin.com / tsgVeshn Я очень быстро прочитаю то, что ты сказал.
 TJ Biddle17 мая 2012 г., 03:13
Edited. Из любопытства - есть ли причина, по которой вы не будете переходить по ссылке для вставки?
 TJ Biddle17 мая 2012 г., 03:21
@ trashgod - Вы комментируете размещение ссылки для вставки? Вы также можете скопировать необработанный код из pastebin (плюс получите немного симпатичной подсветки синтаксиса: p)

Ваш ответ на вопрос