# Eigene JComponent in GridLayout



## LatinFavourite (27. Mai 2015)

Hallo alle zusammen,

ich habe das Problem, meine eigenen Komponenten im GridLayout anzuordnen. Sie werden immer untereinander und mit einem großen Abstand zueinander angeordnet. Ich möchte eine Art Grid erstellen, jedes einzelne soll dann später angeklickt werden. Habe die getPreferredSize Methode überschrieben, damit die Komponente die Größe dem Layoutmanager mitteilt. Aber es funktioniert nicht wie gewünscht. Hat einer vielleicht eine Idee. Vielen Dank im Voraus.


PS. Außerdem scheinen die Komponenten größer zu sein. Auch außerhalb der gezeichneten Quadrate wird eine ID ausgegeben, wenn ich einen MouseListener hinzufüge. Als ober-und unterhalb des jeweiligen Feldes.

```
public class Tile extends JComponent{
	
	private Rectangle bounds;
	private int id;
	
	public Tile(int id){
		bounds = new Rectangle(0,0,50,50);
		this.id = id;
		
		addMouseListener(new MouseInput());
	}

	protected void paintComponent(Graphics g){
		
		final Dimension DIM = getPreferredSize();
		
		g.setColor(Color.black);
		g.drawRect(bounds.x, bounds.y, DIM.width, DIM.height);
	}
	
	public Dimension getPreferredSize(){
		return new Dimension(bounds.width, bounds.height);
	}
	
	public Dimension getMinimumSize(){
		return getPreferredSize();
	}
	
	private class MouseInput extends MouseAdapter{
		public void mousePressed(MouseEvent e){
			System.out.println(id);
		}
		
	}
	

}

}
```





```
public class View extends JFrame {
	
	public View(){
		super("Grid");
		setSize(500, 500);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setResizable(false);
		setLocationRelativeTo(null);
		
		JPanel content = new JPanel(new GridLayout(2,2));
		
		
		for(int i=0; i<20; ++i){
				content.add(new Tile(i));
		}
	
	
		
		add(content);
		setVisible(true);
	}
```


----------



## Enceladus271 (28. Mai 2015)

1. Wenn du ein GridLayout mit 2 Zeilen und 2 Spalten verwendest (new GridLayout(2,2)) hast du halt keinen Platz für 20 Komponenten.
2. Beim GridLayout sind alle Komponenten gleich groß. Und die Größe wird allein durch die Anzahl der Komponenten und den zur Verfügung stehenden Platz ermittelt. Das heißt das die eigentliche Größe der Komponenten (z.B. die Preferred Size) nicht berücksichtigt wird.

=> Du brauchst GridBagLayout oder BoxLayout.


----------



## LatinFavourite (2. Jun 2015)

Vielen Dank schon einmal für diesen Tipp. Die beiden Layout scheinen aber äußerst kompliziert zu sein. :-( Ich werde einmal versuchen, es mithilfe eines der Layouts umzusetzen. Liebe Grüße


----------



## LatinFavourite (4. Jun 2015)

Hallo nochmals,

habe nun etwas mit dem GridBagLayout probiert, doch es wird lediglich ein Quadrat angezeigt, was ist nun falsch?
Danke für jegliche Hilfe?


```
public class View extends JFrame{
	
	public View(){
		super("GridBagLayout Test");
		setSize(800, 600);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setResizable(false);
		setLocationRelativeTo(null);
		setLayout(new BorderLayout());
		
		
		JPanel raster = new JPanel(new GridBagLayout());
		Tile[][] tiles = new Tile[20][20];
		GridBagConstraints c = new GridBagConstraints();
		Tile tile;
		
		for(int i=0; i<20; ++i){
			for(int j=0; j<20; ++j){
				c.gridx = i;
				c.gridy = j;
				tile = new Tile();
				raster.add(tile, c);
				tiles[i][j] = tile;
			}
		}
		
		add(raster, BorderLayout.CENTER);
		setVisible(true);
	}
	
	private class Tile extends JComponent{
		protected void paintComponent(Graphics g){
			g.fillRect(0, 0, 50, 50);
		}
		
		public Dimension getPreferredSize(){
			return new Dimension(50, 50);
		}
	}

}
```


----------



## Enceladus271 (4. Jun 2015)

Die Fenstergröße 800x600 reicht nicht aus um alle 400 Tiles darzustellen. Du musst dort größere Werte nehmen.

Wenn man nicht immer selbst ausrechnen will wieviel Platz man braucht, kann man auch vor dem setVisible die Methode pack() aufrufen. Dadurch wird die Fenstergröße optimiert. Das setLocationRelativeTo sollte dann nach dem pack() aufgerufen werden:

```
pack();
setLocationRelativeTo( null );
setVisible( true );
```

Alternativ kannst du raster in eine JScrollPane legen:

```
add( new javax.swing.JScrollPane( raster ), BorderLayout.CENTER );
```


----------



## strußi (4. Jun 2015)

hab mal bei deiner Class Tile das JComponent duch JPanel ersetzt; damit man auch sieht, dass es mehr als ein würfel ist, hab ich es bunt färben lassen^^

```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class View extends JFrame{
 
    public View(){
        super("GridBagLayout Test");
        setLayout(new BorderLayout());

        JPanel raster = new JPanel(new GridBagLayout());
        Tile[][] tiles = new Tile[20][20];
        GridBagConstraints c = new GridBagConstraints();
        Tile tile;

        for(int i=0; i<tiles.length; i++){
            for(int j=0; j<tiles[ i].length; j++){
                c.gridx = i;
                c.gridy = j;
                tile = new Tile();
                raster.add( tile, c);
                
                tiles[i][j] = tile;
            }
        }

        add(raster, BorderLayout.CENTER);
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setLocationRelativeTo(null);

        setVisible(true);
    }

    private class Tile extends JPanel{
        @Override
        protected void paintComponent(Graphics gr){
            float[] hsb =new float[ 3];
            Random cRandom =new Random();
            int r = cRandom.nextInt(255);
            int g = cRandom.nextInt(255);
            int b = cRandom.nextInt(255);
            Color.RGBtoHSB(r, g, b, hsb);
            gr.setColor( Color.getHSBColor(hsb[ 0], hsb[ 1], hsb[ 2]));
            gr.fillRect(0, 0, 50, 50);
        }

        @Override
        public Dimension getPreferredSize(){
            return new Dimension(50, 50);
        }
    }


    public static void main( String[] args){
        View v =new View();
    }
}
```


----------



## LatinFavourite (5. Jun 2015)

Vielen Dank euch beiden. 

@Enceladus271 das mit der pack() Anweisung funktioniert, dann erscheint jedoch ein großes schwarzes Feld, das das gesamte Fenster ausfüllt. Habe nun noch Linen hinzugefügt mit.


```
setBorder(new LineBorder(Color.white));
```

@strußi Danke, das ist ja schon einmal hilfreich. 

Danke.


----------



## LatinFavourite (5. Jun 2015)

Eine kleiner Frage habe ich noch, welches Layout biete sich am besten an, wenn auf der linken Seite einige Elemente zur Bedienung angezeigt werden soll. Beim Borderlayout.WEST werden die Elemente zwar links aber mittig dargestellt. Soll ich für das Fenster dann lieber ein GridLayout wählen? Lieben Gruß


----------



## strußi (5. Jun 2015)

du kannst den elementen selber auch eine ausrichtung mitgeben element.setAlignmentY(LEFT_ALIGNMENT);


----------



## LatinFavourite (5. Jun 2015)

Super, das ist ja praktisch, und das wird von dem LayoutManager berücksichtigt? Vielen Dank auf jedenfall, probiere ich gleich aus.
Lieben Gruß


----------

