# [gelöst] Verschiebbare Komponenten mit Linien verbinden



## philth (1. Feb 2009)

Hallo,

aufgrund mangelhafter Planung bin ich bei der Umsetzung meiner Studienarbeit in Schwierigkeiten geraten was die Benutzerschnittstelle betrifft 

Im Bild sieht man ein JPanel, auf welchem weitere JPanel angeordnet sind (mit der Maus bewegbar, NullLayout). Die kleinen JPanel hab ich genommen wegen der MouseListener und dem automagischen repaint().

Problem: Ich muss die Punkte auf den kleinen Panels (bitte nich zuviel reininterpretieren  sind nur "Testobjekte" erstmal) noch mit Linien verbinden. Idealerweise sollen die Linien sichtbar in die kleinen Rechtecke hineinreichen, muss aber nicht sein (am Ende soll es eben aussehen wie ein Blockschaltbild oder Klassendiagramm oder ...). Dazu fallen mir folgene Lösungen ein:

a) malen der Linien als Pfade auf das untenliegende JPanel. Hier kann es aber Probleme geben, weil ich auf einem Panel sowohl zeichne als auch Komponenten platziere, oder? Außerdem müssen die Linien immer neu gezeichnet werden, wenn die kleinen Panels verschoben werden

b) weiteres JPanel über alles drüberlegen, darauf malen. Hier frage ich mich dann, ob die Mausevents dann noch bei den überdeckten Panels ankommen oder ob ich sicherstellen kann, dass das - ich nenne es jetzt mal "Verbindungslinienpanel" - niemals eine Action auslöst.

Für innovative Vorschläge oder auch Ermutigungen, alles Shape-basiert zu lösen (vielleicht noch unschlagbare Argumente dafür) bin ich sehr dankbar!

Grüße
Philipp


----------



## Ariol (1. Feb 2009)

Sowas?


```
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

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

public class Demo extends JFrame
{

	public Demo()
	{
		setLayout(null);
		final JPanel unten = new JPanel();
		unten.setLayout(null);
		unten.setBounds(0, 0, 300, 300);
		
		
		JPanel element1 = new JPanel();
		element1.setName("ELEMENT1");
		element1.setBackground(Color.RED);
		element1.setBounds(30, 30, 60, 60);
		
		JPanel element2 = new JPanel();
		element2.setName("ELEMENT2");
		element2.setBackground(Color.GREEN);
		element2.setBounds(30, 100, 60, 60);
		
		JPanel element3 = new JPanel();
		element3.setName("ELEMENT3");
		element3.setBackground(Color.YELLOW);
		element3.setBounds(100, 30, 60, 60);
		
		JPanel element4 = new JPanel();
		element4.setName("ELEMENT4");
		element4.setBackground(Color.BLUE);
		element4.setBounds(100, 100, 60, 60);
		
		JPanel oben = new JPanel();
		oben.setBounds(0, 0, 300, 300);
		oben.addMouseListener(new MouseAdapter()
		{
			public void mousePressed(MouseEvent e)
			{
				System.out.println("START:" + unten.getComponentAt(e.getPoint()).getName());
			}

			public void mouseReleased(MouseEvent e)
			{
				System.out.println("ENDE: " + unten.getComponentAt(e.getPoint()).getName());
			}
			
		});
		
		
		unten.add(element1);
		unten.add(element2);
		unten.add(element3);
		unten.add(element4);
		unten.add(oben);
		
		add(unten);
		setPreferredSize(new Dimension(200,220));
		pack();
		setVisible(true);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	public static void main(String[] args)
	{
		new Demo();
	}
}
```

Eines der bunten Vierecke anklicken und auf einem anderem,dem gleichen oder dem Hintergrund wieder loslassen.
In der Konsole wird angezeigt von wo nach wo geklickt wurde.

Das mit den Element-Namen ist nur zum besseren Verständnis.


----------



## philth (1. Feb 2009)

Vielen Dank!

Ich glaube, so werde ich es auch machen - ein Panel drüberlegen, dort die Verbindungslinien zeichnen lassen und dann die MouseEvents an die drunterliegenden Objekte durchreichen. GetComponentAt() liefert lt. Java-Doku immer die oberste Komponente also brauche ich für dieses Fenster nur einen Listener, implementiere die jeweiligen Aktionen dann in den Komponenten und reiche die Events durch ... super Sache! Danke.

In der Komponente dann sowas wie:

```
public class BlackBox extends JPanel implements Manipulierbar{
    public void mouseMoved(MouseEvent e){
     do();
     some = thing;
   }
}

public interface Manipulierbar{
   public void mouseMoved(MouseEvent e);
}
```

... und im drüberliegenden Panel

```
public void mouseMoved(MouseEvent e){
   (Manipulierbar) panel.getComponentAt(e.getPoint()).mouseMoved(e);
}
```

(ganz durchsteigen werd ich das dann morgen)

Hast du vielleicht noch einen Tipp für mich, nach was ich suchen könnte, wenn ich mich näher drüber informieren möchte, wie man Darstellung und darzustellende Daten sauber trennt? Bei mir kennt nämlich fast jeder jeden, obwohl ich darauf achte, es zu vermeiden.

Grüße und danke,
Philipp


----------

