Swing KomponentenHöhe an html-Inhalt anpassen

nstrauch

Mitglied
Warum kann ich ein JLabel nicht gleich nach dem setzen eines neuen html-Textes (mit setText()) die dafür benötigte Höhe (zu einer festen Breite) berechnen lassen?

Allgemein funktioniert es mit dem unten angefügten Code.
Dort platziere ich das JLabel und 2 Buttons:
- mit dem ersten Button kann ich den Text des JLabel neu setzen
- mit dem zweiten die Höhe des JLabel neu berechnen und setzen lassen.

Das versuche ich auch schon gleich nach dem Setzen des neuen Textes. Doch dort funktioniert es nicht. :(

Benutze ich statt des JLabel mit html ein JTextArea ohne html, funktioniert es problemlos.

updateUI, repaint, doLayout, validate, revalidate nützen alle nichts.

Fragen:
- Was macht Java von einem Button-Aufruf zum anderen mit dem Label, damit das Berechnen der Höhe plötzlich doch funktioniert?
- Kann ich selbst irgendetwas nach dem Setzen des Textes und vor dem Berechnen der neuen Höhe mit dem JLabel machen, damit letzteres wie erwartet funktioniert?


Herzlichen Dank an alle, die sich dieses meines Prolems annehmen.
(Habe diesmal leider nichts ergooglen können... ???:L )

Viele Grüße,
Nicolai


Java:
/** Test-Klasse: die eigentliche Anwendung ist komplexer. 
  *  (Das Benutzen eines fertigen Layoutmanagers wäre dort nicht möglich.) */
public class LabelSizePanel extends JPanel {
	
	JLabel label = new JLabel("<html>Der Zeilenumbruch funktioniert nur, wenn der Text mit"
						+"entsprechenden Tags als HTML gekennzeichnet ist.</html>");
	
	LabelSizePanel(){

		// die bounds des labels werden per hand gesetzt, ohne layoutmanager
		setLayout(null);

		// Borders um die genauen Größen der Componenten erkennen zu können
		setBorder(BorderFactory.createLineBorder(Color.red));
		label.setBorder(BorderFactory.createLineBorder(Color.green));

		add(label);

		// die bounds des labels werden gesetzt, entsprechend seinem Text 
		resizeTheLabel();

		// Die vom Label errechnete Größe sollte auch das JPanel (this) bekommen
		setPreferredSize(label.getPreferredSize());

		// pack dies alles in ein frame, und zeige es an
		createFrame();
	}

	/** Lässt sich vom User einen Text geben, 
	  *  Übergibt diesen dem label,
	  *  Passt die dimensionen des labels den neuen Text an. (was eben nicht funktioniert) */
	void setTheTextOfLabel(){

		// Fordert vom User einen Text, und gibt diesen dem label.
		label.setText(  
				    JOptionPane.showInputDialog(
										"Enter Label-Text", label.getText())  
		);
				
		// - Nun soll die Höhe des labels seinem neuen Textinhalt angepasst werden. -
		// Benutzt man statt des JLabel mit html ein JTextArea ohne html,
		// funktioniert dies problemlos.
		// Bei JLabel wird an dieser Stelle die Höhe auf eine Zeile gesetzt,
		// unabhängig vom Inhalt.
		// Erst wenn resizeTheLabel() später erneut aufgerufen wird
		// zeigt es die erwartete Wirkung.
		// !! Das löschen der folgenden Zeile hat scheinbar keinerlei Auswirkung !!
		resizeTheLabel();

	}

	// hier folgt der Kern zur Neuberechnung der Höhe des JLabel
	/** Dem label wird die aktuelle Breite dieses JPanel übergeben,
	  *  zu welcher es die Höhe berechnet, die es zur Darstellung seines Inhaltes bedarf.
	  *  Der size des labels wird auf die gegebene Breite und errechnete Höhe gesetzt. */
	void resizeTheLabel(){
		
		// Nehme die aktuelle Breite dieses JPanels (entspricht der des frames).
		int availableWidth = getSize().width;
		
		// Setze das label auf diese Breite, und auf beliebige Höhe.
		label.setSize(availableWidth, Short.MAX_VALUE);
		
		// In getPreferredSize() berechnet das label wieviel es von der
		// gegebenen Breite und Höhe für die Darstellung seines Inhaltes bedarf.
		// Uns interessiert nur die Höhe.
		int calculatedHeight = label.getPreferredSize().height;
		
		// Das label erhält die Breite des JPanel (this), und die Höhe die es bedarf.
		label.setBounds(0, 0, availableWidth, calculatedHeight);
		
		// Man gehe davon aus, das dieses JPanel die nötige Höhe besitzt.
		// Wenn nicht, kann der User sie leicht selbst korrigieren.
	}
	
	/** Hiermit lässt sich der Label-text ändern */
	ActionListener changeTextListener =
		new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				
				setTheTextOfLabel();

			}
		};
	
	/** Hiermit kann man die Höhe des Labels neu berechnen und setzen lassen */
	ActionListener doLayoutListener =
		new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				
				resizeTheLabel();
				
			}
		};
		
		
	void createFrame(){

		final JButton changeTextButton = new JButton("Enter new Text");
		changeTextButton.addActionListener(changeTextListener);
		final JButton doLayoutButton = new JButton("Layout the label again");
		doLayoutButton.addActionListener(doLayoutListener);
		
		final JPanel panel = new JPanel();		
		panel.setLayout(new BorderLayout());
		panel.add(changeTextButton, BorderLayout.NORTH);
		panel.add(this, BorderLayout.CENTER);
		panel.add(doLayoutButton, BorderLayout.SOUTH);
		
		JFrame frame = new JFrame("LabelSizePanel");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// Ändert man die Größe des frames,
		// wird die Höhe des labels hiermit auch neu berechnet
		frame.addComponentListener(new ComponentAdapter() {
			public void componentResized(ComponentEvent e) {
				resizeTheLabel();
			}
		});

		frame.add(panel);
		frame.pack();		
		frame.setVisible(true);
		
	}
	
	public static void main(String a[]){
		new LabelSizePanel();
	}
	
}
 

GUI-Programmer

Top Contributor
Ganz einfach, indem du einen LayoutManager verwendest (also nicht
Code:
setLayout(null);
)! Somit bekommt das JLabel automatisch soviel Platz wie es benötigt - einer der Hauptvorteile eines LayoutManagers: Man muss sich nicht selbst um die Größem- und Positionsberechnungen kümmern.
 

nstrauch

Mitglied
Vielen Dank für die Antwort.

Leider kann ich kein LayoutManager verwenden, befürchte ich:

Das JLabel soll als CellRenderer in einer JTree verwendet werden.
Hier kann ich selbst die Erwünschte Größe der Komponente bestimmen.
Doch wie bekomme ich die bei JLabel heraus?

Bei JTextArea funktioniert es.

Im folgenden das nun etwas komplexere Beispiel mit einer JTree, mit einem JLabel und einem JTextArea als CellRenderer, zum Vergleich:


Java:
public class LabelSizeTree extends JTree {
	
	/** Knoten, welcher sich eine Renderer-Component merkt. */
	static class CellRenderingTreeNode extends DefaultMutableTreeNode {
		Component renderingComponent;
		CellRenderingTreeNode(Component renderingComponent){
			this.renderingComponent = renderingComponent;
		}
		public Component getTreeCellRendererComponent() {
			return renderingComponent;
		}
	}
	
	
	static String cellsText = "Langer, langer langer InitialText. Braucht keine html-tags, sie werden später hinzugefügt.";
	static JLabel label = new JLabel("<html>"+cellsText+"</html>");
	static JTextArea textArea = new JTextArea(cellsText);
	
	
	LabelSizeTree(){
		super(mountNodes(label, textArea));
		setCellRenderer(new TreeCellRenderer(){
			public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
				JLabel dummyComponent = new  JLabel("Vergleich zwischen JLabel und JTextArea");
				if(value instanceof CellRenderingTreeNode)
					return ((CellRenderingTreeNode)value).getTreeCellRendererComponent();
				return dummyComponent;
			}
		});
		textArea.setLineWrap(true);
		textArea.setWrapStyleWord(true);
		createFrame();
	}
	
	/** Baut einen Root-Knoten mit zwei Kindern, eins für ldas JLabel, eines für textArea auf. */
	static TreeNode mountNodes(JLabel label, JTextArea textArea){
		DefaultMutableTreeNode root = new DefaultMutableTreeNode();
		DefaultMutableTreeNode child1 = new CellRenderingTreeNode(new JLabel("JLabel:"));
		DefaultMutableTreeNode childchild1 = new CellRenderingTreeNode(label);
		child1.insert(childchild1, 0);
		DefaultMutableTreeNode child2 = new CellRenderingTreeNode(new JLabel("JTextArea:"));
		DefaultMutableTreeNode childchild2 = new CellRenderingTreeNode(textArea);
		child2.insert(childchild2, 0);
		root.insert(child1, 0);
		root.insert(child2, 1);
		return root;
	}
	
	
	void setTheTextOfLabel(){
		
		cellsText =   JOptionPane.showInputDialog("Enter a Text", cellsText);
		if(cellsText==null || cellsText.equals("")) return;
		
		label.setText("<html>"+cellsText+"</html>");
		textArea.setText(cellsText);
		
		resizeTheLabel();

	}
	
	void resizeTheLabel(){
		
		// Nehme die aktuelle Breite dieses JPanels (entspricht der des frames).
		int availableWidth = getSize().width - 30; // ziehe 30 ab wegen Einrückung der Knoten
		
		// Setze die zur Verfügung stehende Breite, sowie beliebige Höhe
		label.setSize(availableWidth, Short.MAX_VALUE);
		textArea.setSize(availableWidth, Short.MAX_VALUE);
			
		// In getPreferredSize() wird berechnet wieviel von der gegebenen 
		// Breite und Höhe für die Darstellung des Inhaltes benötigt wird.
		// Uns interessiert nur die Höhe.
		int calculatedLabelHeight = label.getSize().height;
		int calculatedTextAreaHeight = textArea.getSize().height;
		
		// Das label erhält die Breite des JPanel (this), und die Höhe die es bedarf.
		label.setBounds(0, 0, availableWidth, calculatedLabelHeight);
		textArea.setBounds(0, 0, availableWidth, calculatedTextAreaHeight);
		
		updateUI();
		repaint();
	}
	
	
	/** Hiermit lässt sich der Label-text ändern */
	ActionListener changeTextListener =
		new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				
				setTheTextOfLabel();
				
			}
		};
	
	/** Hiermit kann man die Höhe des Labels neu berechnen und setzen lassen.
	 *  Hat in diesem Beispiel keine Auswirkung mehr,
	 *  das label bleibt wie es ist... */
	ActionListener doLayoutListener =
		new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				
				resizeTheLabel();
				
			}
		};
	
	void createFrame(){

		final JButton changeTextButton = new JButton("Enter new Text");
		changeTextButton.addActionListener(changeTextListener);
		final JButton doLayoutButton = new JButton("Layout the label again");
		doLayoutButton.addActionListener(doLayoutListener);
		
		final JPanel panel = new JPanel();		
		panel.setLayout(new BorderLayout());
		panel.add(changeTextButton, BorderLayout.NORTH);
		panel.add(this, BorderLayout.CENTER);
		panel.add(doLayoutButton, BorderLayout.SOUTH);
		
		JFrame frame = new JFrame("LabelSizePanel");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// Ändert man die Größe des frames,
		// wird die Höhe des labels hiermit auch neu berechnet
		frame.addComponentListener(new ComponentAdapter() {
			public void componentResized(ComponentEvent e) {
				resizeTheLabel();
			}
		});

		frame.add(panel);
		frame.pack();		
		frame.setVisible(true);
		
	}
	
	public static void main(String a[]){
		new LabelSizeTree();
	}
	
}
 

nstrauch

Mitglied
Habe eine Lösung selbst gefunden:

Rufe ich in
Code:
setTheTextOfLabel()
Code:
paintImmediately(label.getBounds())
auf bevor
Code:
resizeTheLabel();
aufgerufen wird, wird die Größe des JLabel korrekt gesetzt.

Leider hab ich noch nicht rausgefunden, wie man dies auf einen TreeCellRenderer anwenden kann...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
izoards HTML Editor AWT, Swing, JavaFX & SWT 3
H setToolTipText ignoriert HTML-Formatierung des anzuzeigenden Strings AWT, Swing, JavaFX & SWT 4
Yonnig Lokale HTML-Datei in Java GUI rendern AWT, Swing, JavaFX & SWT 4
kodela HTML-tags für JLabel AWT, Swing, JavaFX & SWT 9
C HTML Editor Eingabemaske kafenio Ersatz AWT, Swing, JavaFX & SWT 7
A JavaFX Daten in eine HTML-Table mit JS schreiben AWT, Swing, JavaFX & SWT 3
T JTextPane ignoriert HTML Zeilenumbruch <br> tag wegen eigenem HTMLEditorKit AWT, Swing, JavaFX & SWT 5
E Java FX FXML Problem mit html Scriptausführung AWT, Swing, JavaFX & SWT 2
K Html Editor AWT, Swing, JavaFX & SWT 3
B Swing HTML in JLabels AWT, Swing, JavaFX & SWT 6
S jLabel HTML Formatierung AWT, Swing, JavaFX & SWT 2
B JavaFX Java FX Html Template AWT, Swing, JavaFX & SWT 0
F JavaFX JavaFX HTMLEditor-Eingabe in Textarea als HTML anzeigen AWT, Swing, JavaFX & SWT 2
D Swing Breite einer HTML Tabelle in einer JTextPane AWT, Swing, JavaFX & SWT 6
R Swing JTable : Header der Spalten ergänzen mit caption (wie bei html-table) AWT, Swing, JavaFX & SWT 2
I LookAndFeel HTML Auflösung - Online Editor programmieren AWT, Swing, JavaFX & SWT 2
T HTML mit Java AWT, Swing, JavaFX & SWT 1
U Label zeigt nicht überall HTML Zeichen AWT, Swing, JavaFX & SWT 3
N JLabel HTML mit custom Font AWT, Swing, JavaFX & SWT 0
H RCP(SWT) Browser-Widget zeigt keine locale HTML-Dateien an AWT, Swing, JavaFX & SWT 1
F Submit eines HTML-Formulars in Vaadin AWT, Swing, JavaFX & SWT 3
T Swing HTML Text aus JLabel ohne "HTML-Tags" in String einlesen AWT, Swing, JavaFX & SWT 5
J JApplet, HTML und access denied exitVM.0 AWT, Swing, JavaFX & SWT 3
L Swing JToogleButton Vordergrundfarbe bei HTML String AWT, Swing, JavaFX & SWT 4
H Swing JApplet - HTML - ClassNotFoundException AWT, Swing, JavaFX & SWT 7
G Swing HTML Version AWT, Swing, JavaFX & SWT 11
S HTML in Java einbinden AWT, Swing, JavaFX & SWT 4
B JEditorPane lädt keine Schriftfarbe in HTML AWT, Swing, JavaFX & SWT 2
J JEditorPane mit HTML füllen AWT, Swing, JavaFX & SWT 2
N Swing JTree TreeCellRenderer mit html und automatischen Zeilenumbruch AWT, Swing, JavaFX & SWT 8
F Applet JApplet per html einbinden - Main class kann nicht gefunden werden AWT, Swing, JavaFX & SWT 15
C html browser in Application nutzen AWT, Swing, JavaFX & SWT 10
S SWT Anzeigen einer lokalen HTML-Seite im Browser Widget über RAP nicht möglich AWT, Swing, JavaFX & SWT 3
S HTML Syntaxhighlighting AWT, Swing, JavaFX & SWT 7
S SWT HTML-WYSIWUG-Editor AWT, Swing, JavaFX & SWT 3
R Swing Renderproblem bei HTML in einer JTextPane AWT, Swing, JavaFX & SWT 12
N Swing JTextPane zur Anzeige von HTML AWT, Swing, JavaFX & SWT 2
N Applet JButton soll html Datei aus einem Ordner öffnen AWT, Swing, JavaFX & SWT 2
H JScrollPane - JEditorPane und HTML-Tabelle AWT, Swing, JavaFX & SWT 2
H Swing JEditorPane und HTML AWT, Swing, JavaFX & SWT 3
D System.out.println() gibt html-Tags mit aus AWT, Swing, JavaFX & SWT 2
P Swing HTML-Renderer AWT, Swing, JavaFX & SWT 15
G Swing JCheckBox, setEnabled(false) und HTML Text Problem AWT, Swing, JavaFX & SWT 5
J 2D-Grafik Html in drawString() AWT, Swing, JavaFX & SWT 2
L Applet In HTML einbinden klappt einfach nicht AWT, Swing, JavaFX & SWT 5
X Frei nutzbarer HTML Editor AWT, Swing, JavaFX & SWT 13
B WYSIWYG-HTML-Editor / Validator für JAVA AWT, Swing, JavaFX & SWT 2
N JCombobox wie in HTML AWT, Swing, JavaFX & SWT 6
H Swing HTML in einem JEditorPane zeilenweise hinzufügen ohne Inhalt jedes Mal neu zu laden AWT, Swing, JavaFX & SWT 4
G Swing JEdtitorPane und HTML Image Seite AWT, Swing, JavaFX & SWT 2
C Swing JTextPane zeigt HTML-Text aus Variable nicht an :( AWT, Swing, JavaFX & SWT 3
P Swing html mit bilder drin AWT, Swing, JavaFX & SWT 12
destroflyer Wort im JLabel verlinken (per HTML) AWT, Swing, JavaFX & SWT 3
R Swing JTextComponent und HTML AWT, Swing, JavaFX & SWT 7
D Nodes eines statischen JTrees sollen auf Anker (Textmarken) in einer HTML-Datei zeigen AWT, Swing, JavaFX & SWT 8
S Swing HTML-Text in JEditorPane einfärben AWT, Swing, JavaFX & SWT 5
D Darstellung in Swing wie HTML? AWT, Swing, JavaFX & SWT 2
H Mit JLabel HTML - formatierten Text anzeigen AWT, Swing, JavaFX & SWT 14
M Swing Kein update bei simulierten HTML-Link AWT, Swing, JavaFX & SWT 4
B Grafiken in JLabel mittels html AWT, Swing, JavaFX & SWT 5
E Swing JTextPane Inhalt(Text und Bilder) als HTML text bekommen AWT, Swing, JavaFX & SWT 3
B JEditorPane - Text und Graphik in HTML speichern AWT, Swing, JavaFX & SWT 4
K Alternative zu Applet mit HTML-Einbindung AWT, Swing, JavaFX & SWT 11
D Swing JEditorPane mit HTML aber ohne Bilder AWT, Swing, JavaFX & SWT 3
S Swing Text -> HTML: Caret-Koordinaten verschoben AWT, Swing, JavaFX & SWT 6
S JEditorPane soll HTML und dann Text anzeigen..? AWT, Swing, JavaFX & SWT 5
T HTML und JEditorPane AWT, Swing, JavaFX & SWT 6
J JList & HTML AWT, Swing, JavaFX & SWT 2
T HTML Seite neu laden mittels Applet AWT, Swing, JavaFX & SWT 2
N Performanceprobleme mit JLabel und HTML content AWT, Swing, JavaFX & SWT 5
A Oberfläche wir mit html-Frames aufbauen AWT, Swing, JavaFX & SWT 11
C JTextPane HTML und eigene Tags AWT, Swing, JavaFX & SWT 10
W HTML-Text mit relativer URL in JEditorPane einlesen AWT, Swing, JavaFX & SWT 10
C Suche fertigen HTML editor AWT, Swing, JavaFX & SWT 2
B HTML in Swing Components (JLabel) AWT, Swing, JavaFX & SWT 7
M JEditorPane lädt HTML ohne Bilder AWT, Swing, JavaFX & SWT 2
M JEditorPane lädt HTML ohne Bilder AWT, Swing, JavaFX & SWT 2
G Hilfe beim Erstellen eines eigenen Html-Editors! AWT, Swing, JavaFX & SWT 4
S drawString für HTML-Text? AWT, Swing, JavaFX & SWT 7
G Frage zu Labels mit html AWT, Swing, JavaFX & SWT 3
P HTML darstellen mit Java AWT, Swing, JavaFX & SWT 4
GilbertGrape Fehler bei HTML in JTextPane AWT, Swing, JavaFX & SWT 2
ARadauer swing html wysiwyg componente AWT, Swing, JavaFX & SWT 6
V "Anker" wie in HTML für JScrollPane? AWT, Swing, JavaFX & SWT 2
M html im Titel von JFrame AWT, Swing, JavaFX & SWT 9
M html aus einem Stream Laden und Anzeigen AWT, Swing, JavaFX & SWT 4
T Öffnen von SWT-Dialogboxen durch HTML-Link in HTML-Code AWT, Swing, JavaFX & SWT 4
B JTextPane und Image importieren in HTML String. AWT, Swing, JavaFX & SWT 2
J Html in JTextPane anzeigen? AWT, Swing, JavaFX & SWT 2
V Swing to HTML? AWT, Swing, JavaFX & SWT 4
A HTML-Datei öffnen AWT, Swing, JavaFX & SWT 3
A Noch mal Zusammenarbeit Java und HTML AWT, Swing, JavaFX & SWT 4
A Java und HTML AWT, Swing, JavaFX & SWT 8
R HTML Hintergrund für Swing - Componenten AWT, Swing, JavaFX & SWT 2
G Problem mit Anzeige von HTML AWT, Swing, JavaFX & SWT 5
G Probleme mit Druck von pdf und html AWT, Swing, JavaFX & SWT 2
DeeDee0815 JEditorPane + HTML + <img src=file> + JAR = FALSE AWT, Swing, JavaFX & SWT 3
F HTML anzeigen AWT, Swing, JavaFX & SWT 3
P HTMLDocument in einem JTextPane. Anhängen von HTML-Code AWT, Swing, JavaFX & SWT 2
G Komplexe HTML-Seiten mit Swing Browsen AWT, Swing, JavaFX & SWT 5

Ähnliche Java Themen

Neue Themen


Oben