Java Benötige Unterstützung bei der Bekämpfung der Sturheit von JTabbedPane!

Killkrog

Lt. Junior Grade
Registriert
Jan. 2006
Beiträge
354
Hi Jungs und Mädels.

Ich versuch's mal kurz zu machen. Ich habe eine mäßig verschachtelte GUI mit einer JTabbedPane. Obwohl verschachtelt, alles sauber runterprogrammiert. Keine "hacky" Sachen, die mit den Größen der Komponenten in irgendeiner Art und Weise rumspielen.

So, folgendes Phänomen:
Trotz Aufruf von pack() werden die Inhalte der JTabbedPane nicht korrekt dargestellt, sie sind zu klein, was im Stauchen der Inhalte resultiert. Erst wenn man mit der Maus das Fenster nur um wenige Pixel (dazu später mehr) vergrößert, werden die Inhalte korrekt angezeigt.

Habe mal einen ChangeListener an die JTabbedPane geklebt und lasse mir immer, wenn ich ein Tab auswähle, die Werte von getSize() und getPreferredSize() von jeweils der JTabbedPane und der Komponente ausgeben, die hinter dem Tab liegt:

Code:
  Component getPreferredSize() -> java.awt.Dimension[width=495,height=521]
           Component getSize() -> java.awt.Dimension[width=495,height=519]
JTabbedPane getPreferredSize() -> java.awt.Dimension[width=500,height=545]
         JTabbedPane getSize() -> java.awt.Dimension[width=500,height=545]
Auffallen sollte hier der kleine Unterschied zwischen der getSize() und getPreferredSize() der Komponente. Dieser Unterschied ist auch genau derjenige, um den man das Fenster per Maus vergrößeren muss, damit alles ordentlich aussieht.

Ich kann mir das absolut nicht erklären. Hat jemand eventuell dieses Verhalten schon einmal beobachtet und kann Hilfestellung geben?

Eventuell noch ein kleines Detail: Wenn ich die Tabs nicht oben sondern links anzeigen lasse, manifestiert sich die kleine Größenabweichung auf der x-Achse und nicht mehr auf y-Achse.

Wären um jeden Vorschlag dankbar.

Lieber Gruß,
ein furchtbar verzweifeltes Killy
 
Wie sieht der Layout-Code aus? Vermutlich liegt dort der Fehler.

Poste bitte ein lauffähiges Beispiel, dann wird man den Fehler schnell ausmachen können.
 
Hier ein einfaches Beispiel, dessen Ausgabe sich mit der oben beschriebenen deckt.

Code:
public class Example {

	public Example() {
		JFrame frame = new JFrame();

		frame.setLayout(new BorderLayout(0, 0));
		frame.add(new LeftPanel(), BorderLayout.WEST);
		frame.add(new RightPanel(), BorderLayout.CENTER);

		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

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

Code:
public class LeftPanel extends JPanel {

	private final Dimension prefSize = new Dimension(200, 300);

	public LeftPanel() {
		setBorder(new CompoundBorder(new EmptyBorder(5, 5, 5, 5), new TitledBorder("Left Panel")));
	}

	public Dimension getPreferredSize() {
		return prefSize;
	}
}

Code:
public class RightPanel extends JPanel {

	public RightPanel() {
		setBorder(new CompoundBorder(new EmptyBorder(5, 0, 5, 5), new TitledBorder("Right Panel")));

		final JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);

		final Dimension size = new Dimension(600, 400);
		JPanel panel1 = new JPanel();
		JPanel panel2 = new JPanel();
		panel1.setPreferredSize(size);
		panel2.setPreferredSize(size);

		tabbedPane.add("Panel 1", panel1);
		tabbedPane.add("Panel 2", panel2);

		tabbedPane.addChangeListener(new ChangeListener() {

			public void stateChanged(ChangeEvent e) {
				System.out.println(tabbedPane.getSelectedComponent().getPreferredSize());
				System.out.println(tabbedPane.getSelectedComponent().getSize());
			}
		});

		add(tabbedPane);
	}
}
 
Seltsamer Fehler. Am Layout-Code sollte es nicht liegen.

Wenn ich den Tab-Container wie folgt ändere:

Code:
final JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP);

dann wird die gewünschte Größe erreicht (TOP kann man dann aber auch weglassen). Wird JTabbedPane.SCROLL_TAB_LAYOUT verwendet, ist das nicht der Fall. Verwendet man ein anderes Look&Feel, kann die Abweichung von der gewünschten Größe sogar größer sein!

Ich würde mir mal die Implementierung des UI-Delegates anschauen. Möglicherweise gibt es einen Workaround, falls man die alternative Tab-Policy nicht verwenden kann/möchte.

Wieviele Tabs werden denn tatsächlich verwendet? Wenn nicht alle auf einmal dargestellt werden können, würde ich ohnehin eine andere Strategie verwenden.
Ergänzung ()

Ein Tipp noch zum Stil: Ich würde vom Einsatz von TitledBorder abraten. Verwende besser lediglich eine horizontale Trennlinie (ev. mit Text) wenn notwendig, oder einfach etwas leeren Platz. Dadurch wirkt das Design sehr viel unaufgeregter - und professioneller.

Sogar Microsoft entwickelt sich mittlerweile in diese Richtung:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa511459.aspx
 
Sehr fein!
Ich wusste beim Schreiben dieses Programmteiles noch nicht genau, wie viele Tabs hinzukommen, aber im Endeffekt ist die policy nicht wichtig, daher ein schön einfacher Fix. Vielen Dank dafür! Trotzdem ein komischer Fehler...
Die TitledBorder ist in meinem Programm, auch laut Aussage von MS, in Ordnung, weil ich damit wirklich zusammengehörige Kontrollstrukturen gruppiere, auch wenn das nicht ersichtlich war aus meinem Beispiel. Danke trotzdem für den Hinweis!

Schönen Abend noch!
 
Wie MS so schön schreibt, geht der Trend in Richtung Klarheit - möglichst wenig Linien sollen den Benutzer verwirren. Deshalb würde ich solche Boxen nur nutzen, wenn es gar nicht anders geht.

Ein TabbedPane sorgt selber schon für eine Begrenzung. Da kommt es dann schnell zu "Border Cruft", wie ich das zu nennen pflege. Aber klar, ich kenne Deine Anwendung nicht, vielleicht ist es in Deinem Fall nicht anders zu machen (was ich bezweifele ;)).
 

Ähnliche Themen

Antworten
10
Aufrufe
3.637
Zurück
Oben