Swing Ausrichtung innerhalb der Reiterlasche eines JTabbedPanes

hansmueller

Bekanntes Mitglied
Hallo,

ich habe ein JTabbedPane mit den Reiterlaschen auf der linken Seite.
In einigen Reiterlaschen habe ich ein LabelButton-Element hinzugefügt, mit dem man den entsprechenden Reiter löschen kann. Andere Reiterlaschen sind Standard.

Das Problem ist, daß ich den Inhalt der Reiterlaschen so ausrichten will, daß der Text immer linkbündig ist, aber der Button immer rechtbündig.

Als L&F benutze ich das Standard Ocean.
Dort werden die Inhalte der Reiterlaschen anscheinend immer zentriert.
Weiß irgendjemand wie man die Ausrichtung innerhalb der Reiterlaschen beeinflussen kann?
Auch hätte ich gerne, daß alle Reiterlaschen gleich hoch sind.

Hier mal ein kleines Beispielprogramm:
Java:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.metal.MetalTabbedPaneUI;
import javax.swing.JComponent;

public class MainProg
{
	JFrame Fenster;
	JTabbedPane jtp;
	
	static int x = 0;
	static int y = 0;
	
	public static void main(String[] args)
	{
		MainProg x = new MainProg();
	}

	public MainProg()
	{
		Fenster = new JFrame("Versuch Reiter");
		Fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		jtp = new JTabbedPane(JTabbedPane.LEFT);
		
		//jtp.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
		//jtp.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
		//jtp.setAlignmentX(JTabbedPane.LEFT_ALIGNMENT);
		//jtp.setAlignmentY(JTabbedPane.LEFT_ALIGNMENT);
		
		//jtp.setUI(new AlignedTabbedPaneUI());
		
		jtp.addTab("Reiter 01", new JLabel("Tabinhalt01"));
		jtp.setTabComponentAt(0, new yTabKomponenteLabelButton());
		
		jtp.addTab("Reiter 02 Mehr Text", new JLabel("Tabinhalt02"));
		jtp.setTabComponentAt(1, new yTabKomponenteLabelButton());
		
		jtp.addTab("Normaler Reiter", new JLabel("Tabinhalt03"));
		jtp.addTab("Standard Reiter", new JLabel("Tabinhalt04"));
		
		mGroesseermittelnundsetzen();
		
		Fenster.add(jtp);
		
		Fenster.setSize(600, 600);
		Fenster.setVisible(true);	
	}

	public void mGroesseermittelnundsetzen()
	{
		x = 0;
		y = 0;
		
		for(int i = 0, m = jtp.getTabCount(); i < m; i++)
		{
			Component c = jtp.getTabComponentAt(i);
			
			Dimension d = new Dimension();
			
			if(c != null)
			{
				//Hier wird die Größe des LabelButton-Elementes ermittelt
				d = ((yTabKomponenteLabelButton) c).getLayout().preferredLayoutSize((yTabKomponenteLabelButton) c);
				
				if(x < d.width)
				{
					x = d.width;
				}
				
				if(y < d.height)
				{
					y = d.height;
				}
			}
			else
			{
				//Hier wird die größe des Textes ermittelt, den ein normaler Reiter enthält.
				//Stimmt leider nicht exakt mit dem dargestellten Text überein.
				//Ist notwendig, falls der Text länger als das LabelButton-Element ist.
				System.out.println(jtp.getTitleAt(i));
				JPanel pndummy = new JPanel(new GridLayout(1, 1, 0, 0));
				JLabel dummy = new JLabel(jtp.getTitleAt(i));
				pndummy.add(dummy);
				
				d = pndummy.getLayout().preferredLayoutSize(pndummy);
				
				if(x < d.width)
				{
					x = d.width;
				}
				
				if(y < d.height)
				{
					y = d.height;
				}				
			}
		}
		
		
		//Jetzt werden noch allen LabelButton-Elementen die oben ermittelte Größe zugewiesen.
		for(int i = 0, m = jtp.getTabCount(); i < m; i++)
		{
			Component c = jtp.getTabComponentAt(i);
			
			if(c != null)
			{
				((yTabKomponenteLabelButton) c).setPreferredSize(new Dimension(x, y));				
			}
		}
	}
	
	
	class yTabKomponenteLabelButton extends JPanel
	{
		TabJButton btn;

		JLabel lb;

		public yTabKomponenteLabelButton()
		{
			// super.setLayout(new GridLayout(1,1));//(FlowLayout.LEFT, 0, 0));

			GridBagLayout gbl = new GridBagLayout();
			this.setLayout(gbl);

			this.setOpaque(false);//true);

			lb = new JLabel()
			{
				public String getText()
				{
					int i = jtp
							.indexOfTabComponent(yTabKomponenteLabelButton.this);
					if (i != -1)
					{
						return jtp.getTitleAt(i);
					}

					return null;
				}
			};

			// JPanel pn = new JPanel(new BorderLayout(0, 0));

			// pn.add(lb, BorderLayout.WEST);

			btn = new TabJButton();
			// pn.add(btn, BorderLayout.EAST);

			// this.add(pn);

			GridBagConstraints gbc = new GridBagConstraints();
			gbc.gridx = 0;
			gbc.gridy = 0;
			gbc.gridwidth = 1;
			gbc.gridheight = 1;
			gbc.weightx = Integer.MAX_VALUE;
			gbc.weighty = 0;
			gbc.fill = GridBagConstraints.NONE;
			gbc.anchor = GridBagConstraints.WEST;
			gbc.insets = new Insets(0, 0, 0, 0);

			gbl.setConstraints(lb, gbc);
			this.add(lb);

			gbc = new GridBagConstraints();
			gbc.gridx = 1;
			gbc.gridy = 0;
			gbc.gridwidth = 1;
			gbc.gridheight = 1;
			gbc.weightx = Integer.MAX_VALUE;
			gbc.weighty = 0;
			gbc.fill = GridBagConstraints.NONE;
			gbc.anchor = GridBagConstraints.EAST;
			gbc.insets = new Insets(0, 0, 0, 0);

			gbl.setConstraints(btn, gbc);
			this.add(btn);
		}

		class TabJButton extends JButton implements ActionListener
		{
			public TabJButton()
			{
				this.setText("Löschen");
				this.addActionListener(this);
			}

			@Override
			public void actionPerformed(ActionEvent e)
			{
				int i = jtp.indexOfTabComponent(yTabKomponenteLabelButton.this);

				if (i != -1)
				{
					jtp.removeTabAt(i);
					mGroesseermittelnundsetzen();
				}
			}
		}
	}
}

Wie ihr seht, habe ich schon eine Teillösung gefunden, aber ich finde diese nicht sehr elegant. Da muß es doch noch was besseres geben.

Die einzige Möglichkeit, die mir noch einfällt ist die, daß ich auch für die Standard-Reiterlaschen ein Label-Element mache und deren Größe ermittle. So könnte ich auch die Höhe steuern.

Ich habe auch schon versucht ein bißchen mit dem L&F zu spielen und dort einzelne Methoden zu überschreiben, bisher aber ohne Erfolg.

MfG
hansmueller
 

hansmueller

Bekanntes Mitglied
Hallo,

hat da wirklich niemand eine bessere Idee?
Sonst kann man ja auch jeden S***** ganz genau einstellen - nur bei den Reiterlaschen soll das jetzt nicht gehen?

MfG
hansmueller
 

CroniD

Aktives Mitglied
Benutze doch einfach das BorderLayout für deine "yTabKomponenteLabelButton" Komponente. Das Label bringst du bei BorderLayout.CENTER unter und den Button bei BorderLayout.LINE_END bzw. BorderLayout.EAST.

Kleiner Ausflug zum BorderLayout: Galileo Computing :: Java ist auch eine Insel – 19.11 Alles Auslegungssache: die Layoutmanager

Oder du benutzt gleich eine der zahlreichen JTabbedPane Erweiterungen, die man so im Netz finden kann. Google einfach nach: JTabbedPane TabComponent Button

Da findest du mit sicherheit so einiges. :)

EDIT: Ach ja, und bei dem JLabel setzt du am besten noch die "HorizontalAlignment" Property auf SwingConstants.LEFT, falls du auch noch ein Icon in dem JLabel anzeigen willst, dann auch die "HorizontalTextPosition" setzen!
 
Zuletzt bearbeitet:

hansmueller

Bekanntes Mitglied
Hallo,

@VfL_Freak: Ocean ist das Standard-L&F von Java. Den Link kenne ich schon, aber trotzdem Danke.

@CroniD: BorderLayout in meiner "yTabKomponenteLabelButton"-Komponente hat ebenso keine Auswirkung wie das von mir momentan verwendete GridBagLayout. Ohne die "mGroesseermittelnundsetzen()"-Methode werden die LabelButton-Komponenten auf ihre optimale Größe reduziert und zentriert in der Reiterlasche dargestellt. Das ist ja Schwierigkeit. Wie stellt man möglichst elegant die Ausrichtung in der Reiterlasche ein? Für dieses Teil gibt es da anscheinend gar nichts. Weder für Komponenten, die man wie meine LabelButton-Komponente hinzufügt, noch für den einfachen Text. Das ist immer nur zentriert.

MfG
hansmueller
 
B

bERt0r

Gast
BorderLayout funktioniert bei mir:

Java:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;


public class TabTest extends JFrame{
	
	
	JTabbedPane jtp=new JTabbedPane(JTabbedPane.LEFT);
	
	public TabTest()
	{
		jtp.addTab("Sepp", new JLabel("Sepps Component"));
		JButton sepp=new JButton("Sepp der Button");
		jtp.setTabComponentAt(0, new TabPanel(sepp,BorderLayout.WEST));
		
		jtp.addTab("Fritz", new JLabel("Fritzis Component"));
		JLabel fritz=new JLabel("Fritz das Label");
		jtp.setTabComponentAt(1, new TabPanel(fritz,BorderLayout.EAST));
		
		this.add(jtp);
		this.setSize(400,400);
		this.setVisible(true);
	}
	
	public static void main(String args[])
	{
		new TabTest();
	}
	
	class TabPanel extends JPanel
	{
		JComponent component;
		
		public TabPanel(JComponent c,String alignment)
		{
			component=c;
			this.setLayout(new BorderLayout());
			this.add(c,alignment);
		}
		
		public Dimension getPreferredSize()
		{
			return new Dimension(200,30);
		}
	}
}
 

hansmueller

Bekanntes Mitglied
Hallo,

@bERt0r: nur wenn man mit getPreferredSize() die Größe der Komponente manuell festlegt. Das entspricht in etwa meiner mGroesseermittelnundsetzen()-Methode.

Anscheinend bleibt mir nichts anderes übrig, in jedem Reiter, auch wenn er nur Text enthält eine eigene TabComponent zu setzen und dann allen TabComponenten die Abmessungen der größten TabComponente geben. Der Inhalt der TabComponenten läßt sich dann nach Belieben mit den Layoutmanagern steuern.

Hatte gehofft, das es da was Eleganteres gibt, mit dem man das besser steuern kann.

MfG
hansmueller
 

CroniD

Aktives Mitglied
Schau dir das mal was ich angehängt habe. Es ist in der Tat etwas umfangreicher. In dem Zip File findest du eine Klasse "JTabbedPaneNSSC" mit jeder Menge Extras. Diese Komponente hatte ich letztes Jahr geschrieben, aber bin nie dazu gekommen sie fertig zu stellen. Aber man kann sie benutzen, keine Sorge, jedoch ist der Code kaum dokumentiert. D.h. du musst dich ein bisschen durch meinen Code wuschteln. ^^ Eine main Methode findest du in der Hauptklasse. Diese startet eine kleine Demo.

Ach ja, einige Sachen in der Klasse stammen nicht direkt von mir. Also wenn du darüber nach denkst den Code heraus zugeben, dann solltest du aus Rechtlichen Gründen (und moralischen) diese Codeanteile entfernen. So lange du es aber private oder zu schulischen Zwecken verwenden möchtest: feel free. :)

Noch kurz was dir diese Komponente bereits bietet:
- Schliessbare Tabs (per Button, verwende die "TabCloseEventListener" wenn du danach horchen möchtest)
- editierbare Tabtitel per Mouse Klick
- Defaulteinstellungen (weitestgehend) für den Fall, dass mal alle Tabs vom User geschlossen wurden
- MinWidth und MaxWidth für die Tab Komponenten und dafür auch vordefinierte Kontextmenüs
- eine Property, ob ein Tab entfernt werden kann oder nicht (via removeTab() Methode, ne)
- Die Tabtitle skalieren mit der JTabbedPane

Na ja, ich hoffe ich habe nichts vergessen ins Zip zu packen. Falls was fehlen sollte, dann nur unwichtiges und das solltest dann einfach auskommentieren.

Ach und mir fällt noch ein, dass es nen dämlichen Bug mit der Property "tabLayoutPolicy = WRAP_TAB_LAYOUT" gab. Diese nicht verwenden oder vorher selber fixen. :)
 

Anhänge

  • nssc_private.zip
    20,8 KB · Aufrufe: 2
Zuletzt bearbeitet:

hansmueller

Bekanntes Mitglied
Hallo,

@CroniD: Vielen Dank, ich werde mir den Code zu Gemüte ziehen. Habe nur mal kurz drübergesehen und da sind wirklich viele Extras drin. Ich habe mir zwar inzwischen selber was gebastelt (auch mit der Möglichkeit die Tabtitel zu editieren) aber gegen das, was du da gemacht hast, wirkt mein Teil einfach nur stümperhaft.

Es fehlen nur die Klassen für den Aufruf von NSSCoptions.getLocalString(LocalStrings.xxx), aber man kann das ja ganz einfach durch einen finalen String ersetzten, ist also unwichtig.

Nochmals vielen Dank.:toll:

MfG
hansmueller
 

CroniD

Aktives Mitglied
Kein Problem. :)

Würde mich sogar freuen, wenn du beispielsweise einige Sachen fixen könntest oder neue Sachen einbaust. Wie z.B. Tabs Drag'n'Drop oder "Ghost"-Tabs, "+"-Button (in der Hauptklasse müssten dazu Links hinterlegt sein und im unterpackage "java" müsste bissle Dummy Code sein). Außerdem habe ich für den "CloseButton" keine eigene UIKlassen, sondern die Anpassungen werden irgendwo bei der Intanzierung gemacht (so genau weiß ich das nicht mehr). Für das WinLAF sieht es ganz gut aus, für Nimbus glaube ich auch, aber Mac-, GTK-, Motif-, MetalLAF eher nicht so. Na ja, wenn du mal Zeit hast. :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P Größe und Ausrichtung von Komponenten festlegen AWT, Swing, JavaFX & SWT 13
R Swing Verändern der Ausrichtung JButton und neu anzeigen AWT, Swing, JavaFX & SWT 2
X JMenu Menu-Bar ausrichtung ändern im Programm AWT, Swing, JavaFX & SWT 0
C LayoutManager JFrame größe und ausrichtung + Position von Fensterelementen AWT, Swing, JavaFX & SWT 2
M Ausrichtung Vertikaler BOX funktioniert nicht AWT, Swing, JavaFX & SWT 3
J Swing JTable cell-ausrichtung für zahlen mit alternierenden zeilenfarben AWT, Swing, JavaFX & SWT 2
M Ausrichtung von Box'en AWT, Swing, JavaFX & SWT 3
C Swing GridBag-Probleme (Größe und Ausrichtung) AWT, Swing, JavaFX & SWT 3
M JFreeChart Ausrichtung der Balken AWT, Swing, JavaFX & SWT 2
R Swing JLabel Text ausrichtung AWT, Swing, JavaFX & SWT 2
N Swing Ausrichtung von Text in JTable AWT, Swing, JavaFX & SWT 9
W GUI übernimmt ausrichtung nicht AWT, Swing, JavaFX & SWT 5
D SWT SWT TableViewer ausrichtung des Inhaltes nach Datentyp AWT, Swing, JavaFX & SWT 2
G BoxLayout: Ausrichtung der Komponenten AWT, Swing, JavaFX & SWT 2
C Ausrichtung im JPanel AWT, Swing, JavaFX & SWT 19
G Ausrichtung in der GUI - Problem AWT, Swing, JavaFX & SWT 16
N ausrichtung Button - hilfe bitte AWT, Swing, JavaFX & SWT 2
A JScrollPane und mittige ausrichtung AWT, Swing, JavaFX & SWT 5
G GridbagLayout Ausrichtung AWT, Swing, JavaFX & SWT 3
M Ausrichtung eines Panels AWT, Swing, JavaFX & SWT 7
G tabbedpane ausrichtung der reiter AWT, Swing, JavaFX & SWT 4
T Ausrichtung eines Jbuttons AWT, Swing, JavaFX & SWT 6
R Ausrichtung am oberen Rand beim Gridbag-Layout AWT, Swing, JavaFX & SWT 2
B FlowLayout ausrichtung | "Wasserzeichen" im JFrame AWT, Swing, JavaFX & SWT 8
S Keine Ausrichtung im JTextPane? AWT, Swing, JavaFX & SWT 3
J Ermittlung der Ausrichtung einer Komponente im BorderLayout AWT, Swing, JavaFX & SWT 3
F Ausrichtung einer Spalte ändern? AWT, Swing, JavaFX & SWT 4
C Ausrichtung von Zelleninhalten bei JTable AWT, Swing, JavaFX & SWT 2
ralfb1105 JavaFX HTTP Download task im Hintergrund innerhalb GUI AWT, Swing, JavaFX & SWT 70
ralfb1105 JavaFX Label lässt sich innerhalb service Task nicht updaten? AWT, Swing, JavaFX & SWT 22
W Swing JTable Zeilenumbruch innerhalb einer Zelle AWT, Swing, JavaFX & SWT 3
J JavaFX Rectangle innerhalb eines Rectangle oder Panes positionieren? AWT, Swing, JavaFX & SWT 1
D TAB Taste innerhalb eines JSpinner AWT, Swing, JavaFX & SWT 2
M PDF einlesen und innerhalb Pane anzeigen AWT, Swing, JavaFX & SWT 5
M Swing JPanel innerhalb eines Frames verschieben AWT, Swing, JavaFX & SWT 3
R Swing Bewegung eines Graphics Objektes innerhalb eines JPanels funktioniert nicht richtig AWT, Swing, JavaFX & SWT 2
A Swing Textübergabe innerhalb der Anwendung in unterschiedlichen Fenster AWT, Swing, JavaFX & SWT 8
M Java FX Innerhalb einem FXML-Dialog weiteren FXML-Dialog einblenden AWT, Swing, JavaFX & SWT 3
C JTable Drag and Drop von Zeilen innerhalb einer Table AWT, Swing, JavaFX & SWT 2
U Bild innerhalb hatml code anzeigen AWT, Swing, JavaFX & SWT 5
M Mehrere Fenster innerhalb einer Application AWT, Swing, JavaFX & SWT 3
L Swing Component alignment innerhalb einer JList AWT, Swing, JavaFX & SWT 3
R JTextField Eingabefeld innerhalb verschieben AWT, Swing, JavaFX & SWT 2
P setStroke komplett innerhalb eines Rectangles AWT, Swing, JavaFX & SWT 4
D JDialog alwaysOnTop, aber nur innerhalb der Applikation AWT, Swing, JavaFX & SWT 3
D Bestimmtes JPanel innerhalb eines JTabbedPane ansprechen AWT, Swing, JavaFX & SWT 2
D Drag-Action: Innerhalb meiner View? AWT, Swing, JavaFX & SWT 3
S Swing JButton mit ActionListener innerhalb einer JTable AWT, Swing, JavaFX & SWT 4
K JButtons innerhalb eines JPanels verschieben (DRAG&DROP) AWT, Swing, JavaFX & SWT 5
A SWT Scrollable Composite innerhalb eines Composites AWT, Swing, JavaFX & SWT 3
JuliaOne Komponenten innerhalb eine JScrollpane werden auch ausserhalb davon gezeichnet! AWT, Swing, JavaFX & SWT 7
M Swing Rahmen innerhalb des JButton entfernen AWT, Swing, JavaFX & SWT 2
D JTables, Test highlighten innerhalb einer Zelle AWT, Swing, JavaFX & SWT 5
J Swing Container innerhalb eines JPanels erfragen AWT, Swing, JavaFX & SWT 3
N rootPane überschreibt bg Innerhalb von secs AWT, Swing, JavaFX & SWT 5
G MousePosition innerhalb eines MouseWheelEvents AWT, Swing, JavaFX & SWT 2
B SWT - Drag & Drop innerhalb einer Table AWT, Swing, JavaFX & SWT 3
hdi Layout innerhalb eines JScrollPane AWT, Swing, JavaFX & SWT 4
A Drag & Drop von Zeilen innerhalb einer Tabelle AWT, Swing, JavaFX & SWT 2
R Gelöst: panelGrösse innerhalb eines JFrames AWT, Swing, JavaFX & SWT 7
I Text innerhalb von Rectangle rendern AWT, Swing, JavaFX & SWT 3
T Auf Fenster innerhalb der Anwendung zugreifen-auch elegant? AWT, Swing, JavaFX & SWT 2
R Innerhalb der GUI Klasse meine neue Klasse aufrufen AWT, Swing, JavaFX & SWT 1
A Hintergrundfrabe eines JButtons innerhalb eines JToolBar AWT, Swing, JavaFX & SWT 4
A Aktualisierung eines Bildes innerhalb einer Komponente AWT, Swing, JavaFX & SWT 7
T erkennen ob innerhalb oder außerhalb von canvas gezeichnet AWT, Swing, JavaFX & SWT 2
L TreePath eines Objektes innerhalb eines JTree ermitteln? AWT, Swing, JavaFX & SWT 1
B einzelne Zellen scrollbar machen innerhalb einer Tabelle AWT, Swing, JavaFX & SWT 3
javasdann JTable sichtbare Zeilen innerhalb von JScrollPane ermitteln AWT, Swing, JavaFX & SWT 5
G JTable Zeilenumbruch innerhalb einer Zelle bzw. columnHeader AWT, Swing, JavaFX & SWT 1

Ähnliche Java Themen

Neue Themen


Oben