Line2D

unknown

Bekanntes Mitglied
Hallo
Ich habe im Forum kein passendes Topic für meine Frage gefunden, deshalb eröffne ich mal eins.

Ich hätte eine Frage, und zwar wenn ich in einer Methode ausserhalb von "public void paintComponent(Graphics g)" Line2D.Double erstellen möchte, bekomme ich eine Exeption.

Mein code nach "public void paintComponent(Graphics g)"- Methode sieht wie folgt aus:

Java:
public void up()
	{	
		Line2D.Double myLine = new Line2D.Double(50, 40, 70, 40);	
		g2.draw(myLine);
		
	}

Weiss jemand wie man dieses Problem beheben kann?

Ich danke euch im Vroaus für eure Antworten.
 
Zuletzt bearbeitet:

unknown

Bekanntes Mitglied
es ist einbisschen zu lang, deshalb hatte ich es nicht kopiert:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at LineComponent.up(LineComponent.java:39)
at LineComponent.paintComponent(LineComponent.java:25)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at java.awt.Window.paint(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$700(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at LineComponent.up(LineComponent.java:39)
at LineComponent.paintComponent(LineComponent.java:25)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at java.awt.Window.paint(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$700(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
 

unknown

Bekanntes Mitglied
Da wäre die ganze Klasse:

[Java]
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;


public class LineComponent extends JComponent
{
int pointX;
int pointY;
Graphics2D g2;


public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
up();


}

public void setPosition(int x, int y)
{
int pointX = x;
int pointY = y;
}

public void up()
{
Line2D.Double myLine = new Line2D.Double(50, 40, 70, 40);
g2.draw(myLine);


}



}[/Java]
 

diggaa1984

Top Contributor
da haben wirs doch schon .. das g2 in Zeile 16 hat nix mit dem in Zeile 11 zu tun. Übergeb doch den Graphic-context per Parameter an die Methode up und entferne es als Klassenvariable

Java:
public void up(Graphics2D g2) {   
    Line2D.Double myLine = new Line2D.Double(50, 40, 70, 40);
    g2.draw(myLine);
}
 

unknown

Bekanntes Mitglied
Das hab' ich auch probiert, geht aber trotzdem nicht.

dann wird auf der Zeile 17 up(); rot unterstrichen.



Da wäre die Exeption:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at LineComponent.up(LineComponent.java:39)
at LineComponent.paintComponent(LineComponent.java:25)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at java.awt.Window.paint(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$700(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at LineComponent.up(LineComponent.java:39)
at LineComponent.paintComponent(LineComponent.java:25)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at java.awt.Window.paint(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$700(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
 

diggaa1984

Top Contributor
Java:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
 
 
public class LineComponent extends JComponent {
    int pointX;
    int pointY;
    
    
    public void paintComponent(Graphics g) {
        up((Graphics2D) g);
    }
    
    public void setPosition(int x, int y) {
        pointX = x; //kein int davor! sonst ist es wieder nur lokale variable
        pointY = y;
    }
    
    public void up(Graphics2D g2) {   
        Line2D.Double myLine = new Line2D.Double(50, 40, 70, 40);
        g2.draw(myLine);   
    }
}

du musst natürlich den parameter angeben, wenn die methode einen verlangt!
 

unknown

Bekanntes Mitglied
Besten Dank nun funktionierts.

Allerdings bin ich gleich auf das nächste Poroblem gestossen:

Wie muss ich das Programm umschreiben, dass die Variablen pointX und pointY (Zeile 25 und 26) die Werte annehmen, die ich auf der Zeile 17 setPosition(50, 70); eingebe?

Java:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;


public class LineComponent extends JComponent
{
	int pointX;
	int pointY;
	Graphics2D g2;
	
	
	public void paintComponent(Graphics g)
	{
		Graphics2D g2 = (Graphics2D)g;
		setPosition(50, 70);
		up((Graphics2D) g, 50);


	}
	
	public void setPosition(int x, int y)
	{
		int pointX = x;
		int pointY = y;
	}
	
	public void up(Graphics2D g2, int numberOfPixel)
	{	
		Line2D.Double myLine = new Line2D.Double(pointX, pointY, pointX, (pointY - numberOfPixel));
		g2.draw(myLine);

		
	}
	


}
 

unknown

Bekanntes Mitglied
[Java]
public void down(Graphics2D g)
{
if (i == 10)
{
Line2D.Double myLine = new Line2D.Double(pointX, pointY, pointX, (pointY + nrOfPixel));
g.draw(myLine);
System.out.println ("hello");
pointY = pointY + nrOfPixel;
i = 0;
//right((Graphics2D) g);
}
}
[/Java]
 

unknown

Bekanntes Mitglied
Hallo

Kann mir jemand sagen, wieso "myLine" nicht gezeichnet wird, wenn ich das ganze in eine "if"-Schleife setze? Ohne die Schleife funktioniert es.

Und eine zweite Frage:
Wenn ich mehrere Linien darstellen möchte, und nicht jedes Mal eine neue Variable (myLine1, Myline2, etc.) deklarieren möchte, was gibt es für eine Möglichkeit?

[Java]
public void down(Graphics2D g)
{
int i = 10;
if (i == 10)
{
Line2D.Double myLine = new Line2D.Double(pointX, pointY, pointX, (pointY + nrOfPixel));
g.draw(myLine);
System.out.println ("hello");
pointY = pointY + nrOfPixel;
i = 0;
}
}
[/Java]
 
Zuletzt bearbeitet:

diggaa1984

Top Contributor
Wenn ich mehrere Linien darstellen möchte, und nicht jedes Mal eine neue Variable (myLine1, Myline2, etc.) deklarieren möchte, was gibt es für eine Möglichkeit?

[Java]
public void down(Graphics2D g) {
int i = 10;
if (i == 10) {
g.draw(new Line2D.Double(pointX, pointY, pointX, (pointY + nrOfPixel)));
System.out.println ("hello");
pointY = pointY + nrOfPixel;
i = 0;
}//if
}
[/Java]
Du kannst es derart, ganz ohne explizite Variablenzuweisung gestalten. Da du ja eh nix weiter mit "myLine" machst ausser es einer Methode zu übergeben, brauchst es auch nicht zwingend als Variable deklarieren.

was hast es mit dem i auf sich?

du kannst aber auch einfach
Code:
drawLine(pointX, pointY, pointX, (pointY + nrOfPixel))
verwenden statt immer über
Code:
new Line2d.Double
gehen, ist übersichtlicher
 
Zuletzt bearbeitet:

unknown

Bekanntes Mitglied
Die if-Schleife oder (while) soll später dazu dienen, dass die Spirale aufhört, wenn es einen gewissen Wert hat.

Nun sieht mein Code so aus und ich bekomme trotzdem eine Exeptionen wenn ich von "left" zu "down" gehen möchte.

Java:
public void down(Graphics2D g)
    {   
        int i = 1;   
        if (i == 1) 
        {
            //g.draw(new Line2D.Double(pointX, pointY, pointX, (pointY + nrOfPixel)));
            g.drawLine(pointX, pointY, pointX, (pointY + nrOfPixel));
            pointY = pointY + nrOfPixel;
            i=0;
            right((Graphics2D) g);
        }

    }
    
    public void right(Graphics2D g)
    {   

    	g.drawLine(pointX, pointY, (pointX + nrOfPixel), pointY);
        pointX = pointX + nrOfPixel;
        up((Graphics2D) g);

    }
    
    public void up(Graphics2D g)
    {   

    	g.drawLine(pointX, pointY, pointX , (pointY - nrOfPixel));
        pointY = pointY - nrOfPixel;
        nrOfPixel = (int) nrOfPixel * 85 / 100;
        left((Graphics2D) g);
    }

    
    public void left(Graphics2D g)
    {   
    	
    	g.drawLine(pointX, pointY, (pointX - nrOfPixel), pointY);
        pointX = pointX - nrOfPixel; 
        nrOfPixel = nrOfPixel * 85 / 100;
        down((Graphics2D) g);
        
    }

p.s. welche Regel sprechen dagegen, dass man "myLine" in jeder Methode nur einmal verwenden darf?


die Exeption:
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at sun.java2d.d3d.D3DGraphicsDevice.getContext(Unknown Source)
at sun.java2d.d3d.D3DSurfaceData.getContext(Unknown Source)
at sun.java2d.d3d.D3DSurfaceData.getContext(Unknown Source)
at sun.java2d.pipe.BufferedContext.validateContext(Unknown Source)
at sun.java2d.d3d.D3DRenderer.validateContext(Unknown Source)
at sun.java2d.pipe.BufferedRenderPipe.drawLine(Unknown Source)
at sun.java2d.SunGraphics2D.drawLine(Unknown Source)
at LineComponent.up(LineComponent.java:59)
at LineComponent.right(LineComponent.java:52)
at LineComponent.down(LineComponent.java:42)
at LineComponent.left(LineComponent.java:72)
at LineComponent.up(LineComponent.java:62)
at LineComponent.right(LineComponent.java:52)
at LineComponent.down(LineComponent.java:42)
at LineComponent.left(LineComponent.java:72)
at LineComponent.up(LineComponent.java:62) etc.
 
Zuletzt bearbeitet:

diggaa1984

Top Contributor
stackoverflow = endlosschleife

down - right - up - left - down ...

warum kommt es dazu? Du setzt am Anfang der down-Methode ein neu erzeugtes i IMMER auf 1 .. und daher gehst du immer in die if-anweisung rein (if ist keine schleife :) )

und es spricht auch nix dagegen eine Variable nur 1x zu nutzen, ich finde es persönlich nur übersichtlichter wenn ich dann den new ... - Teil gleich als Parameter angebe, und nicht erst eine Variable deklariere, die ich dann weitergebe.
 
Zuletzt bearbeitet:

unknown

Bekanntes Mitglied
Ich meinte, wieso darf man in einer Methode so was:

Line2D.Double myLine = new Line2D.Double(pointX, pointY, pointX, (pointY + nrOfPixel));
g.draw(myLine);
Line2D.Double myLine = new Line2D.Double(pointX, pointY, pointX, (pointY + nrOfPixel));
g.draw(myLine);


nicht zweimal benutzen?
Da würde ich eine Exeption bekommen und müsste dann beispielsweise einmal myLine und einmal myLine2 verwenden.
wieso kann ich innerhalb von einer Methode die myLine nicht zwei mal definiert werden? das würde ja mit einer Variable gehen.

Also das wäre die ganze Klasse. Obwohl ich ganz am Anfang den Wert "i" als 1 definiert habe, wird die Methode Down trotzdem nicht ausgeführt:

Java:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
 
 
public class LineComponent extends JComponent
{
    int pointX;
    int pointY;
    Graphics2D g2;
    int nrOfPixel;
    int i = 1;

    
    
    public void paintComponent(Graphics g)
    {
    	
        Graphics2D g2 = (Graphics2D)g;
        setPosition(30, 10);
        nrOfPixel = 200;
        down((Graphics2D) g);
    	

    }
    
    public void setPosition(int x, int y)
    {
        pointX = x;
        pointY = y;
    }
    
    public void down(Graphics2D g)
    {    
        if (i == 1) 
        {
            //g.draw(new Line2D.Double(pointX, pointY, pointX, (pointY + nrOfPixel)));
            g.drawLine(pointX, pointY, pointX, (pointY + nrOfPixel));
            pointY = pointY + nrOfPixel;
            i=0;
            right((Graphics2D) g);
        }

    }
    
    public void right(Graphics2D g)
    {   

    	g.drawLine(pointX, pointY, (pointX + nrOfPixel), pointY);
        pointX = pointX + nrOfPixel;
        up((Graphics2D) g);

    }
    
    public void up(Graphics2D g)
    {   

    	g.drawLine(pointX, pointY, pointX , (pointY - nrOfPixel));
        pointY = pointY - nrOfPixel;
        nrOfPixel = (int) nrOfPixel * 85 / 100;
        left((Graphics2D) g);
    }

    
    public void left(Graphics2D g)
    {   
    	
    	g.drawLine(pointX, pointY, (pointX - nrOfPixel), pointY);
        pointX = pointX - nrOfPixel; 
        nrOfPixel = nrOfPixel * 85 / 100;
        down((Graphics2D) g);
        
    }
    
 
 
}
 

unknown

Bekanntes Mitglied
Also ich kapiere wirklich nicht, wie diese Graphic2D funktioniert..
Die Switch Schleife funktioniert auch nicht...

wieso wird die Linie nicht gezeichnet, wenn ich im "down" "control=2;" eingebe?

Java:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
 
 
public class LineComponent extends JComponent
{
    int pointX;
    int pointY;
    Graphics2D g2;
    int nrOfPixel;
    int i = 1;
    int control = 1;

    
    
    public void paintComponent(Graphics g)
    {
    	
        Graphics2D g2 = (Graphics2D)g;
        setPosition((Graphics2D)g, 10, 10);
        nrOfPixel = 200;
        //down((Graphics2D) g);
    	

    }
    
    public void setPosition(Graphics2D g, int x, int y)
    {
    	pointX = x;
    	pointY = y;
    	
    	
    	switch (control) {
    	
    	case 1:
    	down((Graphics2D) g);
    	break;
    	}
    	
    	
    }

    public void down(Graphics2D g)
     {  
    	g.drawLine(pointX, pointY, pointX, (pointY+nrOfPixel));
    	pointY = pointY + nrOfPixel; 
    	control = 2;
     }
 
 
}
 

njans

Top Contributor
Wenn du eine Variable definierst, dann gibst du auch immer einen Typ an, von dem die Variable ist:
Java:
String text;
int zahl;
MeineKlasse variablenName;
Wenn du nun aber sowas machst:
Java:
String text = "foo";
String text = "bar";
dann versuchst du eine Variable zweimal zu deklarieren, das lässt der Compiler nicht zu :)

paintComponent() wir ziemlich oft aufgerufen, vermutlich ist "i" am Anfang schon 1, aber durch den erneuten Aufruf bekommst du davon gar nichts mit :)
Pack doch mal ein System.out.println(i); an den Anfang von down(), dann wirst du sehen, dass das schon beim ersten mal 1 ist.
 

unknown

Bekanntes Mitglied
Ja, das hab' ich schon probiert und "i" hat den Wert 1.
Aber das, was in der Schleife ist wird trotzdem nicht ausgeführt.

Und ich weiss immer noch nicht wieso der Switch in meinem code nicht funktioniert, nur weil ich "control = 2;" eingegeben habe (ohne control=2; würde es funktioneren, bringt mir aber nicht viel, wenn ich den Wert nich ändern darf).

Ich weiss nicht was in diesem Graphics2D so anders ist das nichts so funktioniert, wie ich es definiere :)
 

diggaa1984

Top Contributor
so wird daraus n schuh:

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JComponent;


public class LineComponent extends JComponent {

	int pointX;
	int pointY;
	int nrOfPixel;
	int i = 1;

	public LineComponent(int width, int height) {
		setMinimumSize(new Dimension(width, height));
		setPreferredSize(new Dimension(width, height));
	}//

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		pointX = 250;
		pointY = 250;
		nrOfPixel = 200;
		i = 0;
		
		g.setColor(Color.RED);
		down((Graphics2D) (g.create()));
	}


	public void setPosition(int x, int y) {
		pointX = x;
		pointY = y;
	}


	public void down(Graphics2D g) {
		if (i <= 10) {
			g.drawLine(pointX, pointY, pointX, (pointY + nrOfPixel));
			pointY = pointY + nrOfPixel;
			i++;
			right(g);
		}
	}


	public void right(Graphics2D g) {
		g.drawLine(pointX, pointY, (pointX + nrOfPixel), pointY);
		pointX = pointX + nrOfPixel;
		up(g);
	}


	public void up(Graphics2D g) {
		nrOfPixel = (int) (nrOfPixel * 0.85);
		g.drawLine(pointX, pointY, pointX, (pointY - nrOfPixel));
		pointY = pointY - nrOfPixel;
		left(g);
	}


	public void left(Graphics2D g) {
		g.drawLine(pointX, pointY, (pointX - nrOfPixel), pointY);
		pointX = pointX - nrOfPixel;
		nrOfPixel = (int) (nrOfPixel * 0.85);
		down(g);
	}
}

mal abgesehen davon dass ich das leicht anders coden würde, aber so entspricht es deinem Ansatz, da verstehst es besser. Nun darfst du "raten" was der eigentliche Fehler war, der dafür sorgte das nichts zu sehen war :)

Ach und bitte nicht alles fett schreiben, liest sich auch in Normalschrift ganz gut ;)
 

unknown

Bekanntes Mitglied
also ich gehe mal davon aus, weil ich die "i"-Variable nicht in der "paintComponent" initialisiert hatte, sondern direkt in der Klasse.
Aber das sollte ja eigentlich auch gehen, oder?
 

diggaa1984

Top Contributor
das war ein teil, richtig .. du musst i jedesmal auf 0 setzen, da sonst deine down-methode nur am Anfang (wenn du noch gar nix siehst) komplett durchlaufen wird, wie du dir das vorstellst - danach allerdings wird die if-Bedingung einfach nicht mehr erfüllt, und du er zeichnet die Spirale nicht mehr, pinselt aber fleissig den Hintergrund vorher neu.

Weiterhin, hat deine Komponente keine Größenangaben gehabt, sodass dein Frame auch winzig wurde, mit dem pack() - Befehl. Du musst die Größe des JFrame nicht festlegen, wenn die Subkomponenten über Größeninformationen verfügen. Den Rest erledigen die Layout-Manager (null ist dabei nicht wirklich zu empfehlen)

sieht dann zB so aus:
Java:
public MyFrame(String title) {
    super(title); 
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    
    JPanel panel = new JPanel();
    panel.add(new LineComponent(700,700), BorderLayout.CENTER);
    
    add(panel);
    pack();
}
 

unknown

Bekanntes Mitglied
Ich versuche mir das vorzustellen, versteh aber den Ablauf trotzdem nicht.
Wieso muss man unbedingt in paintCompetent i auf 0 setzen. Das Programm sollte doch nur bevor die down-Methode aufgerufen wird einmal in paintComponent reingehen und dann nicht mehr, oder?
Wie ist der genaue Ablauf? (diese Methoden würden beispielsweise mit println funktionieren, ohne dass man in der Mainmethode i jedes mau auf 0 setzt).

Nun habe ich noch eine wichtigere Frage:
Ist Graphics2D überhaupt eine Klasse oder eine Methode?
Wieso muss man in paintComponent, (Graphics g) unbedignt als Parameter mitgeben?
soweit ich weiss gibt man weder Klassen noch Methoden als Parameter mit.
Was ist überhaupt "g"? :)

Java:
    /**
     * Macht vom Startpunkt aus um den Betrag numberOfPixel eine Linie in blau nach unten und legt danach den neuen Startpunt für die nächste Mehode fest
     * @param g ????
     * @param numberOfPixel legt die Anzahl von Pixel fest, um die sie die Linie nach unten zeichnet 
     */
    public void down(Graphics2D g, int numberOfPixel) { 	
        	g.setColor(Color.BLUE);
            g.drawLine(startPointX, startPointY, startPointX, (startPointY + numberOfPixel));
            startPointY = startPointY + numberOfPixel;
    }
 

hdi

Top Contributor
Nun habe ich noch eine wichtigere Frage:
Ist Graphics2D überhaupt eine Klasse oder eine Methode?
Wieso muss man in paintComponent, (Graphics g) unbedignt als Parameter mitgeben?
soweit ich weiss gibt man weder Klassen noch Methoden als Parameter mit.
Was ist überhaupt "g"?

Graphics2D ist eine Klasse. Graphics auch. Und stimmt, man gibt werder Klassen noch Methoden als Parameter mit - ist auch gar nicht möglich. (*in Java7, vllt kommen irgendwann Closures, dann wäre letzteres möglich).

Aber "g" ist keine Klasse, sondern eine Variable, die einen Wert referenziert. Wie schon vorher gesagt wurde ist Java streng typisiert, d.h. du musst für eine Variable immer einen Datentyp angeben, damit du weißt, was da drin steckt. Graphics g heißt: Du bekommst einen Wert vom Typ Graphics. Und wieso du das mitgeben musst? Weil du mit diesem g zeichnest. Was willste denn in die paintComponent schreiben, wenn du kein g hast?
 

unknown

Bekanntes Mitglied
Noch eine Frage:

Darf man in einer void Methode überhaupt so was machen:
pointY = pointY + nrOfPixel;

Wäre dies eigentlich nicht etwas für eine Return methode?:)

[Java]
public void down(Graphics2D g) {
if (i <= 10) {
g.drawLine(pointX, pointY, pointX, (pointY + nrOfPixel));
pointY = pointY + nrOfPixel;
i++;
right(g);
}
}
[/Java]
 

hdi

Top Contributor
Das eine hat mit dem anderen überhaupt nichts zu tun. Aber wenn ich mir diese Methode so ansehe, dann frag ich mich was du da anstellst. Lass deine Zeichnung mal besser in der paintComponent. Alles andere, zB Bestimmung oder Veränderung von Position usw kommt da raus, das machen andere Methoden. Aber misch nicht die Logik mit dem Zeichnen.
 

unknown

Bekanntes Mitglied
aber ist es nicht so, dass man solche Operationen generell in einer Return Methode macht?
Return benötigt man doch, wenn man einen Wert zurückhaben möchte.
Und bei diesem Beispiel will man den Wert pointY returniert haben, oder nicht?
 

hdi

Top Contributor
aber ist es nicht so, dass man solche Operationen generell in einer Return Methode macht?

Was meinst du mit solche? Eine Methode ist nicht-void, wenn sie dem Aufrufer irgendetwas zurückgeben muss. Das kann das Ergebnis einer Berechnung sein, oder auch einfach nur ein Wert, der dem Aufrufer sonst nicht zugänglich ist (siehe Getter).

Vllt ne Faustregel (Ausnahmen bestätigen die Regel): Wenn du dich an Stelle x im Code befindest, und nun willst du eine Methode aufrufen, dann gilt für diese Methode:
- sie ist nicht-void und returned etwas, wenn du dir denkst "ich brauch jetzt xy oder ich muss xy wissen"
- sie ist void und returned nix, wenn du dir denkst "ich will dass jetzt xy passiert".

Was willst du denn da grad genau machen? Zeig mal Code, das ist jetzt schwer zu verstehen was du meinst.
 

hdi

Top Contributor
Anhand von diesem Code lässt sich das aber nicht erklären ;) Ob diese Methode etwas returnen sollte oder nicht kann ich nur sagen wenn ich sehe wie diese Methode in dein Programm integriert ist, d.h. wo du sie aufrufst und wo du welche Werte verwendest. Wie gesagt, ich denke alleine die Existenz dieser Methode ist schon zu bemängeln...
 

unknown

Bekanntes Mitglied
ich nehme ein anders Beispiel, das etwas übersichtlicher ist:

wieso hat man sich bei der "getArea" Mehode für return und bei der "grow" Methode für void entschieden?
eigentlich würden ja beide Varianten für beide Methoden gehen. Sprich, sie könnten ja beide return oder void sein, oder nicht?


Java:
public class MySquare
{

private int sideL;
private int myArea;

public MySquare (int initialL)
{
sideLength = initialL;
getArea();
System.out.println(myArea);

}

public int getArea()
 {
myArea = sideL * sideL;

}

public void grow() 
 { 
  sideL = 2 * sideL;
 }

}
 

unknown

Bekanntes Mitglied
Meine letzte Frage hat sich geklärt :)

Aber könnte mir jemand verraten, was Paintcomponent eigentlich für eine Methode ist?
Es ist ja kein Konstruktor, verhält sich aber sehr ähnlich (wird ja automatisch ausgeführt ohne aufgerufen zu werden).
In meinen Beispiel mit der Schleife hat es sich gezeigt, dass der Ablauf einbisschen anders ist. Denn es spielt eine Rolle, ob ich "i" innerhalb von dieser Methode intialiesere, oder innerhalb der Klasse.
Ist es so, dass das Programm zunächst alle anderen Methoden ausführt und erst am Schluss die Paintcomponent?

Wieso schreibt man einmal so: Graphics2D und einmal so: (Graphics2D)g
[Java] Graphics2D g2 = (Graphics2D)g [/Java]

Ach und noch eine Frage, wo kann ich ein Beipsiel mit einer Static Methode oder Variable finden? Ich dachte static Attributen können in anderen Klassen gebraucht werden, ohne dass man von der entsprechenden Klasse eine Instanz machen muss, bei mir klappt es allerdings nicht :bahnhof:
 
Zuletzt bearbeitet:

hdi

Top Contributor
Aber könnte mir jemand verraten, was Paintcomponent eigentlich für eine Methode ist?
Es ist ja kein Konstruktor, verhält sich aber sehr ähnlich (wird ja automatisch ausgeführt ohne aufgerufen zu werden).
Ui, wo bitte wird ein Konstruktor automatisch aufgerufen? Ohne
Code:
new
kein Aufruf. Das einzig "komische" an der paintComponent-Methode ist, dass sie ein interner Thread (EDT) aufruft. Da wird einfach Code ausgeführt, den nicht du selbst geschrieben hast, aber trotzdem ist es ein stinknormaler Methodenaufruf.

In meinen Beispiel mit der Schleife hat es sich gezeigt, dass der Ablauf einbisschen anders ist. Denn es spielt eine Rolle, ob ich "i" innerhalb von dieser Methode intialiesere, oder innerhalb der Klasse.
Ist es so, dass das Programm zunächst alle anderen Methoden ausführt und erst am schluss die Paintcomponent?
paintComponent() wird immer dann aufgerufen, wenn die GUI sich neuzeichnen soll. D.h. immer wenn das Fenster sichtbar wird oder seine Größe verändert. Außerdem wird es aufgerufen wenn du selbst ein repaint() aufrufst.

Wieso Schreibt man einmal so: Graphics2D und einmal so: (Graphics2D)g
[Java] Graphics2D g2 = (Graphics2D)g [/Java]
paintComponent spezifiziert als Parameter etwas vom Typ Graphics, und nicht Graphics2D. Zur Laufzeit ist es allerdings ein Graphics2D-Objekt, aber um auf die Graphics2D-spezfiischen Methoden zugreifen zu können musst du casten. Es gibt einen unterschied zwischem deklarierten Datentyp und tatsächlichem Datentyp zur Laufzeit.

Ich dachte static Attributen können in anderen Klassen gebraucht werden, ohne dass man von der entsprechenden Klasse eine Instanz machen muss, bei mir klappt es allerdings nicht :bahnhof:
Ist schon richtig, was du dachtest. Natürlich muss die Variable/Methode für die andere Klasse sichtbar sein. Wenn du sie als private deklarierst ist sie nicht sichtbar. Ansonsten poste mal dein Beispiel.
 
Zuletzt bearbeitet:

unknown

Bekanntes Mitglied
paintComponent spezifiziert als Parameter etwas vom Typ Graphics, und nicht Graphics2D. Zur Laufzeit ist es allerdings ein Graphics2D-Objekt, aber um auf die Graphics2D-spezfiischen Methoden zugreifen zu können musst du casten. Es gibt einen unterschied zwischem deklarierten Datentyp und tatsächlichem Datentyp zur Laufzeit.

Was meinst du genau mit casten? Also was wäre der Unterschied zwischen Garphics2D und (Graphics2D)g?


Also wegen static... ich habe ein ganz einfaches Beispiel und bei mir funktioniert es nicht:
Java:
public class TestStatic {
	
	public static int myTest;

}

Java:
class Main {


	public static void main(String[] args) {
		myTest = 10;

	}

}

Error Meldung: "myTest cannot be resolved to a variable"
 

hdi

Top Contributor
Was meinst du genau mit casten? Also was wäre der Unterschied zwischen Garphics2D und (Graphics2D)g?

Graphics2D ist erstmal nur ein Datentyp, den du so zB als Datentyp für eine Variable deklarieren könntest. (Graphics2D)g hingegen ist eine Anweisung zur Laufzeit, und nennt sich Casten. Dabei wird der für g deklarierte Datentyp (also Graphics im Falle der paintComponent-Methode) zum Datentyp Graphics2D umgewandelt. Das funktioniert, sofern das tatsächlich durch g referenzierte Objekt eine Instanz von Graphics2D ist. Und das ist sie. Wie gesagt: Der deklarierte Datentyp entspricht nicht unbedingt dem tatsächlichen Datentyp der Instanz. Stichwort Dynamic Binding, Polymorphismus.. Du kannst auch sowas schreiben:

Java:
Auto a = new BMW(); // class BWM extends Auto

Aber jetzt hast du über a nur die Methoden der Klasse Auto zur Verfügung, obwohl es ein BMW ist. Hier könntest du auch casten:

Java:
BMW b = (BMW)a;

Und dann hast du über b auch alle Methoden der Klasse BMW. Intern wird paintComponent mit einem Graphics2D-Objekt aufgerufen, aber da die Signatur nur Graphics deklariert, musst du casten um auch an alle Methoden von Graphics2D zu kommen.

-----------------

Zum Static:

Du muss schon noch die Klasse angeben:

Java:
TestStatic.myTest = 10;

Sonst weiß Java ja nicht, wo diese Variable liegt. Alternativ kannst du ein static import der Klasse machen, dann könntest du den Klassennamen weglassen:

Java:
import static pfad.zur.klasse.TestStatic.myTest; // oder gleich TestStatic.*;
 
Zuletzt bearbeitet:

Oben