Zweimal im gleichen Paint-Fenster malen

jamesv

Bekanntes Mitglied
Hey Java-Forum-Gemeinschaft,

Mein Problem, dass ich habe, ist:

Wenn ich das Programm starte und zwei Kreise malen möchte, dann öffnen sich zwei Fenster. (Ich habe versucht, dass mittels Threads so zu ändern, dass das eine Fenster zeit versetzt geöffnet wird, das würde theoretisch klappen, nur wird leider der ganze Java-Thread gestoppt und der Nutzer kann keine Eingabe machen.)

Und wenn ich das eine Fenster ausgefüllt habe, mit den Daten, dann öffnet sich ein neues Fenster, in dem der Kreis gemalt wird. Nun fülle ich das zweite Fenster aus und es öffnet sich ein zweites Fenster, was ja klar ist, denn ich instanziere die Klasse ja noch mal, kann ich aber irgendwie, auf das selbe Objekt noch mal zugreifen, sodass aber das vorherige Oval nicht überschrieben wird?

Ich hoffe, ihr könnt mir helfen.
Vielen Dank schonmal im voraus 😀

Lg James.


Code:


Klasse Startup:


Java:
package basics;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class Startup
extends JFrame
implements ActionListener
{
	Kreis[] k;
	Kreis parent;
	Thread warten;
	Thread kreis;
	JFrame frame;
	Paint zeichnen;
	JLabel label;
	JTextField anzahl;
	JButton enter;
	JButton exit;
	int anz;
	
	private static final long serialVersionUID = 1L;
	
	
	public static void main(String[] args)
	{
		new Startup();
	}

	public Startup()
	{
//		parent.x = getX();
		
		
//		zeichnen = new Paint(x, y, d, fill);
		
//		warten = new Thread();
//		kreis = new Thread();
		
		frame = new JFrame();
		label = new JLabel();
		anzahl = new JTextField();
		enter = new JButton();
		exit = new JButton();
		
		enter.setText("Abschicken");
		exit.setText("Beenden");
		enter.setPreferredSize(new Dimension(120,25));
		exit.setPreferredSize(new Dimension( 120,25));
		
		enter.addActionListener(this);
		exit.addActionListener(this);
		
		anzahl.setPreferredSize(new Dimension(25,20));
		label.setPreferredSize(new Dimension(225,20));
		label.setText("Bitte die gewünschte Anzahl angeben:");
		
		frame.setSize(350,120);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLayout(new FlowLayout(FlowLayout.CENTER, 10,10));
		
		frame.add(label);
		frame.add(anzahl);
		frame.add(enter);
		frame.add(exit);
		
		frame.setVisible(true);
	}

/*
	public void run()
	{
		new Kreis();
	}
	
*/
	
	public void paint(Graphics g)
	{
		super.paint(g);
		g.setColor(Color.red);
		g.fillOval(5, 5, 50, 50);
	}
	
	@Override
	public void actionPerformed(ActionEvent ae)
	{
		if(ae.getSource() == enter)
		{
			frame.dispose();
			anz = Integer.parseInt(anzahl.getText());
//			System.out.println(anz);
			
			for (int i = 0; i < anz; i++)
			{
				new Kreis(this);
//				k[i] = new Kreis();
/*				
				try
				{
					Thread.sleep(2000);
				}
				catch(InterruptedException e)
				{
					System.out.print("Klappt nicht.");
				}
*/				
			}
		}
		else if (ae.getSource() == exit)
		{
			System.exit(0);
		}
	}
}

Klasse Kreis:

Java:
package basics;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class Kreis
extends JFrame
implements ActionListener
{
	Paint zeichnen;
	Startup parent;
	JLabel labPosX;
	JLabel labPosY;
	JLabel labDPixel;
	JLabel labFilled;
	JButton enter;
	JButton exit;
	JTextField posX;
	JTextField posY;
	JTextField dPixel;
	JCheckBox filled;
	public int x;
	public int y;
	public int d;
	public boolean fill;
	private static final long serialVersionUID = 1L;
	
	public Kreis(Startup parent)
	{
/*
 	int x = parent.x;
	int y = parent.y;
	int d = parent.d;
	boolean fill = parent.fill;
*/
		this.parent = parent;
		abfrage();
	}
	
	public void abfrage()
	{
		labPosX = new JLabel();
		labPosY = new JLabel();
		
		labDPixel = new JLabel();
		labFilled = new JLabel();
		
		enter = new JButton();
		exit = new JButton();
		
		posX = new JTextField();
		posY = new JTextField();
		
		dPixel = new JTextField();
		filled = new JCheckBox();
		
		labFilled.setText("Kreis gefüllt? Ja/Nein.");
		labPosX.setText("Position X. Bitte angeben.");
		labPosY.setText("Position Y. Bitte angeben.");
		labDPixel.setText("Durchmesser in Pixel.");
		
		enter.setText("Generieren");
		exit.setText("Beenden");
	
		add(labFilled);
		add(filled);
		
		add(labPosX);
		add(posX);
		
		add(labPosY);
		add(posY);
		
		add(labDPixel);
		add(dPixel);
		
		add(enter);
		add(exit);
		
		posX.setPreferredSize(new Dimension(25, 25));
		posY.setPreferredSize(new Dimension(25, 25));
		dPixel.setPreferredSize(new Dimension(25, 25));
		
		enter.setPreferredSize(new Dimension(100, 25));
		exit.setPreferredSize(new Dimension(100, 25));
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300,400);
		setLayout(new FlowLayout(FlowLayout.CENTER, 20, 20));
		setVisible(true);
		
		enter.addActionListener(this);
		exit.addActionListener(this);

	}
	
	@Override
	public void actionPerformed(ActionEvent ae)
	{
		if(ae.getSource() == enter)
		{
			x = Integer.parseInt(posX.getText());
			y = Integer.parseInt(posY.getText());
			d = Integer.parseInt(dPixel.getText());
			fill = filled.isSelected();
			
			dispose();

			new Paint(x, y, d, fill);
//			if(fill)
//			{
//				new FillPaint(x,y,d);
//			}
//			else
//			{
//			new Paint(x,y,d);
//			}
			
		}
		else if(ae.getSource() == exit)
		{
			dispose();
//			System.exit(0);
		}
	}
}


Klasse Paint:

Java:
package basics;

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

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Paint
extends JFrame
{
	Kreis parent;
	JPanel panel;
	boolean fill;
	int d = 0;
	int x = 0;
	int y = 0;
	
	private static final long serialVersionUID = 1L;
	
	public Paint(int x, int y, int d, boolean fill)
	{
		this.x = x;
		this.y = y;
		this.d = d;
		this.fill = fill;
		
/*
 * 		System.out.println(x);
 * 		System.out.println(y);
 * 		System.out.println(d);	
*/	
		panel = new JPanel();
		setSize(450,450);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public void paint(Graphics g)
	{
		super.paint(g);
		g.setColor(Color.white);
		g.fillRect(0, 0, 450, 450);
		g.setColor(Color.black);
		if(!fill)
		{
			g.drawOval(x, y, d, d);
		}
		else
		{
			g.fillOval(x, y, d, d);
		}
	}
}
 
ganz schön wirr, ich nehme an es geht um:
öffne weniger neue Fenster sondern nutze vorhandene,
wenn nur ein Fenster, dann ist es ja leicht,
wenn mindestens zwei, dann übergib etwa das erste ans zweite als Parameter im Konstruktor,
somit kennt das zweite das erste und kann dort was aufrufen statt ein drittes zu erzeugen?

soweit verstanden?
eigentlich nichts neues, wie paar Objekte untereinander kommunizieren gehört zu relativ tiefen Grundlagen weit vor komplizierten Fenstern..
 
ein weiteres Beispiel von: auf eine Nebenfrage geantwortet, zum eigentlichen Thema nichts geschrieben,

ich habe schon geantwortet und weiß nun nicht was ich noch weiteres neues schreiben sollte,
ich weiß nichtmal ob du das Thema schon als gelöst und beendest ansiehst

-------

> Wie meinst du ds weit vor komplizierten Fenstern?

das ist so als wenn du in der Mathematik nach 5+5 fragst bei Integralrechnung,
lange bevor etwas kompliziertes drankommt sollte man die einfachen Dinge kennen, z.B. das ein Objekt an ein anderes übergeben wird
 
Also das Thema ist immer noch geöffnet.

Ich markiere die erledigten Threads immer als erledigt 😀


Also wie gesagt, ich möchte, dass wenn ich auf den Button Enter klicke passiert folgendes:

Java:
if(ae.getSource() == enter)
		{
			x = Integer.parseInt(posX.getText());
			y = Integer.parseInt(posY.getText());
			d = Integer.parseInt(dPixel.getText());
			fill = filled.isSelected();
			
			dispose();
			
			zeichnen;
			
			new Paint(x, y, d, fill);
		
		}

Als erstes, wird das vorhandene Fenster geschlosse und ein neues Fenster, nämlich das Fenster Paint, wo die Zeichnungen drin sind, erscheint.

Java:
package basics;

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

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Paint
extends JFrame
{
	Kreis parent;
	JPanel panel;
	boolean fill;
	int d = 0;
	int x = 0;
	int y = 0;
	
	private static final long serialVersionUID = 1L;
	
	public Paint(int x, int y, int d, boolean fill)
	{
		this.x = x;
		this.y = y;
		this.d = d;
		this.fill = fill;
		
              	panel = new JPanel();
		setSize(450,450);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public Paint()
	{
		
	}
	public void paint(Graphics g)
	{
		super.paint(g);
		g.setColor(Color.white);
		g.fillRect(0, 0, 450, 450);
		g.setColor(Color.black);
		if(!fill)
		{
			g.drawOval(x, y, d, d);
		}
		else
		{
			g.fillOval(x, y, d, d);
		}
	}
}

So hier wird ein Fenster geöffnet, wo erstmal ein weißes rechteck gezeichnet wird. Auf dieses Rechteck, wird dann der Kreis gezeichnet.


Das Problem:


Wenn ich jetzt zwei Kreise malen möchte, dann werden zwei Fenster geöffnet.
De Facto, sind die Kreise nicht in einem Fenster.


Also ich möchte, dass die Action-Performed-Methode auf das selbe Objekt zugreift.

Wenn ich jetzt davor den "Variablen"namen setzte,
Java:
zeichnen = new Paint(x, y, d, fill);

dann wird ja trotzdem ein zweites Fenster geöffnet. Also müsste ich vorher gucken, ob das Fenster schon aktiv ist.
also

Java:
if(!zeichnen.isActice())
{
     zeichnen = new Paint(x, y, d, fill)
}
else
{

}
Nur weiß ich jetzt nicht, was ich in den Else-Teil reinschreiben soll, da ich ja irgendwie die daten an die Paint Methode bringen muss.



VIelen Dank für deine HIlfe.


lg James
 
grundsätzlich musst du repaint() aufrufen um ein erneutes Zeichnen zu bewirken,
die Varialben zu übergeben ist dann wieder Grundlage

zunächst musst du wissen wie du sie speichern willst, üblicherweise zeichnet ein paint() alles komplett neu,
also brauchst du die Daten vom ersten Kreis auch, falls der noch angezeigt werden soll,
dann alle Variablen doppelt ablegen, unschön, oder eine Liste mit Objekten die die benötigten Informationen enthalten,

der Konstruktor hilft dir in der Tat nicht viel, aber du kannst ja jederzeit eine neue Methode erstellen mit den Parameter
und den Aktionen darin die du gerade brauchst,

also:
- Platz/ Variablen für Information schaffen
- Informationen übergeben
- repaint()
- paint muss alle vorhandenen Informationen korrekt verarbeiten

--------

in einem JFrame mit paint() zu zeichnen ist übrigens schlecht wie es überall steht,
besser in einem JPanel mit paintComponent() malen!

Galileo Computing :: Java ist auch eine Insel – 20 Grafikprogrammierung
Wenn Swing eine Komponente zeichnet, ruft es automatisch die Methode paint() auf. Um eine Grafik selbst in ein Fenster zu zeichnen, ließe sich von JFrame eine Unterklasse bilden und paint() überschreiben – das ist jedoch nicht der übliche Weg.

Stattdessen wählen wir einen anderen Ansatz, der sogar unter AWT eine gute Lösung ist. Wir bilden eine eigene Komponente, eine Unterklasse von JPanel [..]
....
 
Hey SlaterB,

sollte ich das in ein Array packen?

Oder kannst du mir vielleicht ein CodeSchnipsel geben, wie du das proggen würdest?


lg James
 
ok. Danke 😀 ist sowieso besser, wenn du mir so hilfst, anstatt mir den Code zu geben.


Dann brauche ich eine Schleife in der Action-performed methode, oder?

Naja vielen Dank, ich denke ich schlafe dann auch noch mal ´ne Nacht drüber. Mal gucken, ob mir was einfällt. Ich melde mich auf jeden Fall.


lg James
 

Zurück
Oben