Punkte und Pfeile zeichnen im Koordinatensystem

bd3m

Grünschnabel
Hallo an alle,

Vorerst ein paar kurze Worte zur allgemeien Aufgabe:

Ich habe einige Klassen geschrieben, die einen Graphen repräsentieren, mit Knoten und Kanten. (-> Graphentheorie)
Diese Knoten haben x und y Koordinaten und die Kanten, enthalten Infos mit welchen Knöten sie verbunden sind.

Das ganze funktioniert prima.

Nun muss ich aber das ganze graphisch darstellen. D.h: Ich muss einen Graphen aus einer xml-Datei einlesen (soweit auch geschafft) und diesen dann
graphisch darstellen.
Ich denke auch nicht, dass das so schwer ist, da die einzelnen Knoten ja x und y Koordinaten haben.

Fragen:
1) Wie erstelle ich ein Koordinatensystem
2) Wie lasse ich Swing automatisch die einzelnen Knöten(Punkte) erzeugen ?
3) Wie mache ich das mit den Kanten ? Die sind ja mit Knöten verbunden
 
Hi und Willkommen bei tutorials.de,

du hast also schon Koordinaten vorgegeben?
(statt welche berechnen zu müssen, damit der Graph irgendwie schön ausschaut)

Was soll genau angezeigt werden?
Gibt es Bilder für Knoten, oder ein einfacher Kreis, oder...?
 
Hey,

ja ich habe die Koordinaten vorgegeben und die Anzahl der Knöten. Und Anzahl der Kanten und welche Kante mit welchem Knoten verbunden ist.

Schön ausschauen ist mir egal, muss nur die Aufgabe erfüllen :D

Für Knoten einen Kreis.
Für Kanten eine Gerade mit einer Pfeilspitze am Ende (Start und Zielknoten; zum Zielknoten soll eine Pfeilspitze oder irgendwas in der Art gezeichnet werden).

Vielen Dank für deine Antwort =)
 
Hier meine bisherige GUI: Die soll auch genauso aussschauen, und irgendwo rechts von den Buttons un co.
soll ein dieser Graph gemalt werden.
Code:
public class DiGraphView extends JFrame {
	private JTextField txtSuchalgorithmus;
	private JTextField txtStart;
	private JTextField txtZiel;
	private JComboBox comboBox;
	private JComboBox comboBox_1;
	private JComboBox comboBox_2;
	private JSlider slider;
	private JEditorPane editorPane;
	private JButton btnGraphLaden;
	private JButton btnNewButton;
	DiGraph graphen;

	public DiGraphView() {

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("DiGraph-GUI-View");
		getContentPane().setLayout(null);
		setBounds(300, 300, 1050, 600);

		btnGraphLaden = new JButton("Graph laden");
		btnGraphLaden.setBounds(35, 269, 174, 25);
		getContentPane().add(btnGraphLaden);
		btnGraphLaden.addActionListener(new FileOpenListener());

		btnNewButton = new JButton("suchen");
		btnNewButton.setBounds(35, 320, 174, 25);
		getContentPane().add(btnNewButton);

		txtSuchalgorithmus = new JTextField();
		txtSuchalgorithmus.setText("Suchalgorithmus");
		txtSuchalgorithmus.setBounds(44, 71, 114, 19);
		getContentPane().add(txtSuchalgorithmus);
		txtSuchalgorithmus.setColumns(10);

		txtStart = new JTextField();
		txtStart.setText("Start");
		txtStart.setBounds(44, 136, 114, 19);
		getContentPane().add(txtStart);
		txtStart.setColumns(10);

		txtZiel = new JTextField();
		txtZiel.setText("Ziel");
		txtZiel.setBounds(44, 193, 114, 25);
		getContentPane().add(txtZiel);
		txtZiel.setColumns(10);

		comboBox = new JComboBox();
		comboBox.setModel(new DefaultComboBoxModel(new String[] { "A-Stern",
				"Breitensuche", "Tiefensuche", "Dijsktra" }));
		comboBox.setBounds(202, 68, 86, 24);
		getContentPane().add(comboBox);

		comboBox_1 = new JComboBox();
		comboBox_1.setBounds(188, 133, 86, 24);
		getContentPane().add(comboBox_1);

		comboBox_2 = new JComboBox();
		comboBox_2.setBounds(202, 193, 86, 24);
		getContentPane().add(comboBox_2);

		slider = new JSlider();
		slider.setBounds(35, 241, 200, 16);
		getContentPane().add(slider);

		
	}

	class FileOpenListener extends JPanel implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// JFileChooser-Objekt erstellen
			JFileChooser chooser = new JFileChooser();
			// Dialog zum Speichern von Dateien anzeigen
			chooser.showDialog(null, "Datei öffnen");
			File graph = chooser.getSelectedFile();
			InputStream inStream = null;
			try {
				inStream = new java.io.FileInputStream(graph);
			} catch (FileNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			XYGXLSupport support = new XYGXLSupport();
			try {
				graphen = support.read(inStream);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
Ach ja, eine kleine Besonderheit:
Das Koordiantensystem, bzw. der Graph, soll automatisch sklalierbar sein. D.h. wenn es 500 Knöten gibt soll es dementsprechend kleiner skaliert sein, wie wenn es nur 3 gibt.

Ach und es muss auch garkein Koordinatensystem sein... Der Graph soll einfach nur angezeigt werden. Ob es einfach nur in der GUI ist , ist egal.
Ich kann den auch einfach ins blaue zeichnen....
 
Zuletzt bearbeitet:
Genaue Codeanweisungen für alles wäre an dieser Stelle etwas zu viel,
deshalb nur Theorie:

Mach ein Panel, dass als Zeichenfeld dient.
Am Einfachsten wäre, wenn es quadratisch ist.
Denk dir dazu innerhalb vom Panel am Rand entlang einen Streifen, auf den nicht gezeichnet wird.
Grund: Wenn mn die Mittelpunkte der Knotenkreise im Zeichenbereich annimmt
kann ein Knoten ganz am Rand sein. Wäre das der Rand des echten Panels
würde man nur den halben Knoten sehen. So ist noch etwas Platz für den Restkreis.
Wenn man das Panel als Pixelkoordinatensystem sieht hat es als nur eine Höhe/Breite,
die das tatsächliche Maß minus 2*Streifendicke ist.
Zeichenoperationen werden dann auf X+Streifendicke | y+Streifendicke gemacht.

Zu der Skalierung:
Such dir am Anfang die größte X-Koordiante und die größte Y-Koordiante (getrennt) aus den Daten.
Wenn das Zeichenfeld quadratisch ist nimm die wertmäßig Kleinere davon = X,
sonst muss noch mit einem Faktor verrechnet werden.
Tatsächliche Koordinaten und Radius eines Kreises sind dann
Faktor * EigentlicherDatenwert * PixelgrößeDesZeichenfelds / X
wobei ein vernünftiger Faktor und Standardradius
am Leichtesten durch Ausprobieren zu ermitteln sind.
Die Sache mit dem freien Streifen kommt noch als Rechen-Verumständlichung dazu.

Wenn man will kann man das selbe Spiel mit der Liniendicke vom Kreis
(und auch den Pfeilen dann) machen

Pfeile: Gehen gedacht von einem Kreismittelpunkt zum Anderen,
beginnen aber erst "AktuellerRadius" nach dem Ersten und enden genausoviel vom dem Zweiten
(damit sie nicht in den Kreis reinstehen)
Dazu gibts noch zwei kleine Striche am Ziel, in einem bestimmten Drehwinkel zum Hauptstrich.
Sinus/Cosinus helfen da; die Länge der Pfeilspitzen ist wieder eine Skalierungsrechnung.
 
Zurück