# JFrame Resize Polygone anpassen



## deepfry (13. Aug 2009)

Hallo zusammen,

ich bin jetzt seit mehreren Stunden an einem, ich denke doch, sehr simplen Problem. Ich bin dabei ein Brettspiel umzusetzen und habe dafür eine feste Karte als Hintergrund in einem JPanel (siehe unten). Jetzt besteht die Karte aus Regionen, auf die der User klicken kann. Die Idee ist jetzt, dass ich jeder Region ein Polygon zuordne und dann mit contains() durch alle Regionen durchiteriere um zu sehen wo geklickt wurde. Schön und gut das funzt auch. Leider sind nicht alle mit einer hohe Auflösung gesegnet sodass, ich GUI und vor allem die Karte in der Größe anpassen muß. Nun das Problem wie kann ich das Model, also die Polygone anpassen??? Habe es schon mit ComponentListener und dann alle Poylgone mit translate( oldWidth-newWidth, oldHeight-newHeight) zu verschieben versucht, aber das tut nicht wirklich.

Meine Frage gibt es da eine offensichtliche Lösung oder bin ich da mit Polygon sowieso auf dem Holzweg und es gibt eine viiieeel elegantere Lösung. Danke für jede Hilfe


----------



## Marco13 (14. Aug 2009)

Warum translate? Wenn, dass müssen die doch skaliert werden?! Entweder die Punkte einzeln, oder mit einer AffineTransform ... oder du rechnest einfach den Skalierungsfaktor in die Mausklick-Position rein, und läßt den Rest wie er ist


----------



## deepfry (14. Aug 2009)

Ich hab die Polygon hart reinkodiert und müsste die also skalieren, leider bietet Polygon nur translate, muß ich vll. mit einer anderen Shape arbeiten?


----------



## deepfry (14. Aug 2009)

Das Porblem ist auch , dass ich die Größe des Bildes kenne aber wenn ich mir schon beim Start die Größe des Panels geben lasse stimmen die Werte schon nicht. Hab alles probiert, getBounds(), getSize() obwohl ich Max Min und Pref Size fest gesetzt habe im Panel. ???:L immer falsche Werte, hier mal etwas Code

Das Panel mit dem Bild

```
public class MapView extends JLabel
{
	private Image mapImage;
	private int currentProvinceID;
	private boolean highlightProvince;
	private MapModel mapModel;
	
	public MapView()
	{
		this.mapImage = Images.MAP;

		this.setPreferredSize( new Dimension(741,732));
		this.setMaximumSize( new Dimension(741,732));
		this.setMinimumSize( new Dimension(741,732));
		this.highlightProvince = false;
	}

	public void setDependencies( MapModel mapModel, InputManager inputManager )
	{
		this.mapModel = mapModel;
		this.addMouseListener(inputManager);
		this.addMouseMotionListener(inputManager);
	}
	
	@Override
	public void paintComponent( Graphics g )
	{
		super.paintComponent( g );

		paintMap( g );
		
		if( highlightProvince )
		{
			g.setColor(Color.RED);
			g.drawPolygon( mapModel.getProvince( currentProvinceID ).getProvinceBoundary() );
		}
		
		highlightProvince = false;
	}

	private void paintMap(Graphics g)
	{
		g.drawImage( this.mapImage, MapModel.MAP_POSITION.x, MapModel.MAP_POSITION.y, this.getWidth(),this.getHeight(),this );
	}

	public void highlightProvince(int provinceID)
	{
		currentProvinceID = provinceID;
		this.highlightProvince = true;
		this.repaint();
	}

	public void resetMap()
	{
		repaint();
	}
}
```

Und hier der TestFrame wo es drin angezeigt wird

```
public class TestMap extends JFrame implements ComponentListener
{
	private MapView mapView;
	private InputManager inputManager;
	private MapModel mapModel;
	private Logger logger;
	private int oldwith;
	private int oldHeight;

	public TestMap()
	{
		
		this.mapModel = new MapModel();
		this.mapView = new MapView();
		this.logger = new Logger();
		this.inputManager = new InputManager();
		
		this.setLayout(new BorderLayout());

		this.inputManager.setDependencies(mapView, mapModel, logger);
		this.mapView.setDependencies(mapModel, inputManager);
		this.addComponentListener(this);
		this.add( mapView ,BorderLayout.CENTER);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.pack();
		this.setVisible(true);
	}
	
	public static void main(String[] args)
	{
		Images.loadImages();
		new TestMap();
	}

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

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

	@Override
	public void componentResized( ComponentEvent e )
	{
		//Do fancy rescale work here
	}

	@Override
	public void componentShown( ComponentEvent e )
	{

	}
}
```


----------



## Marco13 (14. Aug 2009)

Naja, Polygon passt eigentlich schon - wobei ich sagen muss, dass Polygon eine der IMHO unschönsten Klassen der ganzen API ist (alernative wäre GeneralPath oder Path2D). Aber Polygon hat public arrays "xpoints" und "ypoints", die die x- und y-Koordinaten der Punkte speichern. Die kannst du durchgehen und einzeln skalieren.


----------



## deepfry (14. Aug 2009)

Marco13 hat gesagt.:


> Naja, Polygon passt eigentlich schon - wobei ich sagen muss, dass Polygon eine der IMHO unschönsten Klassen der ganzen API ist (alernative wäre GeneralPath oder Path2D). Aber Polygon hat public arrays "xpoints" und "ypoints", die die x- und y-Koordinaten der Punkte speichern. Die kannst du durchgehen und einzeln skalieren.



ok das geht stimmt, da denkt man schon gar nicht mehr dran weil man versucht etwas mit i.einer API Methode totzuschlagen ^^. Werde das garad mal umsetzen. 

Edit: Ok jetzt bin ich überfragt

habe den Code hier

```
@Override
	public void componentResized( ComponentEvent e )
	{
		int scaleX = this.mapView.getWidth() - oldWidth;
		int scaleY = this.mapView.getHeight() - oldHeight;
		
		System.out.println(this.mapView.getWidth()+" "+this.mapView.getHeight());
		
		if( this.mapView.getWidth() != oldWidth || this.mapView.getHeight() != oldHeight )
		{
			mapModel.scalePolygons(scaleX, scaleY);
			System.out.println("called scaling");
		}
		this.oldWidth = this.mapView.getWidth();
		this.oldHeight = this.mapView.getHeight();
	}
```

das komische, bei Debug Modus mit Breakpoints kommt dieser Ausdruck auf der Konsole
*741 732
741 732
*
und alles funktioniert ( Ich lass die Polygon zeichnen wenn ich über die entsprechende Region drüberfahr). Im normalen Modus kommt nun aber folgender Ausdruck und nichts geht mit drüberfahren und Polygone zeichnen
*741 732
called scaling:
ScaleX:741
ScaleY:732
741 732*
???:L???:L???:L

ok Problem gelöst musste im Konstruktor feste Werte für oldWidth/oldHeight übergeben statt mapView.getWidth()/mapView.getHeight() zu nehmen. Unnnnd.... es klappt :applaus::applaus: thx für deine Hilfe Marco :toll:


----------



## deepfry (14. Aug 2009)

Sry aber jetzt spinnt der scalePolygon()

```
public void scalePolygons( double scaleX, double scaleY, int sizeX, int sizeY )
	{
		for( int i = 0; i < provincePolygons.length; i++ )
		{

			for( int j = 0; j < provincePolygons[i].xpoints.length; j++)
			{
				provincePolygons[i].xpoints[j] *= scaleX;
				provincePolygons[i].xpoints[j] += sizeX;
			}

			for( int k = 0; k < provincePolygons[i].ypoints.length; k++)
			{
				provincePolygons[i].ypoints[k] *= scaleY;
				provincePolygons[i].ypoints[k] += sizeY;
			}
			provinces[i].setProvinceBoundary(provincePolygons[i]);
		}
	}
```

es werden nicht alle Polygone gezeichnet sizeX ist dabei die Verschiebung in x Richtung und sizeY in y. Die Idee istdoch korrekt, die X und Y Werte skalieren und dann noch verschiebn um die Größenänderung des Fensters? ???:L

Die Berechnung mach ich wie folgt

```
double scaleX = (double) this.mapView.getWidth()   / (double) oldWidth ;
		double scaleY = (double) this.mapView.getHeight() / (double) oldHeight;
		int sizeX = (int) (this.mapView.getWidth()  - oldWidth);
		int sizeY = (int) (this.mapView.getHeight() - oldHeight);
```


----------

