# GridBagLayout - Zeitplan



## Nardian (19. Sep 2012)

Hey,

will als "kleine" Übung eine Art Zeitplan schreiben. Dazu wollt ich das GridBagLayout verwenden weil es einige der Probleme recht schön lösen würde..

Im Grunde hab ich mir das so vorgestellt, dass die 1. Zeile natürlich die Tage anzeigen, und die 1. Spalte die Stunden (0-23), wobei die Zelle 1/1 ganz leer bleibt.. 
Bislang würde sich ja auch eine JTable oder sowas anbieten, allerdings gäbs damit ein Problem:

Ich möchte dass in dem Daten-Fenster man Termine anzeigen lassen kann (also einfach Blöcke) - fürs erste will ich mal davon ausgehn, dass jeder Termin spätestens um 24:00 endet.
Das Problem ist, wenn sich Termine übschrneiden. Ich hätte da gerne, wenn dann die 2 Termine sich einfach die Spalte teilen und nebeneinander sichtbar sind. 
Damit werde ich denke ich wohl Probleme mit der Tabelle bekommen, da ich nicht nur alle Spalten verschieben muss, sondern auch nicht genau weiß, wie ich dann nur eine Überschrift (also die Zellen aus der 1. Zeile) über 2 Spalten kriege...

Da bietet sich GridBagLayout recht schön an.. also soweit kein Problem.. nur - woran ich gerade festhänge ist, dass ich nicht davon ausgehen will, dass alle 24 Stunden sich ausgehen.. Das heißt, irgend eine Art von Scrollbalken muss her --> JScrollPane 
Nur wie krieg ich das hin, dass die 1. Zeile immer sichtbar ist, ABER trotzdem die Breite der Zelle aus 1/1 freilässt (also das Ganze auf 2 GridBagLayouts aufzuteilen wird wohl nicht funktionieren).

Kann mir aber auch nicht vorstellen wie ich mit einem GridBagLayout sowas hinkriegen könnte, dass Zeile 2 bis 25 (oder so) scrollbar ist, allerdings Zeile 1 immer bleibt... Also denke ich dass ich mit GridBagLayout auch aufm Holzweg bin...

Hat jemand eine Idee?

MfG


----------



## jgh (19. Sep 2012)

BorderLayout wählen, oben im Norden dann halt mit preferedSize und/oder bspw. GridLayout die Daten/Tage, und im Center eine JScrollPane die dann bspw ein JPanel mit GridBagLayout besitzt...ABER imho ist das nicht unbedingt Anfängerfreundlich, ohne dir jetzt AnfängerStatus unterstellen zu wollen.


----------



## Nardian (19. Sep 2012)

Danke mal für die Antwort 

Ja, auf sowas bin ich schon gekommen, nur sehe ich nicht wie ich dynamisch auf die Breite der 1. Spalte kommen / reagieren soll...

Eine Art Listener die auf einen der JLabels schaut ob dessen Breite sich verändert und dann so den BorderLayout.North's freizulasenden Platz korrigiert... halte ich nicht für besonders schön.... OK - würde vermutlich sogar funktionieren geb ich zu... aber naja.. ^^


----------



## jgh (19. Sep 2012)

??? evtl. ist es auch zu spät für mich, wieso soll denn die 1.Spalte dynamisch sein? Da werden doch feste Zeitintervalle genutzt...

Meinst du die erste Reihe evtl. ? Und sofern die sich im BorderLayout-North befinden, bekommen sie eh genau die Größe die sie benötigen => dafür brauchst du keinen Listener oder ähnliches. Solltest du JLabels benutzen ist die preferedSize, die Size die benötigt wird um das Label korrekt darzustellen.


----------



## Nardian (19. Sep 2012)

hmm.. 

was ich meinte ist sowas:


```
<Leer> | Montag | Dienstag ...
00:00  |        |
01:00  |        |
.
.
.
```

Sowas ist mit einem Gridbaglayout ja kein Problem. Wenn ich dich richtig verstanden hab, meintest du ja, dass man die 1. Zeile (also "<Leer>, Montag, ...") einfach in nen BorderLayout.NORTH schiebt, und der Rest bleibt GridBagLayout, allerdings im CENTER des BorderLayouts und nochmal geschachtelt in einem JScrollPane...

Mein "Problem" war, das die Breite jeder Spalte (sowohl vom NORTH als auch von den eigentlich Daten im CENTER) gleich sein sollten --> die 1. Spalte von NORTH (also "<Leer>") müsste dann freigelassen werden. 

Dachte daran, dass das ein Problem wäre, wenn sich diese verändert, wenn man das Fenster skaliert, allerdings muss ich mich grad selber fragen warum sie sich ändern sollte.. Wenn man das Fenster skaliert interessiert einen wohl eher die Daten als der Anzeige für die Uhrzeit mehr Platz zu geben ^^

Sprich, auch im NORTH ein GridBagLayout mit einen JLable(""), dass die selbe prefferedSize hat,wie der Breiteste aus der 1. Spalte vom CENTER...

Ja, könnte klappen, Danke


----------



## jgh (19. Sep 2012)

jo, sollte eigentlich...habe sowas -kA wann und wie genau- mal für einen Wochen-Plan gemacht, evtl. finde ich das noch irgendwo...

Viel Spaß und Viel Erfolg dabei


----------



## bERt0r (19. Sep 2012)

Mit dem MigLayout sollte sowas am einfachsten gehen, das wurde für Kalender entwickelt: MiG Layout Java Layout Manager for Swing and SWT


----------



## Nardian (19. Sep 2012)

MigLayout sieht ganz nett aus, jedoch löst es leider nicht das grundsätzliche Problem mit dem Scrollbalken...

Soweit bin ich daweil gekommen.. 







Sieht eigentlich schon fast gut aus.. würde aber noch sehr gern die Borders "gerade" kriegen... 
Hab schon etwas getrickst und der ersten und letzten Zelle von headers, das heißt:
* Die 1/1-er Zelle (die leer ist), ist wirklich eine leere JPanel mit erzwungener prefferedSize und Size (nur eines von den beiden wurde irgendwie ignoriert)
* Die 8/1-er Zelle ("23  So") hat einen insets.right, damit der Abstand von dem Scrollbalken drunter eingehalten wird..

Dennoch gibt es kleinere Unterschiede... jemand eine Idee wie man die wegbekommt?

MfG


----------



## jgh (19. Sep 2012)

für die 1/1 Zelle bietet sich auch an als JLabel mit Background = Foreground zu nutzen und dann dementsprechend einen gleichen Text zu setzen.


----------



## Nardian (19. Sep 2012)

Ja, stimmt. Ist vielleicht etwas "hübscher" vom Code (JPanel als Objekt wird wohl etwas fetter sein als nur ein JLabel), aber am eigentlich Problem ändert das leider nichts.

Hab gerade etwas experimentiert.. das heißt, ich hab mit 
	
	
	
	





```
headerPanel.setBackground(Color.black);
```
 nun herausgefunden, dass GridBagLayout erst dann die einzelnen Zellen "skaliert" sobald er alle skalieren kann (ist ja logisch, passt ja auch). Solange er dies jedoch nicht kann, gibt es sowohl ganz links als auch ganz rechts einen Abstand - also alle meine header-Zellen sind zentriert. 
Da es im dataPanel (abgesehen von dessen Scrollbar) auch so ist, ist das ja nicht weiter schlimm. Ich denke ich könnte selbst diese kleinen Unterschiede (wie zuvor angesprochen) beheben, wenn ich GridBagLayout dazu kriege, eine leere Zelle *nach* "23 So" zu schmuggeln, allerdings so, dass diese Zelle *immer* ganz rechts bleibt. Der Idee wäre, dass diese an den Rand geklebte Zelle den Abstand "simulieren" sollte, die auch die Scrollbar drunter verbraucht. Wenn GridBagLayout dann auch noch erst links von dieser Schmugglerzelle (^^) anfängt mit dem zentrieren, dürfte das wohl mein Problem (mit etwas Glück sogar perfekt) beheben.

Habe es schon mit dem 
	
	
	
	





```
gbc.anchor = GridBagConstraint.LINE_END;
```
 bzw 
	
	
	
	





```
FIRST_LINE_END
```
 versucht, ohne Erfolg...

Eine andere Idee?

[edit]
lol - eine recht... fiese... Idee wäre natürlich den headerPanel ein BorderLayout zu geben, in dessen EAST die Schmugglerzelle zu stecken, und den rest wie gehabt in den CENTER zu lassen... 
könnte gehn -aber ich denke dass es schon langsam viel wird mit den Layout-Schachtelungen ^^
[/edit]


----------



## Nardian (20. Sep 2012)

Sorry für Doppelpost.. hab denk ich mein (bzw eines meiner vielen ^^) Problem/e auf ein kleines Beispiel reduzieren können...

Dieser Code

```
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

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

public class Main {
	public static void main(String[] args) {
		JFrame mainFrame = new JFrame("GridBagLayout Test");
		
		JPanel mainPanel = new JPanel(new GridBagLayout());
		mainFrame.setContentPane(mainPanel);
		
		Main.initMainPanel(mainPanel);
		
		mainFrame.setSize(202, 100);
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setLocationRelativeTo(null);
		mainFrame.setVisible(true);
	}
	
	private static void initMainPanel(JPanel mainPanel) {
		JLabel[] labels = new JLabel[40];
		
		mainPanel.setBackground(Color.black);
		
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = gbc.gridy = 1;
		gbc.anchor = GridBagConstraints.WEST;
		gbc.weightx = 1;
		
		for (int i = 0; i < labels.length; i++) {
			labels[i] = new JLabel("" + i);
			labels[i].setOpaque(true);
			
			mainPanel.add(labels[i], gbc);
			gbc.gridx++;
		}
	}
}
```

liefert dieses Ergebnis:






Mein Problem ist der schwarze Fleck links von 0. 

Ich hatte mir erhofft, dass mit [c]gbc.anchor = GridBagConstraints.WEST;[/c] die 0 immer ganz links stehen wird, und der rest sich erst dann ausdähnt, wenn rechts genug platz freigeschaffen wurde (also kurz - die zeile sollte linksbündig sein und bleiben)

Vielleicht verstehe ich GridBagLayout auch falsch, aber ich verstehe nicht warum sowas nicht geht?

Oder bin nur ich der Dumme der etwas falsch mach? 

ps.: neben [c]WEST[/c] hab ich auch [c]LINE_START[/c] probiert, ändert nichts.


----------



## jgh (20. Sep 2012)

imho macht das keinen Unterschied, denn das GridBagLayout centert die Komponente...

sowas wie 


```
int defaultInset = 10;
for (int i = 0; i < labels.length; i++) {
			if (i == 0) {
				gbc.insets = new Insets(defaultInset, 0, defaultInset,
						defaultInset);
			} else {
				gbc.insets = new Insets(defaultInset, defaultInset,
						defaultInset, defaultInset);
			}
```

hilft nicht??

dann halt die ganze Komponente irgendwie in den Westen legen:


```
mainFrame.add(mainPanel, BorderLayout.WEST);
```


----------



## Nardian (20. Sep 2012)

> imho macht das keinen Unterschied, denn das GridBagLayout centert die Komponente...


 hmm ja.. aber wozu dann der anchor? bzw wäre es dann mal nett zu erwähnen dass fill den anchor effekt aufhebt...

das mit den Insets hilft da auch nicht, und BorderLayout.WEST lässt zwar alles wie gewünscht links kleben, allerdings skaliert es nicht mehr - nimmt also nicht mehr den ganzen frame ein, wenn es mehr platz gibt als minimal benötigt.


----------



## Nardian (20. Sep 2012)

Hi,

nur mal kurz ein nachträgliches Danke an euch beide - letzten Endes hats dann doch mit dem MigLayout geklappt wie ichs mir gewünscht hatte 

Solche kleinen Pixel-Probleme können echt nervig sein - wusste bis lang zb gar nich, dass ein JScrollPane ein 1px Border oder sowas hat... muss man MigLayout auch erstmal beibringen dass er da etwas freilassen soll 

Egal, passt jetzt alles... und ich hab tatsächlich gefallen an MigLayout gefunden, denke dass ich nach langen Jahren von GridBagLayout auf Mig umsteigen werde.. sehe nichts was GridBag könnte aber Mig nicht - anders rum gibts schon einige Sachen 

Danke, nochmals


----------

