2D-Grafik Neue Farbe für einen Teilbereich einer Linie?

piplack

Mitglied
Hallo,

in einem Panel zeichne ich horizontale und vertikale Linien. Ich möchte, wenn der User auf einen bestimmten Bereich klickt, dass dieses Linienstück eine andere Farbe bekommt.

Wie kann ich dies anstellen?
Habe es schon mit repaint() versucht, aber leider klappt das nicht.

Klasse Spielfeld: Hier werden die Grundlinien gezeichnet, das klappt auch wunderbar

Java:
public class Spielfeld extends JPanel implements MouseListener {

	private int anzahlKaestchen;
	private int panelgroesse;
	private int abstand;
	private int index;
	private int rand;
	private Spiel spiel;
	private Spieler s;
	private String symbol;
	private Graphics g;

	
	
	public int getAnzahlKaestchen() {
		return anzahlKaestchen;
	}

	public void setAnzahlKaestchen(int anzahlKaestchen) {
		this.anzahlKaestchen = anzahlKaestchen;
	}

	public Spielfeld() {

		addMouseListener((MouseListener) new Startcontroller(this));
	}

	/**
	 * Methode, um die Linien zu zeichnen
	 * 
	 * @author Anke
	 * @param anz
	 *            = Anzahl der Kästchen in der Breite bzw. in der Höhe
	 * @param g
	 *            = Grafik-Spielfeld
	 */
	public void spielfeldZeichnen(int anz, Graphics g) {
//		panelgroesse = getHeight()-2;
//		panelgroesse = Startview1.getPanelgroesse();
		panelgroesse = 180;
		anzahlKaestchen = 4;

		int breite = Integer.parseInt((String) Startview1.getBreite().getSelectedItem());
		
		if (breite != anzahlKaestchen) {
			anzahlKaestchen = breite;
		}
		else {
			anzahlKaestchen = anzahlKaestchen;
		}
		System.out.println("Kästchenbreite = " + anzahlKaestchen);
		System.out.println("Panelgroesse = " + panelgroesse);
		
		abstand = panelgroesse / anzahlKaestchen;
		Spiel spiel;

		// horizontale Linien
		for (int y = 0; y <= (panelgroesse); y += abstand) {
			g.drawLine(0, y, panelgroesse, y);
		}

		// vertikalen Linien
		for (int x = 0; x <= (panelgroesse); x += abstand) {
			g.drawLine(x, 0, x, panelgroesse);
		}
		this.g = g;
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		spielfeldZeichnen(anzahlKaestchen, g);
//		paintSpielzug(index, rand, getG());
	}

	//getter + setter für g
	public Graphics getG() {
		return g;
	}

	public void setG(Graphics g) {
		this.g = g;
	}

....

	/**
	 * Die Methode 'paintSpielzug' setzt den angeklickten Rand in eine andere Farbe
	 * @param index = Index vom Kästchen
	 * @param rand = Index vom Rand
	 * @author Anke
	 */
	public void paintSpielzug(int index, int rand, Graphics g) {
		int i = getIndex();
		int r = getRand();
		g = getG();
		
		Color farbe = Color.BLUE;
		
		float a;
		float b;

		a = Startcontroller.getKlick().getX() / abstand;
		b = Startcontroller.getKlick().getY() / abstand;
		
		int xa = (int) (a * abstand);
		int yb = (int) (b * abstand);
		int xa2 = xa + abstand;
		int yb2 = yb + abstand;
		
		System.out.println("Rand= "+rand);
		System.out.println("xa = " + xa);
		System.out.println("yb = " + yb);
		System.out.println("x2a = " + xa2);
		System.out.println("yb2 = " + yb2);
		
		if (r == 0) {
			g.setColor(farbe);
			g.drawLine(xa, yb, xa2, yb);
		}
		else if (r == 1) {
			g.setColor(farbe);
			g.drawLine(xa2, yb, xa2, yb2);
		}
		else if (r == 2) {
			g.setColor(farbe);
			g.drawLine(xa, yb2, xa2, yb2);
		}
		else {
			g.setColor(farbe);
			g.drawLine(xa, yb, xa, yb2);
		}
		this.g = g;
		
		System.out.println("Die Funktion paintSpielzug wird aufgerufen!");
	}

Die Methode wird auch aufgerufen, aber in der View ist leider keine Änderung.

In der Controller-Klasse ist der Mouse-Listener, der dann das neuzeichnen aktivieren sollte

Java:
public class Startcontroller implements ActionListener, MouseListener{

	private Startview1 startview1;
	private Startmodel startmodel;
	private Spielfeld spielfeld;
	
	private int x;
	private int y;
	
	private static Punkt klick;
	private static Punkt kaestchenKoordinate;

	public Startcontroller(Startview1 startview1) {
	this.startview1 = startview1;	
	}
	
	public Startcontroller(Spielfeld spielfeld) {
	this.spielfeld = spielfeld;
	}

	public Startmodel getStartmodel() {
		return startmodel;
	}

	public void setStartmodel(Startmodel startmodel) {
		this.startmodel = startmodel;
	}

	public Startview1 getStartview1() {
		return startview1;
	}

	public void setStartview1(Startview1 startview1) {
		this.startview1 = startview1;
	}
	
	public Spielfeld getSpielfeld() {
		return spielfeld;
	}

	public void setSpielfeld(Spielfeld spielfeld) {
		this.spielfeld = spielfeld;
	}

//ActionListener rausgenommen)
	
	// Mouseevent fuer Namensfelder
	public void mouseClicked(MouseEvent event) {
		if (event.getSource() instanceof TextField) {
			if (((TextField) event.getSource()).getName() == "Spieler1") {
				Startview1.getSpieler1().setText("");
			} 
			else if (((TextField) event.getSource()).getName() == "Spieler2") {
				Startview1.getSpieler2().setText("");
			}
		}
		if (event.getSource() instanceof JPanel) {
			klick = new Punkt(event.getX(), event.getY());
			int i = spielfeld.berechneKaestchenIndex(klick);
			int rand = spielfeld.berechneRandIndex(klick, kaestchenKoordinate);
			Graphics g = spielfeld.getG();
			
		System.out.println("Kästchen-Index = "+ i + " x= "+ event.getX()+ " Y= "  + event.getY());
		
		spielfeld.berechneRandIndex(klick, kaestchenKoordinate);
		
		spielfeld.paintSpielzug(i, rand, g);
		spielfeld.repaint();   //funktioniert nicht
		}
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		e.getX();
		e.getY();
//		System.out.println(e.getX() + "  "+ e.getY());
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	public static Punkt getKlick() {
		return klick;
	}

	public void setKlick(Punkt klick) {
		this.klick = klick;
	}

}
 
Hm habe jetzt nicht richtig mich da reingearbeitet, aber ich würd doch erstmal schauen, ob das MouceClickEvent ausgelöst wird (einfaches syso von dem event z.b.).
 
in einem Panel zeichne ich horizontale und vertikale Linien. Ich möchte, wenn der User auf einen bestimmten Bereich klickt, dass dieses Linienstück eine andere Farbe bekommt.

Wie kann ich dies anstellen?
Ganz einfach: Eine andersfarbige Linie darübermalen ;-)

1. Anwender klickt
2. Bereich ermitteln
3. per repaint() ein Neuzeichnen der Komponente anfordern
4. in der paintComponent die Standardlinien zeichnen
5. (immer noch in der paintComponent) prüfen, ob ein Bereich gesetzt ist und falls ja, die andersfarbigen Linien in diesem Bereich zeichnen
 
Kannst Du zu 5 etwas ausführlicher werden?

die Methode paintSpielzug wird über den MouseListener aufgerufen.

in dieser Methode wird auch der Bereich ermittelt, wo ich die Linie neue Zeichnen will.
es wird auch aufgefordert, einen bestimmte Linie zu zeichnen.

wo muss ich das repaint() setzen,
und wie kann überprüfen, ob ein Bereich andersfarbig ist?

Methode paintSpielzug() wird aufgerufen, habe ich ausprobiert mit sysout....
 
Zuletzt bearbeitet:
Hm kann es sein, dass du den Spielzug zeichnest, dann aber wieder mit der repaint() das Spielfeld drüber gezeichnet wird?
 
das Graphics-Objekt nicht längerfristig speichern, etwa im MouseListener abfragen,
es gibt (im einfachen Modell) nur paintComponent() welches g liefert, damit malen, wie auch immer, nur wenige ms insgesamt,
danach NICHTS mehr mit diesem g machen, für die Zeit kann es natürlich zur Vereinfachung in diversen Variablen abgelegt werden,
Parameter für Methoden usw.,

auf User-Ereignisse repaint(), damit das ganze von vorne los geht
und die reine Information abspeichern,
notfalls [c]boolean maleLinieVonX40Y50NachX60Y70Blau = true/false; [/c]
aber das ist wohl nicht allgemein genug..,
also irgendwas modellieren, z.B. ein Objekt mit Wahl der Linie, Wahl der Farbe, welches beim painten dann am Ende berücksichtigt wird,
trivial ist das nicht, das ganze Bild muss irgendwie ansprechbar sein, z.B. die Linien von 0-999 durchnummieren,
anhand der Mausklickposition die näheste berechnen/ bestimmen..
 
Oh, das mit dem Graphics Objekt sollte man natürlich nicht machen.

Hier mal ein Q&D Beispiel, wie man an die Sache rangehen könnte. Die geklickte "Koordinate" wird in einem Point gespeichert bzw. beim Loslassen wird die Referenz auf null gesetzt.
In der paintComponent wird überprüft, ob die Variable auf ein Objekt referenziert, wenn ja wird anhand der "Koordinate" die Position ausgereichnet und an dieser Stelle ein farbiges Rechteck gemalt.
Java:
class PaintPanel extends JPanel implements MouseListener{
	private int rows = 4, columns = 4;
	private BasicStroke stroke = new BasicStroke(3);
	private Point p;
	
	public PaintPanel() {
		this.addMouseListener(this);
		p = null;
	}
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D)g;
		g2.setStroke(stroke);
		int w = this.getWidth(), h = this.getHeight();
		int dH = h/columns;
		for (int r=0; r<=rows; r++)
			g2.drawLine(0, r*dH, w, r*dH);
		int dW = w/rows;
		for (int c=0; c<=columns; c++)
			g2.drawLine(c*dW, 0, c*dW, h);
		if (p!=null) {
			g2.setColor(Color.YELLOW);
			g2.drawRect(p.x*dW, p.y*dH, dW, dH);
		}
	}
	public void mouseClicked(MouseEvent e) {}
	public void mouseEntered(MouseEvent e) {}
	public void mouseExited(MouseEvent e) {}
	public void mousePressed(MouseEvent e) {
		p = new Point(e.getX()*columns/this.getWidth(),
			e.getY()*rows/this.getHeight());
		this.repaint();
	}
	public void mouseReleased(MouseEvent e) {
		p = null;
		this.repaint();
	}
}
 
Das funktioniert leider auch nicht.

ich muss den MouseListener in einer anderen Klasse (Startcontroller) setzen.
Dadurch will er, dass die getPoint() als static declariert sein soll, wird aber in Java leider nicht angenommen.
 
weder reichen diese Zeilen um dein Programm zu korrigieren (was sowohl statisch als auch nicht-statisch immer möglich ist, man muss es nur richtig machen)
noch wird jemand aus reinem Jux einen anderen oder sonst wie besseren/ vollständigeren Code posten

die Frage die sich stellt lautet also: was willst du mit deinem Posting aussagen?
(außer eine Antwort wie die meine heraufzubeschwören? 😉 )
 

Zurück
Oben