Grafiken mit Listener verbinden?

Status
Nicht offen für weitere Antworten.

KS

Aktives Mitglied
Hallo

Ich habe mit Rectangle2D ein par Vierecke in eine Grafik gemalt. Nun möchte ich diese Vierecke kontrollieren, falls jemand mit der Maus darauf klickt. Komme hier bei Rectangle2D nicht all zu weit, da keine addMouseListener Methode zur Verfügung steht. Ich hab mal mit implementieren begonnen, aber ich frage mich, ob das wirklich das wahre ist..

Wie schauts aus? Kann mir da jemand helfen? Vielen Dank im Voraus

Gruss
Chris
 

André Uhres

Top Contributor
Was soll's denn werden wenn's fertig ist ?

EDIT: Falls du die Rechtecke verschieben willst, könntest du mit Polygon#translate(..) arbeiten.
 

KS

Aktives Mitglied
Etwas ähnliches wie ein Klalender von thunderbird.. wo du rechtecke als termine siehst und diese mit doppelklick auch gleich bearbeiten kannst..
 

André Uhres

Top Contributor
Den Thunderbird Kalender kenne ich nicht, aber so wie ich dein Problem einschätze
ist es wahrscheinlich besser wenn du eine JTable benutzen würdest.
 

KS

Aktives Mitglied
..mmh.. ich habe bereits eine tabelle, welche termine anzeigt. unten dran hab ich eine kalender grafik welche mir die termine als rechtecke anzeigt. was ich nun will ist wenn ich die rechtecke anklicke z.bsp. der entsprechende eintrag in der Tabelle selektiert wird.

ich dachte man könnte ein viereckobjekt mit der addMouseListener methoder erweitern.. so habe ich gedacht.. geht das denn nicht???
 

André Uhres

Top Contributor
In dem Fall könntest du vielleicht anstatt der Rechtecke JComponents benutzen (z.B. JLabel, JButton oder JPanel).
Da kannst du problemlos MouseListeners dranhängen.

EDIT: aber wahrscheinlich ist es einfacher eine zweite JTable anzulegen wo du einen
MouseListener dranhängst. Bei mouseClicked selektierst du dann die gleiche Zelle in der ersten Tabelle.
Code:
       jTable1.setCellSelectionEnabled(true);
        jTable2.setCellSelectionEnabled(true);
        jTable2.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                jTable2MouseClicked(evt);
            }
        });
        ...
    private void jTable2MouseClicked(MouseEvent evt) {
        jTable1.changeSelection(jTable2.getSelectedRow(), jTable2.getSelectedColumn(), false, false);
    }
 

KS

Aktives Mitglied
super idee mit den panels! das ist das was ich suchte!! das mit den 2 tabellen verstehe ich nicht ganz.
um dir zu zeigen wie es etwa aussieht ein bild meiner applikation:

id88if.jpg


was du siehst: die blauen flächen sind momentan noch Objekte von Rectangle2D,
welche ich jetzt durch JPanels ersetzten werde.. ich habe jedoch noch Probleme mit dem update,
denn wenn ich die Rectangle2D Objekte durch JPanels ersetze, funktioniert das update des
Jpanels nicht mehr korrekt.

Hier ist der Code meiner Klasse GUIPanelGraf (dies ist die ganze Grafik unterhalb der Tabelle):

Code:
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.util.GregorianCalendar;

/**
 * 

Überschrift: Eventer</p>
 *
 * 

Beschreibung: Datebankapplikation für Eventmanagement</p>
 *
 * 

Copyright: Copyright (c) 2005</p>
 *
 * 

Organisation: KSF Engineering</p>
 *
 * @author Christian Schmitz
 * @version 0.2
 */
public class GUIPanelGraf extends JPanel {

	private GUIEventProgrammController controller;
	
	private GregorianCalendar calStart = new GregorianCalendar();

	private GregorianCalendar calEnd = new GregorianCalendar();

	Graphics2D g;
	
	//Eckpunkte der Grafik
	private int nOriginX = 0;
	private int nOriginY = 0;
	private int nSizeX = getSize().width;
	private int nSizeY = getSize().height;
	
	//Zeitlinie Startpunkt x
	private int nStartTimeLineX;
	
	
	private final int nFooterSizeY = 30;
	private final int nTimeFieldMinimalSizeY = 30;
	
	private EventProgramm[] aEventProgramm = null;
	private int[] aRowGroups = null;
	private double nTimeScreenFaktor;

	public GUIPanelGraf(Event objEvent) {
		this.calStart = objEvent.getEventDatumStart();
		this.calEnd = objEvent.getEventDatumEnde();
		this.aEventProgramm = objEvent.getEventProgramm();
		//hier habe ich eine methode dem objekt event angefügt, welches warsch. nur einmal gebraucht wird.. -> sinnvoll???
		this.aRowGroups = objEvent.getActsWithTermin();
		//Size muss später noch angepasst werden (100 = dynamisch auf minimum!!)
		if (aRowGroups == null){
			this.setPreferredSize(new Dimension(this.getSize().width,nFooterSizeY + nTimeFieldMinimalSizeY));	
		} else {
			this.setPreferredSize(new Dimension(this.getSize().width,nFooterSizeY + (nTimeFieldMinimalSizeY * aRowGroups.length)));
		}
	}
	
	public void initialize(GUIEventProgrammController controller) {
		this.controller = controller;
	}

	public void paint(Graphics ga) {

		g = (Graphics2D) ga;

		this.nOriginX = 0;
		this.nOriginY = 0;
		this.nSizeX = getSize().width;
		this.nSizeY = getSize().height;
		
		g.setColor(Color.blue);
		g.drawRoundRect(nOriginX, nOriginY, nSizeX - 1, nSizeY - 1, 16, 16);
		g.setColor(Color.black);
		FontMetrics fm = g.getFontMetrics(g.getFont());
		String s = "" + nSizeX + " x " + nSizeY + " Pixel";
		g.drawString(s, (nSizeX - fm.stringWidth(s)) / 2, (nSizeY - fm
				.getHeight())
				/ 2 + fm.getAscent());
		drawTimeLine();
		drawTimeFields();
		
	}

	private void drawTimeLine() {

		nStartTimeLineX = nOriginX + 10;
		int nStartY = nSizeY - nFooterSizeY;
		int nEndX = nSizeX - 10;
		int nEndY = nStartY;
		
		int nRasterHöhePrimär = nStartY - 10;
		int nRasterTiefePrimär = 5;
		int nRasterHöheSekundär = 3;
		int nRasterTiefeSekundär = 5;
		
		String sTimeLineTextStart = "Event Start";
		String sTimeLineTextEnd = "Event Ende";
		
		//Zeitlinie zeichnen
		Line2D lTimeLine = new Line2D.Double(nStartTimeLineX, nStartY, nEndX, nEndY);
		g.draw(lTimeLine);

		//Zeitlinienbeschriftung unterhalb
		g.setColor(Color.gray);
		FontMetrics fm = g.getFontMetrics(g.getFont());
		g.drawString(sTimeLineTextStart, nStartTimeLineX, nStartY + nRasterTiefePrimär + 2 + fm.getHeight());
		g.drawString(sTimeLineTextEnd, nEndX - fm.stringWidth(sTimeLineTextEnd), nStartY + nRasterTiefePrimär + 2	+ fm.getHeight());

		//Raster setzten
		int nTimeLineWidth = (int) (lTimeLine.getX2() - lTimeLine.getX1());
		long nTimeLineRange = calEnd.getTimeInMillis() - calStart.getTimeInMillis();
		nTimeScreenFaktor = (double)nTimeLineWidth / nTimeLineRange;
		GregorianCalendar calTemp = new GregorianCalendar(calStart.get(GregorianCalendar.YEAR),calStart.get(GregorianCalendar.MONTH),calStart.get(GregorianCalendar.DAY_OF_MONTH),0,0,0);
		//Raster zeichnen (Tagesgrenzen)
		while (calEnd.after(calTemp)) {
			calTemp.add(GregorianCalendar.DAY_OF_MONTH,1);
			int nTempX = (int) ((calTemp.getTimeInMillis() - calStart.getTimeInMillis()) * nTimeScreenFaktor) + nStartTimeLineX;
			g.draw(new Line2D.Double(nTempX, nStartY - nRasterHöhePrimär, nTempX, nEndY + nRasterTiefePrimär));
			//Datum hinzufügen falls platz
			if (nStartTimeLineX + fm.stringWidth(sTimeLineTextStart) < nTempX & nTempX + fm.stringWidth(calTemp.get(calTemp.DAY_OF_MONTH) + "." + (calTemp.get(calTemp.MONTH) + 1)) < nTimeLineWidth - fm.stringWidth(sTimeLineTextEnd)) {
				g.drawString(calTemp.get(calTemp.DAY_OF_MONTH) + "." + (calTemp.get(calTemp.MONTH) + 1), nTempX, nStartY + nRasterTiefePrimär + 2	+ fm.getHeight());
			}
		}
	}

	private void drawTimeFields() {
		if (aRowGroups == null)
			return;
		int nTimeFieldSizeY = (nSizeY - nFooterSizeY - 10) / (aRowGroups.length + 1);
		if (nTimeFieldSizeY < nTimeFieldMinimalSizeY) 
			nTimeFieldSizeY = nTimeFieldMinimalSizeY;
		for (int i = 0; i < aRowGroups.length; i++) {
			for (int j = 0; j < aEventProgramm.length; j++){
				if (aRowGroups[i] == aEventProgramm[j].getActID()) {
					System.out.println("zeichne: " + aEventProgramm[j].getEventProgrammText());
					int nTempX1 = (int) ((aEventProgramm[j].getEventProgrammDatumStart().getTimeInMillis() - calStart.getTimeInMillis()) * nTimeScreenFaktor) + nStartTimeLineX;
					int nTempX2 = (int) ((aEventProgramm[j].getEventProgrammDatumEnde().getTimeInMillis() - calStart.getTimeInMillis()) * nTimeScreenFaktor) + nStartTimeLineX;
					Rectangle2D r = new Rectangle2D.Double(nTempX1,nOriginY+20+(i*nTimeFieldSizeY),nTempX2-nTempX1,nTimeFieldSizeY-10);
					g.setPaint(Color.blue);
					g.fill(r);
					//JPanelTimeField p = new JPanelTimeField(nTempX1,nOriginY+20+(i*nTimeFieldSizeY),nTempX2-nTempX1,nTimeFieldSizeY-10);
					//this.add(p);
					//p.repaint();
					//System.out.println("x: " + nTempX1 + "\ny: " + (nOriginY+20+(i*nTimeFieldSizeY)) + "\nxw: " + (nTempX2-nTempX1) + "\nyw: " + nTimeFieldSizeY);
				}
			}
		}
	}
}

class JPanelTimeField extends JPanel {
	
	Graphics2D g;
	
	public JPanelTimeField(int nX, int nY, int nXWidth, int nYHeight) {
		this.setBounds(nX,nY,nXWidth,nYHeight);
	}
	
	public void paint(Graphics ga) {
		g = (Graphics2D) ga;
		
		Rectangle2D r = new Rectangle2D.Double(this.getX(),this.getY(),this.getSize().width,this.getSize().height);
		System.out.println("x: " + this.getX() + "\ny: " + this.getY() + "\nxw: " + this.getSize().width + "\nyw: " + this.getSize().height);
		g.setPaint(Color.WHITE);
		g.fill(r);
		g.setPaint(Color.GRAY);
		g.drawRect(this.getX(),this.getY(),this.getSize().width,this.getSize().height);
	}
	
}

in der methode drawTimeFields() werden die Einträge der Tabelle als Zeitfelder gezeichnet.
im innersten Loop zeichne ich die Rectangle2D. gleich darunter ist der Code (noch auskommentiert)
für die JPanels (JPanelTimeField(eigene Klasse)), welche als Ersatz der Rectangle2D stehen sollten.
Wenn ich diese jedoch aktiviere sieht der Aufbau meiner GUI so aus:

id89aq.jpg


komisch... auch verändert sich das verhalten dahingehend, dass sich bei mausbewegungen über
dem tab-überschrift "Event Programm" sich das GUI stets updatet, was zu einem flimmern und
der im obigen bild dargestellten verwirrung führt. bist du was java2d betrifft orientiert?
 

André Uhres

Top Contributor
Ein kurzes, selbständiges, kompilierbares Beispiel wäre mir lieber,
aber ich schau mal was sich machen lässt.
 

André Uhres

Top Contributor
Das folgende KSKB müsste eigentlich von der Grafik her deinen Ansprüchen genügen.
Es enthält zwar nicht deine komplizierten Algorithmen, aber darum gehts ja nicht.
Code:
/*
 * GrafikTest.java
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class GrafikTest extends JFrame {
    public GrafikTest() {
        super("GUIPanelGraf");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(500,300);
        setLocationRelativeTo(null);
        grafik = new GUIPanelGraf();
        add(grafik, BorderLayout.CENTER);
    }
    public static void main(String args[]) {new GrafikTest().setVisible(true);}
    private GUIPanelGraf grafik;    
}
class GUIPanelGraf extends JPanel {
    public GUIPanelGraf(){
        setLayout(null);
        fields = new JPanelTimeField[3];
        int len = fields.length;
        for (int i = 0; i < len; i++) {
            fields[i] = new JPanelTimeField(i*150+10,100,100+i*30,50, "Event "+(i+1));
            add(fields[i]);
        }
    }
    public void paintComponent(Graphics g){ //paintComponent malt nur dieses Panel
                                            //..nicht die Kind-Komponenten (fields)
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.drawLine(120,0,120,300);
        g2d.drawLine(120*2,0,120*2,300);
        g2d.drawLine(120*3,0,120*3,300);
    }
    private JPanelTimeField[] fields;
}
class JPanelTimeField extends JPanel {
    public JPanelTimeField(int nX, int nY, int nXWidth, int nYHeight, String nameIn) {
        name = nameIn;
        setBounds(nX,nY,nXWidth,nYHeight);
        setBackground(Color.blue);
        setBorder(new BevelBorder(BevelBorder.RAISED, Color.gray, Color.darkGray));
        addMouseListener(new MouseAdapter(){
            public void mouseClicked(MouseEvent e){
                System.out.println(name);
            }
        });
    }
    private String name;
}
 

KS

Aktives Mitglied
also, vielen Dank für deine Mühe. Sehr saubere Ausführung. Ich habe es nun auch hin bekommen. Schlüssel aus dem Chaos war die Zeile:

super.paintComponent(g); //Deine Zeile 32

Nach dieser Änderung wurde das GUI sauber dargestellt. Kannst Du mir erklären, was das grob bewirkt?
 

André Uhres

Top Contributor
Durch "super.paintComponent(g)" wird das off-screen Bild bereingt.
Fehlt diese Anweisung, dann kann es sein, daß das Bild nicht sauber rauskommt.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Grafiken zuordnen Spiele- und Multimedia-Programmierung 4
E Woher bekommt man seine Grafiken??? Spiele- und Multimedia-Programmierung 3
P Java Grafiken mit Rechnungen verknüpfen Spiele- und Multimedia-Programmierung 4
Androbin Grafiken in JAR einbinden Spiele- und Multimedia-Programmierung 3
G 3D-Objekte / Grafiken gesucht Spiele- und Multimedia-Programmierung 6
T Grafiken übereinanderlegen Spiele- und Multimedia-Programmierung 2
T PNG-Grafiken verwenden Spiele- und Multimedia-Programmierung 9
M Prinzipielle Frage: Kann Java Grafiken ausschneiden? Spiele- und Multimedia-Programmierung 3
V Frage zu Grafiken und Software! Spiele- und Multimedia-Programmierung 5
V Ein oder mehrere GIF-Grafiken zusammenfügen Spiele- und Multimedia-Programmierung 3
B 2D Grafiken auf Canvas3D Spiele- und Multimedia-Programmierung 7
G Grafiken mit Java im richtigen Format drucken Spiele- und Multimedia-Programmierung 3
B Pokerspiel: Problem mit Grafiken und Buttons Spiele- und Multimedia-Programmierung 3
M Abrunden der Ecken von Grafiken Spiele- und Multimedia-Programmierung 10
M Seltsames Flackern bei Laden von Grafiken Spiele- und Multimedia-Programmierung 4
G Minecraft PlayerBot (Listener Thread für jeden Spieler?) Spiele- und Multimedia-Programmierung 3
J mehrere Listener für einen Button / Label Spiele- und Multimedia-Programmierung 1
S Draw Package - Listener Schnittstellen Spiele- und Multimedia-Programmierung 2
C Midi abspielen und Listener anmelden? Spiele- und Multimedia-Programmierung 1
D Key Listener reagiert nicht ! Spiele- und Multimedia-Programmierung 4
F OpenGL 2D MouseClick/MouseMove Listener Spiele- und Multimedia-Programmierung 4
G Java 2D Spiel mit LWJGL verbinden Spiele- und Multimedia-Programmierung 1
J Partikel Texturen verbinden Spiele- und Multimedia-Programmierung 6
H zB Punkte darstellen und mit einer Linier verbinden Spiele- und Multimedia-Programmierung 5

Ähnliche Java Themen

Neue Themen


Oben