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
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();
}
}