# Button Größe - Anfänger



## shwN (4. Aug 2011)

Hallo,

ich habe ein Prblem.

Ich hab mir mit Swing ein kleines Menü erstellt.
Mittig oben soll ein Button platziert sein. Für das Menü habe ich das BorderLayout hergenommen.

Wenn ich jetzt z.B. den Button einfüge (Center oder North...) dann ist er sehr groß.
Ich habe ihm auch ein Icon gegeben, der Button ist jedoch viel länger als das Icon.

Wie kann ich die Größe des Buttons bestimmen?


Hier ist der Code meines Buttons.


```
class StartButton extends JButton
{
    public StartButton()
    {
         Icon icon = new ImageIcon(this.getClass().getResource("./go_button.gif"));
         setIcon(icon);
         // 56x31
         setSize(icon.getIconHeight(),icon.getIconWidth());
         setPreferredSize(new Dimension(icon.getIconHeight(),icon.getIconWidth()));
         setVisible(true);
    }
}
```


----------



## xehpuk (4. Aug 2011)

Das BorderLayout beachtet nur sehr bedingt die PreferredSize der Komponenten. Wenn du es jedoch trotzdem verwenden möchtest, so brauchst du weitere Container, denen du dann die Komponenten hinzufügst.


```
import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ButtonTest {
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				final JFrame frame = new JFrame();
				final JPanel panel = new JPanel();
				panel.add(new JButton("Zentriert"));
				frame.add(panel, BorderLayout.NORTH);
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setSize(300, 200);
				frame.setLocationRelativeTo(null);
				frame.setVisible(true);
			}
		});
	}
}
```

PS: Dimension() und die setSize()-Methoden nehmen als ersten Parameter width, als zweiten height.


----------



## jgh (4. Aug 2011)

pack deinen Startbutton einfach in ein JPanel und dann in den Norden


----------



## shwN (4. Aug 2011)

Danke für die Antwort.

Ich glaube ich mache sogar genau das, wenn ich deine Antwort richtig verstanden habe.

Mein Hauptfenster hat ein BorderLayout. Diesem Hauptfenster füge ich ein Panel ein (north), dass auch BorderLayout hat. Und diesem Panel füge ich bei Center das Icon ein bzw. den Button und links und rechts sollen die Spielernamen sein. Nur zieht sich halt der Button von fast ganz links nach ganz rechts und bleibt nicht einfach mittig. Er ist eig. ja auch nur sehr klein wegen dem Icon.

Soll ich dem Panel jetzt bei Center nochmal ein Panel einfügen oder ?!
Schade das man nicht einfach mit setSize etc. die Buttongröße fest bestimmen kann!! -.-

Hier meine MainMethode:



```
public static void main(String[] args) 
    {
       
        
        // Fenster
        JFrame frame = new Fenster("*** TEST ***");
        
        
        // Panel
        JPanel north = new NorthPanel(); // hat auch BorderLayout
        
        
        // Spieler 
        JLabel playerone = new Label("Player 1");
        JLabel playertwo = new Label("Player 2");

        
        
        // Startbutton
        JButton startbutton = new StartButton();
            // andere Buttons
            JButton south = new iButton("south");
            JButton west = new iButton("west");
            JButton east = new iButton("east");
            JButton center = new iButton("center");
        
        
        // Komponenten ins Fenster hinzufügen
        north.add(startbutton, BorderLayout.CENTER);
        north.add(playerone, BorderLayout.WEST);
        north.add(playertwo, BorderLayout.EAST);
        
        frame.add(north, BorderLayout.NORTH);
        frame.add(south, BorderLayout.SOUTH);
        frame.add(west, BorderLayout.WEST);
        frame.add(east, BorderLayout.EAST);
        frame.add(center, BorderLayout.CENTER);
 
        
        
        
        
        // Sonstiges
        //frame.pack();
        frame.setVisible(true);
        
    }
```



Habe noch ein Foto mit angehängt.
Ein Bild sagt mehr als tausend Worte .


----------



## xehpuk (4. Aug 2011)

Deswegen gibts ja verschiedene LayoutManager. Je nach Szenario verwendet man einen anderen. Das BorderLayout gibt der Center-Komponente so viel Platz wie möglich.

In meinem Beispiel habe ich ein normales JPanel verwendet. Dieses verwendet standardmäßig das FlowLayout, welches die PreferredSize der Komponenten beachtet.

Siehe dazu: Using Layout Managers (The Java™ Tutorials > Creating a GUI With JFC/Swing > Laying Out Components Within a Container)


----------



## shwN (4. Aug 2011)

Das war sogar mein 1. Ansatz. Einfach ohne LayoutManager.
Jedoch kann ich doch ohne LayoutManager dann nicht sagen, dass ganz links ein Label, in der Mitte der Button und ganz rechts dann ein weiteres Label sein soll?

Ich hab mir da schon alle LayoutManager angeschaut und dachte BorderLayout wäre da passend. Habe aber nicht gewusst, dass BorderLayout dem Center so viel Platz gibt wie möglich.


----------



## jgh (4. Aug 2011)

Das BorderLayout gibt wie xehpuk schon sagt, der "Center"-Komponente allen Platz, der zur Verfügung steht. Dafür werden die Bereiche im N,E,S,W in ihrer preferierten Größes dargestellt. 
Wenn man das Verhalten weiß und beachtet, kann man für den Anfang sehr gut mit dem BorderLayout auskommen, vom NULL-Layout rate ich dir ab.


```
// Hilfspanel
		JPanel hilfsPanel = new JPanel();
		hilfsPanel.add(startbutton);
		// Komponenten ins Fenster hinzufügen
		north.add(hilfsPanel, BorderLayout.CENTER);
```


----------



## xehpuk (4. Aug 2011)

Dies ist ja nicht ganz ohne LayoutManager, FlowLayout ist schließlich auch einer. 

Ganz ohne gehts natürlich auch (Layout auf null setzen), aber ist nicht unbedingt empfehlenswert.

BorderLayout ist schon in Ordnung, solange du im Center eben ein anderes Layout verwendest. Mit dem BoxLayout könntest du den Norden auch gut gestalten.

Zum Abschluss auch mal der Vergleich zwischen deiner momentanen Version und dann mit eingeschobenem FlowLayout:


```
import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class BorderLayoutTest {
	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				final JFrame frame = new JFrame();
				final JPanel north = new JPanel(new BorderLayout());
				north.add(new JButton("GO!"), BorderLayout.CENTER);
				north.add(new JLabel("Player1"), BorderLayout.WEST);
				north.add(new JLabel("Player2"), BorderLayout.EAST);
				frame.add(north, BorderLayout.NORTH);
				frame.add(new JButton("west"), BorderLayout.WEST);
				frame.add(new JButton("south"), BorderLayout.SOUTH);
				frame.add(new JButton("east"), BorderLayout.EAST);
				frame.add(new JButton("center"), BorderLayout.CENTER);
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setSize(300, 200);
				frame.setLocationRelativeTo(null);
				frame.setVisible(true);
			}
		});
	}
}
```


```
import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class FlowLayoutTest {
	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				final JFrame frame = new JFrame();
				final JPanel north = new JPanel(new BorderLayout());
				final JPanel northCenter = new JPanel(); // implizit FlowLayout, oder explizit: new JPanel(new FlowLayout())
				northCenter.add(new JButton("GO!"));
				north.add(northCenter, BorderLayout.CENTER);
				north.add(new JLabel("Player1"), BorderLayout.WEST);
				north.add(new JLabel("Player2"), BorderLayout.EAST);
				frame.add(north, BorderLayout.NORTH);
				frame.add(new JButton("west"), BorderLayout.WEST);
				frame.add(new JButton("south"), BorderLayout.SOUTH);
				frame.add(new JButton("east"), BorderLayout.EAST);
				frame.add(new JButton("center"), BorderLayout.CENTER);
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setSize(300, 200);
				frame.setLocationRelativeTo(null);
				frame.setVisible(true);
			}
		});
	}
}
```


----------



## shwN (4. Aug 2011)

Danke, funktioniert jetzt endlich !!

Da kann man echt einfach rumspielen mit den verschiedenen LayoutManagern und einfach Panels einfügen die wiederum einen LayoutManager haben usw...   


Eine hoffentlich letzte Frage:

Warum hat mein NorthPanel nicht die selbe Farbe wie mein Frame?
Habe beide auf Color.gray gesetzt und sie sehen unterschiedlich aus.
Setzte ich beides auf white oder red sehen beide gleich aus.

Das macht doch keinen Sinn oder? ^^




```
// Fenster indem alles platziert wird
class Fenster extends JFrame
{
    public Fenster(String fenstername)
    {
        super(fenstername);
        setBackground(Color.gray);
        setSize(600,200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);        
        setResizable(false);
        BorderLayout bl = new BorderLayout(1,1);
        setLayout(bl);
        
    }
}


// North-Fenster
class NorthPanel extends JPanel
{
    public NorthPanel()
    {
        setBackground(Color.gray);
        FlowLayout fl = new FlowLayout();         // standardmäßig flowlayout..
        setLayout(fl);
    }
}
```


----------



## Camino (4. Aug 2011)

In dem Code ist das NorthPanel ja garnicht zum Fenster hinzugefügt. Ansonsten vermute ich mal, dass du beim NorthPanel evtl. noch setOpaque setzen müsstest.


----------



## xehpuk (4. Aug 2011)

Die Farbe des NorthPanel wird richtig gesetzt. Das Problem hier ist, dass das Setzen der Hintergrundfarbe eines JFrame keine direkten Auswirkungen hat. Das liegt daran, dass man die Komponenten nicht direkt dem JFrame hinzufügt, sondern dem ContentPane.

Probier mal im Konstruktor des JFrame ein 
	
	
	
	





```
getContentPane().setBackground(Color.GRAY);
```
.


----------



## jgh (4. Aug 2011)

wenn du das NorthPanel auf 
	
	
	
	





```
setOpaque(false);
```
 setzt, dann ist es durchsichtig und zeigt den Hintergrund den Frames an.


```
public Fenster(String fenstername)
    {
        super(fenstername);
        getContentPane().setBackground(Color.gray);
```

so klappt es dann auch


----------



## shwN (4. Aug 2011)

Danke, also das NorthPanel wird dem Fenster schon hinzugefügt. Das waren jetzt nur meine beiden Subklassen... in der main Methode füge ich es natürlich mit .add(..) hinzu.


Also ich glaube schon das sich die Farbe ändert. Lasse ich beim Fenster und beim Northpanel das mit der Farbe weg, ist beides ganz hell.

Gebe ich den Northpanel die Farbe rot (Screenshot), dann kriegt es auch wirklich rot.
Gebe ich anschließend auch dem Fenster die Farbe rot passt alles perfekt.


Und das mit getContentPane().. funktioniert auch nicht ganz. (siehe Screenshots)


----------



## shwN (4. Aug 2011)

Ok danke!

Das mit "setOpaque(false);" hat geklappt. Farbe ist jetzt überall "gleich-grau".

Danke für eure Hilfe !


----------

