paintmethod

linomail

Aktives Mitglied
Hi Leute,

ich bräuchte dringend eure Hilfe:

ich hab mehrere paintMethoden geschrieben, die auch auf normalen JFrame funktionieren.
Jetzt wo ich, nicht mehr aufm frame ziechnen möchte, sondern auf einem JPanel funktioniert die Methode nicht ...Ich sah oft in anderen Foren mit super.paintComponents beispiele die mir nicht wirklich weitergeholfen haben ...
Java:
public void paint(Graphics g)
    {
        int next = 0;
        int x1, y1, x2, y2;
        do {

            cities[next].paintCity(g);
            x1 = cities[next].xPos;
            y1 = cities[next].yPos;
            next = cities[next].next;
            x2 = cities[next].xPos;
            y2 = cities[next].yPos;
            g.drawLine(x1,y1,x2,y2);
        }
        while (next !=0);

    }

das möchte ich in diesem panel zeichnen nach meinem Klick
Java:
//hier soll er den graphen zeichnen
    JPanel graph = new JPanel();


//hier soll er nachm klick zeichnen
public void initializeElements() {
       autoSave.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e) {



               JTextField tfCity = new JTextField();
               JTextField tfRoad = new JTextField();

               Object[] message = {"Stadt", tfCity, " Straßen", tfRoad};

               JOptionPane pane = new JOptionPane(  message,
                                                    JOptionPane.PLAIN_MESSAGE,
                                                    JOptionPane.OK_CANCEL_OPTION);
               pane.createDialog(null, "Werte eingeben:").setVisible(true);

               oldcircle = new Map(Integer.parseInt(tfCity.getText()), Integer.parseInt(tfRoad.getText()));
               oldcircle.fillRandom();




           }
       });
   }
 

DrZoidberg

Top Contributor
Du musst dazu die paint Methode des JPanels überschreiben. z.B.
Java:
JPanel graph = new JPanel() {
  @Override
  public void paint(Graphics g) {
  }
};
 

Harry Kane

Top Contributor
das möchte ich in diesem panel zeichnen nach meinem Klick
Ich sehe ein JPanel was initialisiert wird, aber sonst nichts, was nach "zeichnen" aussieht.
Zeig doch mal kompletten Code. So kann man nur raten, was die Ursache ist:
- Fehler in der paintCity-methode
- Eine Exception föliegt, und das zeichnen bricht ab
- JPanel wurde keinen Contaienr hinzugefügt
- Der Container, in dem das JPanel liegt, hat nicht das passende Layout. Ein JPanel, dem keine KOmponenten hinzugefügt wurden, sollte eine preferredSize von im wesentlichen 0x0 Pixeln haben. Hat der Container, in dem das JPanel liegt, einen LayoutManager, der die preferredSize berücksichtigt, bleibt das JPanel unsichtbar.
 

linomail

Aktives Mitglied
Ich sehe ein JPanel was initialisiert wird, aber sonst nichts, was nach "zeichnen" aussieht.
Zeig doch mal kompletten Code. So kann man nur raten, was die Ursache ist:
- Fehler in der paintCity-methode
- Eine Exception föliegt, und das zeichnen bricht ab
- JPanel wurde keinen Contaienr hinzugefügt
- Der Container, in dem das JPanel liegt, hat nicht das passende Layout. Ein JPanel, dem keine KOmponenten hinzugefügt wurden, sollte eine preferredSize von im wesentlichen 0x0 Pixeln haben. Hat der Container, in dem das JPanel liegt, einen LayoutManager, der die preferredSize berücksichtigt, bleibt das JPanel unsichtbar.


Moment ich checke eben alles ab :D
 

linomail

Aktives Mitglied
So okay Das ist meine GUI:
Java:
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;



/**
* Created by AS on 27.09.2017.
*/
public class GUI extends JFrame {

    Map oldcircle;

    JFrame gui = new JFrame("TSP_OS");


    JMenuBar menuBar = new JMenuBar();
    Border bo = new LineBorder(Color.BLUE);

    JMenu menu = new JMenu("Menü");
    JMenu image = new JMenu("Graph");

    JMenuItem autoSave = new JMenuItem("Neu");
    JMenuItem load = new JMenuItem("Laden");
    JMenuItem save = new JMenuItem("Speichern");
    JMenuItem show = new JMenuItem("Anzeigen");


    public void struktur() {


        //Unsere größe
        gui.setSize(1000, 600);
        //Umrandung unserer Menüleiste
        menuBar.setBorder(bo);
        gui.setJMenuBar(menuBar);
        //Was der Menüleiste hinzugefügt wird
        menuBar.add(menu);
        menuBar.add(image);
        //Unterordnung
        menu.add(autoSave);
        menu.add(load);
        menu.add(save);
        image.add(show);
        Container panel = new DrawPanel();
        gui.getContentPane().add(panel,BorderLayout.CENTER);


        //anzeigen
        gui.setVisible(true);
    }

    public void initializeElements() {
        autoSave.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {


                JTextField tfCity = new JTextField();
                JTextField tfRoad = new JTextField();

                Object[] message = {"Stadt", tfCity, " Straßen", tfRoad};

                JOptionPane pane = new JOptionPane(message,
                        JOptionPane.PLAIN_MESSAGE,
                        JOptionPane.OK_CANCEL_OPTION);
                pane.createDialog(null, "Werte eingeben:").setVisible(true);

                oldcircle = new Map(Integer.parseInt(tfCity.getText()), Integer.parseInt(tfRoad.getText()));
                oldcircle.fillRandom();
                oldcircle.nearestNeighbour();
             

            }
        });
    }


    public static void main(String[] args) {

        GUI gui = new GUI();
        gui.struktur();
        gui.initializeElements();
    }


    private static class DrawPanel extends JPanel {

         DrawPanel()
        {
            super();
            setOpaque(false);// zeichne nicht alle bits
        }


        @Override
        protected void paintComponent(final Graphics g)
        {
            super.paintComponent(g);
        }

    }

}

Jetzt kommt die klasse wo sich die PaintCity- Methode befindet
public void paintCity(Graphics g) {


Java:
g.setColor(Color.RED);
        g.drawOval(xPos, yPos, 10, 10);
        g.setColor(Color.BLACK);
        g.fillOval(xPos, yPos, 10, 10);
        if (inTour)
            g.setColor(Color.blue);
        else
            g.setColor(Color.RED);
        g.drawString(name, xPos-name.length()*4, yPos+20);
        g.drawString(""+name+">"+ next, xPos - name.length() * 4, yPos + 36);
    }


}

Das obere erspare ich euch mal :D

Ich möchte nur die paintMethode überschreiben. Und in dem Panel anzeigen
 

linomail

Aktives Mitglied
Bestehend aus einem JFrame mit Menu und einer Instanz der Klasse DrawPanel mit einer überschriebenen paintComponent(Graphics g), in der nichts gezeichnet wird.

Ich sehe weder eine Klassen- noch eine Methodendeklaration.

warte ich schick mal einfach die komplette klasse

Java:
//Pakete
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.awt.*;
import java.util.HashSet;
import java.util.Set;

/**
* Created by Andrej Drobin
* Aufgabe der Klasse einzele Städte zu zeichen
* (roten Kreis mit 10 Pixeln Durchmesser)
*/
public class City
{

    //Variablen des Knotens
    String name;
    int xPos;
    int yPos;
    int next;
    boolean inTour;

    //eine Hashset der Klasse Road
    public final Set<Road> roads = new HashSet<>();

    /**
     * next und intour auf default
     * @param name der Name den man übergeben bekommt
     * @param xPos "
     * @param yPos "
     */
    public City(String name, int xPos, int yPos)
    {

        this.name = name;
        this.xPos = xPos;
        this.yPos = yPos;
        next = 0;
        inTour = false;

    }

    /**
     * übeschreibe die Werte als String
     * @return
     */
    @Override
    public String toString()
    {
        return "Name: " +name
                + ", X: " + xPos
                + ", Y: " +yPos;
    }


    /**
     * generiert unsere Struktur mit Text in der XML
     * @param doc
     * @param nodes
     */
    public void generateXML(Document doc, Element nodes)
    {
        Element node = doc.createElement("Knote");
        nodes.appendChild(node);
        Element name = doc.createElement("Name");
        name.setTextContent(this.name);
        node.appendChild(name);
        Element xPos = doc.createElement("XKoordinate");
        xPos.setTextContent("" + this.xPos);
        node.appendChild(xPos);
        Element yPos = doc.createElement("YKoordinate");
        yPos.setTextContent("" + this.yPos);
        node.appendChild(yPos);

    }

    public void paintCity(Graphics g) {

        g.setColor(Color.RED);
        g.drawOval(xPos, yPos, 10, 10);
        g.setColor(Color.BLACK);
        g.fillOval(xPos, yPos, 10, 10);
        if (inTour)
            g.setColor(Color.blue);
        else
            g.setColor(Color.RED);
        g.drawString(name, xPos-name.length()*4, yPos+20);
        g.drawString(""+name+">"+ next, xPos - name.length() * 4, yPos + 36);
    }


}

Java:
//Pakete

import java.awt.*;
import java.util.*;

/**
* Created by Andrej Drobin.
*/
public class Map {

    //2 Arrays
    City[] cities;
    Road[] roads;

    /**
     * warte auf Länge
     *
     * @param cietiesLength
     * @param roadsLength
     */
    public Map(int cietiesLength, int roadsLength) {
        cities = new City[cietiesLength];
        roads = new Road[roadsLength];
    }

    /**
     * Unser Generator
     * weist dank der Klasse Random werte zu
     */
    public void fillRandom() {
        Random r = new Random();

        //Schleiße zum setzten der Städte
        for (int i = 0; i < cities.length; i++) {
            //Grenze
            int xPos = r.nextInt(500);
            int yPos = r.nextInt(500);

            //trag ein
            cities[i] = new City("City" + i, xPos, yPos);
        }

        //für road
        for (int i = 0; i < roads.length; i++) {
            //vergibt Cities an Road
            int s = r.nextInt(cities.length);
            int t = r.nextInt(cities.length);

            int counter = 0;

            while (s == t && counter < 1000) {
                //ist gleich? ---> neue
                t = r.nextInt(cities.length);
                counter++;
            }
            //ungleich? ---> trag ein
            if (s != t) {
                //erstell Objekt
                Road newRoad = new Road(cities[s], cities[t]);
                //newRoad in Array zuweisen
                roads[i] = newRoad;

                //wenn gleich einträge
                if (cities[s].roads.contains(newRoad)) {
                    //rückwärts
                    i--;
                    //vill noch ein Counter rein -> wegen random
                    continue;
                } else {
                    cities[s].roads.add(newRoad);
                    cities[t].roads.add(newRoad);

                    System.out.println(newRoad);


                }

            }
        }
    }

    public String getCoord(City city)
    {
        return "X" + city.xPos +
                "Y" + city.yPos;
    }

    public void outPutCoords()
    {
        for (int i = 0; i < cities.length; i++)
            System.out.println("" + getCoord(cities[i]));
    }



    /**
     * @return Anzahl der Städte
     */
    public int amountCities() {
        return cities.length;
    }

    /**
     * @return Anzahl der Straßen
     */
    public int amountRoads() {
        return roads.length;
    }

    /**
     * @param i - die gesuchte road
     * @return
     */
    public Road returnRoad(int i) {
        if (i < 0 || i >= roads.length)
            return null;
        return roads[i];
    }

    /**
     * @param i - die gesuchte Cities
     * @return
     */
    public City returnCity(int i) {
        if (i < 0 || i >= cities.length)
            return null;
        return cities[i];
    }


    public double distance(int s1, int s2)
    {


        double dx, dy, dx2, dy2;

        dx = cities[s1].xPos - cities[s2].xPos;
        dy = cities[s1].yPos - cities[s2].yPos;
        dx2 = dx * dx;
        dy2 = dy * dy;

       return Math.sqrt(dx2 + dy2);


    }


    public int nextCity(int s) {
        double dist, min = 100000;
        int index = -1;

        int start = 0;

        while (start < amountCities()) {

            while ((start < amountCities()) && cities[start].inTour) start++;

            if (start >= amountCities()) {
                break;
            }

            dist = distance(start, start);

            if ((start != s) && (dist < min)) {
                min = dist;
                index = start;
            }
            start++;
        }
        return index;
    }

    public void nearestNeighbour()
    {
        int s = 0;

        for (int i=0; i<cities.length - 1; i++)
        {
            cities[s].inTour = true;
            cities[s].next = nextCity(s);
            s = cities[s].next;
        }
        cities[s].inTour = true;
        cities[s].next = 0;
    }



    public void paintCity(Graphics g){

        int i = 0;

        do {
            cities[i].paintCity(g);
            i++;
        }
        while (i < cities.length);

    }


    /**
    public void paintRoads(Graphics g)
    {

        int i = 0;

        do {
            roads[i].paintRoad(g);
            i++;
        }
        while (i < roads.length);
    }
     * @param g**/




    public void paint(Graphics g)
    {
        int next = 0;
        int x1, y1, x2, y2;
        do {

            cities[next].paintCity(g);
            x1 = cities[next].xPos;
            y1 = cities[next].yPos;
            next = cities[next].next;
            x2 = cities[next].xPos;
            y2 = cities[next].yPos;
            g.drawLine(x1,y1,x2,y2);
        }
        while (next !=0);

    }

das sind die beiden klasse in die möchte in meiner gui darstellen
 

Harry Kane

Top Contributor
Quick and dirty: gib deiner DrawPanel Klasse eine Referenz auf eine gut egfüllte Map-Instanz, und rufe in der paintComponent von DrawPanel die paint-Methode von Map auf.
Sauberer: mache eine bessere Trennung von Model (den Daten) und der View (dem Zeichnen). Die Map sollte nur für die Datenhaltung zuständig sein, und vom Zeichnen gar nichts wissen. Eine City sollte auch nicht wissen, wie sie sich zu zeichnen hat. Dann wird es nämlich schwieriger, das Zeichenverhalten zu ändern.
Vorschlag: benenne ein paar Getter-methode in Map um, und mache die Variablen xPos, yPos, name und next über Getter zugänglich. Dann könnte eine paintComponent in etwa so aussehen:
Java:
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int cc = 0; cc < map.getCityCount(); cc++) {//anstatt amountCities
            City city = map.getCity(cc);//anstatt returnCity(cc);
            if (city != null) {
                int xPos = city.getXPos();
                int yPos = city.getYPos();
                String name = city.getName();
                int next = city.getNext();
                g.setColor(Color.RED);
                g.drawOval(xPos, yPos, 10, 10);
                g.setColor(Color.BLACK);
                g.fillOval(xPos, yPos, 10, 10);
                if (city.inTour()) {
                    g.setColor(Color.blue);
                } else {
                    g.setColor(Color.RED);
                }
                g.drawString(name, xPos - name.length() * 4, yPos + 20);
                g.drawString("" + name + ">" + next, xPos - name.length() * 4, yPos + 36);
            }
        }
    }
 

linomail

Aktives Mitglied
Quick and dirty: gib deiner DrawPanel Klasse eine Referenz auf eine gut egfüllte Map-Instanz, und rufe in der paintComponent von DrawPanel die paint-Methode von Map auf.
Sauberer: mache eine bessere Trennung von Model (den Daten) und der View (dem Zeichnen). Die Map sollte nur für die Datenhaltung zuständig sein, und vom Zeichnen gar nichts wissen. Eine City sollte auch nicht wissen, wie sie sich zu zeichnen hat. Dann wird es nämlich schwieriger, das Zeichenverhalten zu ändern.
Vorschlag: benenne ein paar Getter-methode in Map um, und mache die Variablen xPos, yPos, name und next über Getter zugänglich. Dann könnte eine paintComponent in etwa so aussehen:
Java:
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int cc = 0; cc < map.getCityCount(); cc++) {//anstatt amountCities
            City city = map.getCity(cc);//anstatt returnCity(cc);
            if (city != null) {
                int xPos = city.getXPos();
                int yPos = city.getYPos();
                String name = city.getName();
                int next = city.getNext();
                g.setColor(Color.RED);
                g.drawOval(xPos, yPos, 10, 10);
                g.setColor(Color.BLACK);
                g.fillOval(xPos, yPos, 10, 10);
                if (city.inTour()) {
                    g.setColor(Color.blue);
                } else {
                    g.setColor(Color.RED);
                }
                g.drawString(name, xPos - name.length() * 4, yPos + 20);
                g.drawString("" + name + ">" + next, xPos - name.length() * 4, yPos + 36);
            }
        }
    }

bekomme folgende fehlermeldung
Java:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at GUI.paintComponent(GUI.java:11)
    at javax.swing.JComponent.paint(JComponent.java:1056)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paint(JComponent.java:1065)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paint(JComponent.java:1065)
    at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5217)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
    at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
    at javax.swing.JComponent.paint(JComponent.java:1042)
    at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
    at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
    at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
    at java.awt.Container.paint(Container.java:1975)
    at java.awt.Window.paint(Window.java:3904)
    at javax.swing.RepaintManager$4.run(RepaintManager.java:842)
    at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
    at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
 

linomail

Aktives Mitglied
bekomme folgende fehlermeldung
Java:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at GUI.paintComponent(GUI.java:11)
    at javax.swing.JComponent.paint(JComponent.java:1056)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paint(JComponent.java:1065)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paint(JComponent.java:1065)
    at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5217)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
    at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
    at javax.swing.JComponent.paint(JComponent.java:1042)
    at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
    at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
    at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
    at java.awt.Container.paint(Container.java:1975)
    at java.awt.Window.paint(Window.java:3904)
    at javax.swing.RepaintManager$4.run(RepaintManager.java:842)
    at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
    at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

ich hab einfach für getCityCount ---> eine return cities.length methode geschrieben, dernn genau diese Variable gebe ich ihm Map Konstruktor ein
 

Harry Kane

Top Contributor
Tja, ohne Code wird dir niemand helfen können. Die Fehlermeldung ist aber verdächtig. Laut stack trace tritt der Fehler in der paintComponent Methode von GUI auf. Dabei dürfte GUI (das Erweiterung von JFrame) gar keine paintComponent-Methode habe (es sei denn, du schreibst aus welchen Gründen auch immer eine).
Aus dem stack trace kann man sehen, dass du von der paint-Methode einer JComponent die paintComponent-Methode von GUI aufrufst. Ohne es genau zu kenne, behaupte ich mal, dass dieses Konstrukt falsch ist.
 

linomail

Aktives Mitglied
Tja, ohne Code wird dir niemand helfen können. Die Fehlermeldung ist aber verdächtig. Laut stack trace tritt der Fehler in der paintComponent Methode von GUI auf. Dabei dürfte GUI (das Erweiterung von JFrame) gar keine paintComponent-Methode habe (es sei denn, du schreibst aus welchen Gründen auch immer eine).
Aus dem stack trace kann man sehen, dass du von der paint-Methode einer JComponent die paintComponent-Methode von GUI aufrufst. Ohne es genau zu kenne, behaupte ich mal, dass dieses Konstrukt falsch ist.


warte ich gib dir den SOurce von der vorherigen version :/ vill kannst du mir dann mit nem pseudocode aushelfen
Java:
import java.awt.*;
import java.util.Random;

/**
* Created by AS on 07.05.2017.
*/
//Die Hauptklasse der TSP-Software
public class Map {

    private double costs[][];

    //2 Arrays Cities und Roads(Kanten)
    City[] city;
    Road[] roads;

    //Konstruktor wartet auf die Größe der beiden Arrays und erzeugt diese auch
    public Map(int cityLength, int roadLength) {
        city = new City[cityLength];
        roads = new Road[roadLength];
    }

    //Der Generator füllt die Arrays mit Werten
    public void fillRandom() {

        Random random = new Random();

        for (int i = 0; i < city.length; i++) {
            int xPos = random.nextInt(500);
            int yPos = random.nextInt(500);
            city[i] = new City("City" + i, xPos, yPos);

        }

        for (int i = 0; i < roads.length; i++) {
            int s = random.nextInt(city.length);
            int t = random.nextInt(city.length);

            int counter = 0;
            while (s == t && counter < 1000) {
                counter++;
                t = random.nextInt(city.length);
            }
            if (s != t) {
                roads[i] = new Road(city[s], city[t]);
            }

        }

        outPutCoords();
    }
    public String getCoord(City city)
    {
        return "X" + city.xPos +
                "Y" + city.yPos;
    }

    public void outPutCoords()
    {
        for (int i = 0; i < city.length; i++)
        System.out.println("" + getCoord(city[i]));
    }

    //Rückgabewert der amountCities
    public int amountCities() {
        return city.length;

    }

    //Rückgabewert der amountRoads
    public int amountRoads() {
        return roads.length;
    }

    //Rückgabewert der Road
    public Road returnRoad(int i) {
        if (i < 0 || i >= roads.length)
            return null;
        return roads[i];
    }

    //Rückgabewert der City
    public City returnCity(int i) {
        if (i < 0 || i >= city.length)
            return null;

        return city[i];
    }



    public void paintCity(Graphics g){

        int i = 0;

        do {
            city[i].paintCity(g);
            i++;
        }
        while (i < city.length);

    }



    public void paintRoads(Graphics g)
    {

        int i = 0;

        do {
            roads[i].paintRoad(g);
            i++;
        }
        while (i < roads.length);
    }

   // public double calcCost(int route){
  //  return calcCost(route, false);
    //}

    //public double calcCost(int route, boolean isVerbosse){
      //  double travelcost = 0;
  //      for (int i = 1; i < route.length; i++){
    //        travelcost += costs[route[i-1]][route[i]];
      //  }
    //}

    private double distance(int s1, int s2)
    {
        double dx, dy, dx2, dy2;

        dx = city[s1].xPos - city[s2].xPos;
        dy = city[s1].yPos - city[s2].yPos;
        dx2 = dx * dx;
        dy2= dy *dy;

        return Math.sqrt(dx2 + dy2);
    }



    public int nextCity(int s) {
        double dist, min = 100000;
        int index = -1;

        int start = 0;

        while (start < amountCities()) {
            while ((start < amountCities()) && city[start].inTour) start++;

            if (start >= amountCities()) {
                break;
            }

            dist = distance(start, start);

            if ((start != s) && (dist < min)) {
                min = dist;
                index = start;
            }
            start++;
        }
        return index;
    }

    public void nearestNeighbour()
    {
        int s = 0;

        for (int i=0; i<city.length - 1; i++)
        {
            city[s].inTour = true;
            city[s].next = nextCity(s);
            s = city[s].next;
        }
        city[s].inTour = true;
        city[s].next = 0;
    }


    public void paint(Graphics g)
    {
     int next = 0;
     int x1, y1, x2, y2;
     do {
         city[next].paintCity(g);
         x1 = city[next].xPos;
         y1 = city[next].yPos;
         next = city[next].next;
         x2 = city[next].xPos;
         y2 = city[next].yPos;
         g.drawLine(x1,y1,x2,y2);
     }
     while (next !=0);

    }
Code:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.awt.*;


/**
* Created by AS on 07.05.2017.
*/
public class City {
    //Datenstrukturen der Cities und um das TSP zu lösen
    String name = "City";
    int xPos, yPos;
    int next;
    boolean inTour;


    //Konstruktor um Cities zu erstellen
    public City(String name, int xPos, int yPos) {
        this.xPos = xPos;
        this.yPos = yPos;

        next = 0;
        inTour = false;
        this.name = name;
    }

    //Methode zum aufbau der XML - Datei/erstellung Eltern --> Kinder
    public void generateXML(Document doc, Element nodes) {
        Element node = doc.createElement("Node");
        nodes.appendChild(node);
        Element name = doc.createElement("Name");
        name.setTextContent(this.name);
        node.appendChild(name);

        Element xPos = doc.createElement("XKoordinate");
        xPos.setTextContent("" + this.xPos);
        node.appendChild(xPos);
        Element yPos = doc.createElement("YKoordinate");
        yPos.setTextContent("" + this.yPos);
        node.appendChild(yPos);


    }

    //Hier werden name xPos und yPos zurückgegeben
    @Override
    public String toString() {
        return "Name: " + name
                + ", X: " + xPos
                + ", Y:" + yPos;
    }


    public void paintCity(Graphics g) {

        g.setColor(Color.RED);
        g.drawOval(xPos, yPos, 10, 10);
        g.setColor(Color.BLACK);
        g.fillOval(xPos, yPos, 10, 10);
        if (inTour)
            g.setColor(Color.blue);
        else
            g.setColor(Color.RED);
        g.drawString(name, xPos-name.length()*4, yPos+20);
        g.drawString(""+name+">"+ next, xPos - name.length() * 4, yPos + 36);
    }

Das sind die einzigen Klassen die Wirklich zählen
Wie würdest du die Paint-Methode schreiben?

Mein versuch:
Java:
import javax.swing.*;
import java.awt.*;

public class GUI{

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }


    private static void createAndShowGUI()
    {
        System.out.println("Bla? " + SwingUtilities.isEventDispatchThread());
        JFrame f = new JFrame("TSP_OS");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        DrawPanel dpn1 = new DrawPanel();
        f.add(dpn1);
        f.pack();
        f.setVisible(true);


    }
}

class DrawPanel extends JPanel{

    Map map;

    public DrawPanel(){
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
    }

    public Dimension getPreferredSize()
    {
        return new Dimension(250,200);
    }

   
    public void paintCity(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < map.cities.length; i++) {//anstatt amountCities
            City city = map.getCity(i);//anstatt returnCity(cc);
            if (city != null) {
                int xPos = city.getxPos();
                int yPos = city.getyPos();
                String name = city.getName();
                int next = city.getNext();
                g.setColor(Color.RED);
                g.drawOval(xPos, yPos, 10, 10);
                g.setColor(Color.BLACK);
                g.fillOval(xPos, yPos, 10, 10);
                if (city.isInTour()) {
                    g.setColor(Color.blue);
                } else {
                    g.setColor(Color.RED);
                }
                g.drawString(name, xPos - name.length() * 4, yPos + 20);
                g.drawString("" + name + ">" + next, xPos - name.length() * 4, yPos + 36);
            }
        }
    }




    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        paintCity(g);



    }
 

Harry Kane

Top Contributor
Die Variablen city und roads der Map-Klasse sollten private sein (Kapselung), und die einzelnen cities und roads nur über getter zugänglich sein.
Der Fehler kommtr daher, weil die Variable map vom Typ Map in der Klasse DrawPanel zwar deklariert ist, aber nie einen Wert bekommt. Ich sehe eh grade nicht, wo du überhaupt eine Instanz von Map erstellst. Im einfachsten Fall in deiner GUI-KLasse eine Instanz von Map erstellen, dann eine INstanz von DrawPanel, und die Map-Instanz an den Konstruktor von Map übergeben. Dazu musst du lediglich die DrawPanel-Klasse um einen passenden Konstruktor ergänzen.
 

linomail

Aktives Mitglied
naja das hatte ich vorher

Java:
Map map = new Map(5,15)
und die Map-Instanz an den Konstruktor von Map übergeben. .

das wäre doch das da oben?
 

Oben