Mehrere Zeichnungen zeichnen

Schrubber

Bekanntes Mitglied
Hallo Ihr,

Ich zeichne auf meinen JFrame ein Bild mit drawOval();.
Nun möchte ich daneben ein weiteres Bild mit drawLine(); zeichnen, jedoch verschwindet das 1. Bild und nur das letzte wird angezeigt. Wie kann ich das umgehen?


Danke, Schrubber
 
oder auch in einem Panel die Zeichenbefehle nebeneinander setzen, wenn irgendwas verschwindet klingt das nach grundlegenderen Problemen..
 
Klingt nach getGraphics.
Ich würde die Objekte von einen Interface erben lassen, eine globale paint(Graphics) oder ähnliches definieren, sie in eine Collection eintragen und im paint bzw. paintComponent zeichnen lassen.
 
Hier mein bisheriger Code

Java:
import javax.swing.*;

public class Arbeitsblatt extends JComponent
{
	public static void main(String[] args)
	{
		JFrame frame = new JFrame("Schrubber´s TestTool");
		frame.setSize(400, 400);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		frame.add(new Form(10,10,50,50));//Strich
		//frame.add(new Form(110,110,90,90,1));//Rechteck
		frame.add(new Form(50,50,40));//Kreis
	}
}

Java:
import java.awt.Graphics;

public class Form extends Arbeitsblatt
{
	Daten d = new Daten();
	public Form(int x1, int y1, int x2, int y2)//Linie
	{
		d.setX1(x1);
		d.setY1(y1);
		d.setX2(x2);
		d.setY2(y2);
		d.setModus(1);
	}
	public Form(int x1, int y1, int x2, int y2, int modus)//Rechteck
	{
		d.setX1(x1);
		d.setY1(y1);
		d.setX2(x2);
		d.setY2(y2);
		d.setModus(2);
	}
	public Form(int x1, int y1, int radius)//Kreis
	{
		d.setX1(x1);
		d.setY1(y1);
		d.setHeight(radius*2);
		d.setWidth(radius*2);
		d.setModus(3);
	}
	
	public void paint(Graphics g)
	{
		super.paint(g);
		if(d.getModus()==1)
		{
			g.drawLine(d.getX1(),d.getY1(),d.getX2(),d.getY2());
		}
		else
		{
			if(d.getModus()==2)
			{
			g.drawRect(d.getX1(),d.getY1(),d.getX2(),d.getY2());
			}
			else
			{
				g.drawOval(d.getX1(), d.getY1(), d.getWidth(), d.getHeight());
			}
		}
	}
}

Java:
public class Daten
{
	private int x1;
	private int y1;
	private int x2; 
	private int y2;
	private int height;
	private int width;
	private int modus;
	
	public void setX1(int x1)
	{
		this.x1 = x1;
	}
	public int getX1()
	{
		return x1;
	}
	public void setY1(int y1)
	{
		this.y1 = y1;
	}
	public int getY1()
	{
		return y1;
	}
	public void setX2(int x2)
	{
		this.x2 = x2;
	}
	public int getX2()
	{
		return x2;
	}
	public void setY2(int y2)
	{
		this.y2 = y2;
	}
	public int getY2()
	{
		return y2;
	}
	public void setHeight(int height)
	{
		this.height = height;
	}
	public int getHeight()
	{
		return height;
	}
	public void setWidth(int width)
	{
		this.width = width;
	}
	public int getWidth()
	{
		return width;
	}
	public void setModus(int modus)
	{
		this.modus = modus;
	}
	public int getModus()
	{
		return modus;
	}
}

Wird halt nur der Kreis gezeichnet und die Linie verschwindet ;-/
 
vorher irgendwelche Grundlagen, auch nur ein einziges funktionierendes Swing-Beispiel angeschaut?
Galileo Computing :: Java ist auch eine Insel – 20 Grafikprogrammierung
20.1 Grundlegendes zum Zeichnen

20.1.1 Die paint()-Methode für das AWT-Frame

20.1.2 Zeichnen von Inhalten auf ein JFrame
[..]
Allerdings überschreiben eigene Unterklassen von Swing-Komponenten im Regelfall nicht paint(), sondern paintComponent(). Das liegt daran, dass Swing in paint() zum Beispiel noch Rahmen zeichnet und sich um eine Pufferung des Bildschirminhalts zur Optimierung kümmert. So ruft paint() die drei Methoden paintComponent(), paintBorder() und paintChildren() auf, und [..]

ob das der Grund ist kann freilich sofort nicht mit Sicherheit gesagt werden,
ich probier den Code jetzt noch aus
 
Zuletzt bearbeitet von einem Moderator:
Gerade getestet, am Resultat aber keine Änderung.

Arbeitsblatt, gute Frage. Ihr wisst genauso viel, wie ich. Mehr als das Script habe ich nämlich auch nicht.
 
weitere Fehler:
setVisible(true) erst am Ende aufrufen ansonsten na jeder GUI-Änderung aufwendig das Layout neu berechnen

Layoutwahl, BorderLayout nimmt nur eine Komponente auf, jede neue überschreibt die alte,

wenn auf anderes Layout gewechset wird, dann müssen die Subkomponenten eine Größe haben, sonst standardmäßig 0x0 Pixel,

hier kurz ein vollständiges Skript, wobei die Code-Wiederholung in den Form-Konstruktoren nicht zu empfehlen ist,
ohne irgendwelche Swing-Kenntnisse ist das natürlich nur ein einmaliger Schub, jeden Tag muss man 100 Grundlagen bedenken

Java:
zusätzlich
import javax.swing.BorderFactory;



public class Test
{


    public static void main(String[] args)
    {
        JFrame frame = new JFrame("Schrubber´s TestTool");
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        frame.add(new Form(10, 10, 50, 50));// Strich
        frame.add(new Form(10, 10, 50, 50));// Strich
        frame.add(new Form(10, 10, 50, 50));// Strich
        frame.add(new Form(110, 110, 90, 90, 1));// Rechteck
        frame.add(new Form(50, 50, 40));// Kreis

        frame.setVisible(true);
    }
}


class Arbeitsblatt
    extends JComponent
{
    
}


class Form
    extends Arbeitsblatt
{
    Daten d = new Daten();

    public Form(int x1, int y1, int x2, int y2)// Linie
    {
        setPreferredSize(new Dimension(100, 100));
        setBorder(BorderFactory.createLineBorder(Color.BLUE));

        d.setX1(x1);
        d.setY1(y1);
        d.setX2(x2);
        d.setY2(y2);
        d.setModus(1);
    }

    public Form(int x1, int y1, int x2, int y2, int modus)// Rechteck
    {
        setPreferredSize(new Dimension(100, 100));
        setBorder(BorderFactory.createLineBorder(Color.BLUE));
        d.setX1(x1);
        d.setY1(y1);
        d.setX2(x2);
        d.setY2(y2);
        d.setModus(2);
    }

    public Form(int x1, int y1, int radius)// Kreis
    {
        setPreferredSize(new Dimension(100, 100));
        setBorder(BorderFactory.createLineBorder(Color.BLUE));
        d.setX1(x1);
        d.setY1(y1);
        d.setHeight(radius * 2);
        d.setWidth(radius * 2);
        d.setModus(3);
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if (d.getModus() == 1)
        {
            g.drawLine(d.getX1(), d.getY1(), d.getX2(), d.getY2());
        }
        else
        {
            if (d.getModus() == 2)
            {
                g.drawRect(d.getX1(), d.getY1(), d.getX2(), d.getY2());
            }
            else
            {
                g.drawOval(d.getX1(), d.getY1(), d.getWidth(), d.getHeight());
            }
        }
    }
}
 
Java:
		frame.add(new Form(10,10,50,50));//Strich
		//frame.add(new Form(110,110,90,90,1));//Rechteck
		frame.add(new Form(50,50,40));//Kreis
JFrame nutzt standardmäßig das BorderLayout. Ein einfaches
Code:
add(Component)
platziert die Komponente im CENTER Bereich des Frames. Wird eine zweite Komponente an die selbe Stelle hinzugefügt fliegt die erste raus. Also entweder einen anderen LayoutManager verwenden oder die zweite Komponent in einem andern Bereich platzieren.
 
oder doch leichter zurück zu einer ursprünglichen Idee:
nur eine Komponente zum Zeichnen nehmen, in deren paintComponent eine Liste von den schon vorhandenen schönen reinen Daten-Objekten abarbeiten
 
SlaterB, hab ich nicht ganz verstanden🙂 Kannst du das bitte genauer erläutern?

Also mein Programm wird sowas wie ein Paint, soll halt übereinander zeichenbar sein und nicht nur nebeneinander :S
 
du erstellst dir eine Komponente Form, fügst diese wie du selber am Anfang hast ins JFrame ein,
dann wird sie praktischerweise gleich maximiert, achte aber auf setVisible(true) erst am Ende

in das eine Form füge mehrere Daten-Objekte ein, dafür kompliziere Form-Konstruktoren ist sowieso bisschen unnötig,
du brauchst in dem einem Form-Objekt eine Liste, in paintComponent diese Liste durchgehen,

auch das alles braucht natürlich Kenntnisse, hmm..
 
Bin derweil soweit:

Java:
import java.awt.*;

import javax.swing.*;


public class Arbeitsblatt extends JComponent
{
	public static void main(String[] args)
	{
		/*
		JFrame frame = new JFrame("Schrubber´s TestTool");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JComponent newContentPane = new LayeredPane();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);
        frame.setSize(400,400);
        newContentPane.setSize(400,400);
        frame.add(new Form(0,0,200,200));
        frame.add(new Form(0,0,200,200,1));
        frame.add(new Form(0,0,50));
        frame.pack();
        frame.setVisible(true);
        */
		erstelleGUI();
	}
	public static void erstelleGUI()
	{		
		JFrame frame = new JFrame("Schrubber´s TestTool");
        JComponent newContentPane = new LayeredPane();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(newContentPane);
        frame.setSize(400,400);
        frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
        newContentPane.setOpaque(true);
        newContentPane.setSize(400,400);
        
        JPanel draw1 = new JPanel();
        draw1.setLayout(new GridLayout());
//        draw1.setLayout(new BoxLayout(draw1, BoxLayout.LINE_AXIS));
        draw1.add(new Form(50,50,100,100));
        
        JPanel draw2 = new JPanel();
        draw2.setLayout(new GridLayout());
//        draw2.setLayout(new BoxLayout(draw1, BoxLayout.LINE_AXIS));
        draw2.add(new Form(50,50,100,100));

        newContentPane.add(draw1);
        newContentPane.add(draw2);
        frame.pack();
        frame.setVisible(true);
	}
	
}

Java:
import java.awt.Color;

public class Daten
{
	private int x1;
	private int y1;
	private int x2; 
	private int y2;
	private int height;
	private int width;
	private int modus;
	private Color color;
	private boolean befehl = false;
	
	public void setX1(int x1)
	{
		this.x1 = x1;
	}
	public int getX1()
	{
		return x1;
	}
	public void setY1(int y1)
	{
		this.y1 = y1;
	}
	public int getY1()
	{
		return y1;
	}
	public void setX2(int x2)
	{
		this.x2 = x2;
	}
	public int getX2()
	{
		return x2;
	}
	public void setY2(int y2)
	{
		this.y2 = y2;
	}
	public int getY2()
	{
		return y2;
	}
	public void setHeight(int height)
	{
		this.height = height;
	}
	public int getHeight()
	{
		return height;
	}
	public void setWidth(int width)
	{
		this.width = width;
	}
	public int getWidth()
	{
		return width;
	}
	public void setModus(int modus)
	{
		this.modus = modus;
	}
	public int getModus()
	{
		return modus;
	}
	public boolean isBefehl()
	{
		return befehl;
	}
	public void setBefehl(boolean befehl)
	{
		this.befehl = befehl;
	}
	
}

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

public class Form extends Arbeitsblatt
{
	Daten d = new Daten();
	Protokoll p = new Protokoll();
	public Form(int x1, int y1, int x2, int y2)//Linie
	{
		d.setX1(x1);
		d.setY1(y1);
		d.setX2(x2);
		d.setY2(y2);
		d.setModus(1);
	}
	public Form(int x1, int y1, int x2, int y2, int modus)//Rechteck
	{
		d.setX1(x1);
		d.setY1(y1);
		d.setX2(x2);
		d.setY2(y2);
		d.setModus(2);
	}
	public Form(int x1, int y1, int radius)//Kreis
	{
		d.setX1(x1);
		d.setY1(y1);
		d.setHeight(radius*2);
		d.setWidth(radius*2);
		d.setModus(3);
	}
		
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		if(d.getModus()==1)
		{
			if(d.isBefehl())
				g.setColor(null);
			g.drawLine(d.getX1(),d.getY1(),d.getX2(),d.getY2());
		}
		else
		{
			if(d.getModus()==2)
			{
				if(d.isBefehl())
					g.setColor(null);
			g.drawRect(d.getX1(),d.getY1(),d.getX2(),d.getY2());
			}
			else
			{
				if(d.isBefehl())
					g.setColor(null);
				g.drawOval(d.getX1(), d.getY1(), d.getWidth(), d.getHeight());
			}
		}
	}
}

Java:
import java.awt.*;

import javax.swing.*;

public class LayeredPane extends JPanel
{
	public LayeredPane()    
    {
		setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    }
}

Nun kann ich zumindest mehrere Sachen zeichnen, aber die werden nebeneinander oder untereinander angezeigt, jedoch nicht übereinander 🙁 Helft mir bitte.
 
Wenn du so etwas wie Paint haben möchtest würde ich empfehlen ein BufferedImage zu benutzen.
Dieses legst du in eine Variable und holst die jedes mal beim Ändern mit getGraphics das Graphics object.
In das Graphics Object zeichnest du dann und malst jedes mal das BufferedImage beim Paint aufruf per g.drawImage.

Nicht der schönste Weg sollte aber problemlos funktionieren.
 
wie gesagt ein Form mit mehreren Daten,
die Konstruktoren in Form sollten immer noch weg,

hast du eigentlich irgendwas geändert? ok, GridLayout..,
nur 'helfen' funktioniert nicht
 

Neue Themen


Zurück
Oben