Interface Ich möchte eine Zeichenumgebung

A-Stern

Mitglied
Ich möchten den A-Stern-Algorithmus in verschidenen Varianten mal programmieren.
Normalerweise arbeite ich mit C++, aber damit ich schneller Erfolge habe möchte ich das gerne mit Java machen. Ein wenig Erfahrung habe ich schon, aber das reicht dafür nicht.

jetzt das "Problem":

Ich bräuchte dafür eine Oberfläche, auf die ich einfach zeichnen kann. Also einfach mit
Code:
drawnLine
, ... irgendetwas auf die Fläche. Ich möchte die größe selbst bestimmen können oder auslesen können.

ich habe ein wenig gegooglet, aber nix gefunden. Google-Links reichen mir auch.

Net wäre vieleicht auch noch eine Zeichenbefehlreferenz.

Ich verwende NetBeans.

Ich danke schonmal!
 
Danke erstmal. Nur was mache ich falsch?

Manchmal wird einer meine drawn-Befhle angezeigt, manchmal aber keiner, und nie beide übereinander!

Code:

AStarSpecial.java:
Java:
package a.star.special;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Yannick
 */
public class AStarSpecial
{

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        JavaGUI draw = new JavaGUI();
        
        draw.feld(true, 1, 1);
        draw.feld(false, 2, 2);
    }
}

MyFirstCanvas.java:

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package a.star.special;

/**
 *
 * @author Yannick
 */
import java.awt.*;
 
public class MyFirstCanvas extends Canvas
{
    private int x, y;
    private String[] args;
    
    public MyFirstCanvas(String[] argumente, int pos_x, int pos_y)
    {
        x = pos_x;
        y = pos_y;
        args = argumente;
    }
   
    
    public void paint(final Graphics g)
    {
        /* das paint() der super-Klasse muss natürlich aufgerufen werden. */
        super.paint(g);
        
        g.setColor(Color.red);
        g.drawOval(0, 0, 100, 100);

        if(args[0] == "feld")
        {
            if(args[1] == "hindernis")
            {
                g.setColor(Color.black);
                g.fillRect(x * 51 + 1, y * 51 + 1, 50, 50);
            }
            else if(args[1] == "normal")
            {
                g.setColor(Color.white);
                g.fillRect(x * 51 + 1, y * 51 + 1, 50, 50);
            }
        }
    }
}

JavaGUI.java:

Java:
package a.star.special;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Yannick
 */
import javax.swing.*;
import java.awt.*;
 
public class JavaGUI
{
	/* Erstellt ein neues JFrame mit dem Titel "Java phone */
	JFrame mainFrame = new JFrame("Java Phone");
	/* Dazu kommt noch ein kleines Panel */
	JPanel keyDisplayPanel = new JPanel();
 
	public JavaGUI()
        {        
            /* Setzt das Layout vom Frame und vom Panel */
            mainFrame.setLayout(new BorderLayout(20,20));
            keyDisplayPanel.setLayout(new BorderLayout(20,20));

            /* und natürlich noch das Panel auf das Frame */
            mainFrame.add(keyDisplayPanel, BorderLayout.CENTER);

            /* Nur noch anzeigen und das ganze läuft */
            mainFrame.setSize(300,300);
            mainFrame.setVisible(true);
	}
        
        public void feld(boolean flag, int x, int y)
        {
            String[] str = new String[2];
            str[0] = "feld";
            str[1] = (flag)? "hindernis" : "normal";
            
            MyFirstCanvas myCanvas = new MyFirstCanvas(str, x, y);
            
            keyDisplayPanel.add(myCanvas, BorderLayout.CENTER);
            mainFrame.add(keyDisplayPanel, BorderLayout.CENTER);
        }
}
 
Du erstellst bei jedem "feld" Aufruf nen neues Canvas, damit wird das alte natürlich überschrieben.

Außerdem NIEMALS Swing und AWT mischen. Nimm statt dem Canvas nen JPanel und überschreib deren paintComponent Methode.
 
Ich hab hier einfach copy-paste-Code gemacht.

Aber das wonach ich wirklich suche ist etwas, mit dem ich mit Befehlen wie z.B.
Code:
drawLine
ohne Umwege einfach in mein Fenster malen kann. und zwar, dass das "Bild" bei einem neue zeichenbefehl nicht geköscht wird, sindern, dass ich ständig überscheriben kann. Ein Refresh-Befehl, zum kompletten löschen wäre auch nicht schlecht.

Auch nicht schlecht wäre zu wissen, wie ich es schaffe, das Programm nach Fensertschließung zu beenden.
 
Zuletzt bearbeitet:
Aber das wonach ich wirklich suche ist etwas, mit dem ich mit Befehlen wie z.B. drawLine ohne Umwege einfach in mein Fenster malen kann.
Das geht nur in der paintComponent Methode des JPanels (oder im AWT pendant).

Auch nicht schlecht wäre zu wissen, wie ich es schaffe, das Programm nach Fensertschließung zu beenden.
Code:
deinJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Das beendet dein Programm sobald das Fenster geschlossen wird.
 
Danke.

Hat geholfen.

Nur jetzt mein Problem:

Ich habe verschiedene Zeichenbefehle darunter
Code:
drawLine
und
Code:
fillRect
.
Jetzt frage ich mich, ob es möglich ist, diese Befehle nacheinader auszuführen, sodass sie sich übermalen.

Also, dass ich z.B. in die Klasse
Code:
PaintPanel
die Funktionen einbaue.
Ist das möglich? Oder muss ich das anders machen?
 
Jetzt frage ich mich, ob es möglich ist, diese Befehle nacheinader auszuführen, sodass sie sich übermalen.
Nix anderes machst du doch, wenn du
Code:
Graphics2D#draw(Shape)
vor
Code:
Graphics2D#fill(Shape)
verwendest...
 
Nein.
Ich habe das anders gemeint.
Ich zeichne nicht alles auf einmal, sondern nach und nach. Zwischendrin möchte ich auch das Programm pausieren.
Und ich möchte dynamisch zeichnen. Also das "Bild" ändert sich. Deshalb meinte ich, ob es möglich ist, in meiner
Code:
main
-Funktion die Zeichenbefehle ausführen.

Geht das?
 
Nein, so ohne weiteres geht das nicht. Gezeichnet wird ausschließlich in der paintComponent Methode.
Du könntest aber auf von irgendwo auf ein BufferedImage zeichnen, dass das in deinem JPanel per drawImage gezeichnet wird. per getGraphics() kannst du dir das Graphics Objekt des BufferedImage geben lassen, wenn du fertig gemalt hast rufst du repaint() auf dem JPanel auf.
 
Nein, so ohne weiteres geht das nicht. Gezeichnet wird ausschließlich in der paintComponent Methode.
Du könntest aber auf von irgendwo auf ein BufferedImage zeichnen, dass das in deinem JPanel per drawImage gezeichnet wird. per getGraphics() kannst du dir das Graphics Objekt des BufferedImage geben lassen, wenn du fertig gemalt hast rufst du repaint() auf dem JPanel auf.

Die Idee ist nicht schlecht.

Wie mache ich das?
 
Hab ich doch eigentlich schritt für schritt erklärt, was daran ist unklar? Was hast du schon versucht?
 
Ich habe mit java eingentlich keine Erfahrung. Deshalb weiß ich nicht, wie ich auf Bilder zugreifen kann.

Ist jetzt aber egal, da ich eine andere Lösung gefunden habe. Ich zeichne einfach alles neu. Und speichere alles zwischen.

Jetzt hab ich ein anderes Problem:

Ich möchte mir einen Vector anlegen, der aus einem 1-dimensionalen int-Array besteht, das aus 4 Elementen besteht.

Mein bisheriger Versuch:

[JAVA=5]package a.star.special;

import java.util.Vector<E>;

public class Lines
{
private Vector<int[4]> int_lines = new Vector<int[4]>();
}[/code]
 
Vector ist veraltet, nimm stattdessen lieber ne List.
So könntest du deine Liste anlegen:
Java:
List<int[]> list = new ArrayList<int[]>();
Allerdings verstehen sich Arrays und Generics nicht immer gut, da kommts gern mal zu kleineren Problemen. Außerdem repräsentiert dein int[] Array doch sicherlich ein Objekt. Kapsel das dann lieber mit nem Objekt:
Java:
List<DeinObjekt> list = new ArrayList<DeinObjekt>();
 
ok. Danke!

Klappt wunderbar!

Für alle die's interessiert, ist hier nochmal der Code:

AStarSpecial.java:

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Yannick
 */

package a.star.special;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import java.util.Random;
import java.util.Vector;
 
public class AStarSpecial
{
    static private Random r = new Random();
    // Die Map
    static private Map map = new Map(10);
    static private Vector<Line> lines = new Vector<Line>();
    // Fenster erstellen
    static private JFrame frame = new JFrame("Simple paint");
    
    public static void main(String args[])
    {   
        for(int i = 0; i < 10; i++)
        {
            for(int j = 0; j < 10; j++)
            {
                map.set(i, j, r.nextInt(2));
            }
        }
        
        int[] start = {r.nextInt(10), r.nextInt(10)};
        int[] ziel = {r.nextInt(10), r.nextInt(10)};
        
        map.set(start[0], start[1], 2);   // Start
        map.set(ziel[0], ziel[1], 3);     // Ziel
        
        // Das Erzeugen des GUIs muss auf dem
        // Event-Dispatch-Thread ausgeführt
        // werden:
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
        
        while(true)  // Nur zum testen, ob das Aktualisiren funktioniert
        {
            try
            {
                Thread.sleep(2000);
            }
            catch(InterruptedException e)
            {
            }

            map.set(r.nextInt(10), r.nextInt(10), 4);
            map.set(r.nextInt(10), r.nextInt(10), 4);
            map.set(r.nextInt(10), r.nextInt(10), 5);

            lines.add(
                new Line(
                    new Color(128, 255, 128)
                , r.nextInt(10), r.nextInt(10), r.nextInt(10), r.nextInt(10), true)
            );
            
            lines.add(
                new Line(
                    new Color(0, 128, 0)
                , r.nextInt(10), r.nextInt(10), r.nextInt(10), r.nextInt(10), true)
            );

            update();
        }
    }
 
    // Erzeugt ein Fenster, das ein PaintPanel enthält,
    // und macht das Fenster sichtbar
    private static void createAndShowGUI()
    {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        // PaintPanel erstellen und in das Fenster legen
        PaintPanel paintPanel = new PaintPanel(map, lines);
        paintPanel.setPreferredSize(new Dimension(map.get_x_size() * 52, map.get_y_size() * 52));
        frame.getContentPane().add(paintPanel);
 
        // Fenster zentrieren und anzeigen
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    /**
     * Aktualisiert das Fenster
     */
    
    private static void update()
    {
        // PaintPanel erstellen und in das Fenster legen
        PaintPanel paintPanel = new PaintPanel(map, lines);     
        paintPanel.setPreferredSize(new Dimension(map.get_x_size() * 52, map.get_y_size() * 52));
        frame.getContentPane().add(paintPanel);
        
        // Fenster zentrieren und anzeigen
        frame.setVisible(true);
    }
}

Drawing.java:

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package a.star.special;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Vector;

import javax.swing.JPanel;

/**
 *
 * @author Yannick
 */

// Ein JPanel, bei dem die paintComponent-Methode überschrieben ist,
// so dass man in das JPanel etwas reinmalen kann.
class PaintPanel extends JPanel
{
    private Map map;
    private Vector<Line> lines;
    
    PaintPanel()
    {
        map = new Map();
        lines = new Vector<Line>();
    }
    
    PaintPanel(Map map, Vector<Line> lines)
    {
        this.map = map;
        this.lines = lines;
    }
    
    // Die paintComponent-Methode wird immer aufgerufen,
    // wenn das Panel neu gezeichnet wird
    @Override
    protected void paintComponent(Graphics graphics)
    {
        super.paintComponent(graphics);
        Graphics2D g = (Graphics2D) graphics;
        
        int x = map.get_x_size() * 52;
        int y = map.get_y_size() * 52;
        
        g.setColor(Color.WHITE);
        
        g.fillRect(0, 0, x, y);
        
        g.setColor(Color.BLACK);
        
        int j;
        
        for(int i = 0; i <= x; i += 52)
        { 
            j = i + 1;
            
            g.drawLine(i, 0, i, y);
            g.drawLine(0, i, x, i);
            
            g.drawLine(j, 0, j, y);
            g.drawLine(0, j, x, j);
        }
        
        int size = 50;
        int border = 2;
        int total_size = size + border;
        int cur_map_pos;
        
        x = map.get_x_size();
        y = map.get_y_size();
        
        for(int i = 0; i < y; i++)
        {
            for(j = 0; j < x; j++)
            {
                cur_map_pos = map.read(j, i);
                
                if(cur_map_pos == 1)        // Hindernis
                {
                    g.setColor(new Color(100, 0, 0));
                }
                else if(cur_map_pos == 0)   // Nichts
                {
                    g.setColor(Color.WHITE);
                }
                else if(cur_map_pos == 2)   // Start
                {
                    g.setColor(new Color(0, 255, 0));
                }
                else if(cur_map_pos == 3)   // Ziel
                {
                    g.setColor(new Color(255, 0, 0));
                }
                else if(cur_map_pos == 4)   // Offen
                {
                    g.setColor(new Color(128, 128, 255));
                }
                else if(cur_map_pos == 5)   // Geschlossen
                {
                    g.setColor(new Color(0, 0, 255));
                }
                else
                {
                    g.setColor(Color.BLACK);
                }
       
                g.fillRect((j * total_size) + border, (i * total_size) + border, size, size);
            }
        }
        
        size = lines.size();
        
        for(int i = 0; i < size; i++)
        {
            lines.get(i).draw(g);
        }
    }
}

Map.java:

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package a.star.special;

/**
 *
 * @author Yannick
 */
public class Map
{
    private int[][] map;
    private int int_x, int_y;
    
    public Map()
    {
        map = new int[20][20];
        int_x = 20;
        int_y = int_x;
    }
    
    public Map(int size)
    {
        map = new int[size][size];
        int_x = size;
        int_y = int_x;
    }
    
    public Map(int x_size, int y_size)
    {
        map = new int[x_size][y_size];
        int_x = x_size;
        int_y = y_size;
    }
    
    public int read(int x, int y)
    {
        if((x < 0) || (x > int_x) || (y < 0) || (y > int_y))
        {
            return 0;
        }
        
        return map[x][y];
    }
    
    public void set(int x, int y, int value)
    {
        if((x < 0) || (x > int_x) || (y < 0) || (y > int_y))
        {
            return;
        }
        
        map[x][y] = value;
    }
    
    public int get_x_size()
    {
        return int_x;
    }
    
    public int get_y_size()
    {
        return int_y;
    }
}

Line.java:

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package a.star.special;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

/**
 *
 * @author Yannick
 */
public class Line
{
    public Color color;
    public int start_x, start_y, finish_x, finish_y;
    public boolean arrow;
    
    Line()
    {
        this.color = new Color(0, 0, 0);
        this.start_x = 0;
        this.start_y = 0;
        this.finish_x = 0;
        this.finish_y = 0;
        this.arrow = false;
    }
    
    Line(Color color, int start_x, int start_y, int finish_x, int finish_y, boolean arrow)
    {
        this.color = color;
        this.start_x = start_x;
        this.start_y = start_y;
        this.finish_x = finish_x;
        this.finish_y = finish_y;
        this.arrow = arrow;
    }
    
    Line(int red, int green, int blue, int start_x, int start_y, int finish_x, int finish_y, boolean arrow)
    {
        this.color = new Color(red, green, blue);
        this.start_x = start_x;
        this.start_y = start_y;
        this.finish_x = finish_x;
        this.finish_y = finish_y;
        this.arrow = arrow;
    }
    
    public void draw(Graphics2D g)
    {
        Color tmp = g.getColor();
        
        g.setColor(color);
        
        int x_1 = (start_x * 52) + 26;
        int y_1 = (start_y * 52) + 26;
        int x_2 = (finish_x * 52) + 26;
        int y_2 = (finish_y * 52) + 26;
        
        g.drawLine(x_1, y_1, x_2, y_2);
        g.drawLine(x_1 + 1, y_1, x_2 + 1, y_2);
        g.drawLine(x_1, y_1 + 1, x_2, y_2 + 1);
        g.drawLine(x_1 - 1, y_1, x_2 - 1, y_2);
        g.drawLine(x_1, y_1 - 1, x_2, y_2 - 1);
        
        if(arrow)
        {
            ;
        }
        
        g.setColor(tmp);
    }
}
 

Zurück
Oben