Ich habe mit
einen Outliner gebaut.
Für "plain text" benutze ich als
ein
.
Hier funktioniert der automatische Zeilenumbruch problemlos.
Die nötigen Dimensionen des
werden in
wie folgt gesetzt:
Beim Aufruf von
berechnen Komponenten wie
die zur Darstellung ihres Inhaltes benötigte Fläche, nach Möglichkeit innerhalb der mit
gegebenen Dimensionen.
(Diese Form benutzt z. B. auch BorderLayout beim Berechnen des Layouts.)
Mein Problem: Knoten mit html-text:
unterstützt kein html, darum benutze ich ein
.
Normalerweise berechnet auch
mit
die von ihm benötigten Dimensionen, mit automatischen Zeilenumbrüchen im html-text.
(JLabel macht scheinbar nur mit html-Text automatische Zeilenumbrüche, in plain text nie.)
Doch hier funktioniert das nicht: egal was ich mache, es gibt keine automatischen Zeilenumbrüche.
(Es sei denn sie werden vom html-code verlangt, wie z. B. mit "<br>")
Aus irgend einem Grund kann das
nicht sofort den korrekt benötigten Size errechnen.
Muss irgend etwas anderes vor dem Aufruf von
gemacht werden?
(Layoutmanager scheinen den Vorgang öffter zu wiederholen, bis die korrekte Größe angegeben wird - was bei einer TreeCellRenderer-Component kaum möglich ist.)
- Bin für jede Hilfe und Gedankenanregung sehr dankbar! -
Habe in folgendem Beitrag schon mal versucht die Fragestellung um das
zu isolieren:
http://www.java-forum.org/awt-swing-swt/136759-komponentenhoehe-html-inhalt-anpassen.html
Was passiert mit dem
, bevor es sonst die korrekten benötigten Dimensionen berechnet?
Doch... vielleicht ist mein Ansatz beim Erzeugen eines
falsch?
Hier meine Testklasse, welche JTextArea und JLabel gegenüberstellt:
(JEditorPane oder JTextPane anstelle des JLabel führen zum gleichen Ergebnis)
(ohne import-Anweisungen wegen der Übersichtlichkeit; kann doch sicher jeder selbst nachfügen?)
Code:
JTree
Für "plain text" benutze ich als
Code:
TreeCellRenderer
Code:
JTextArea
Hier funktioniert der automatische Zeilenumbruch problemlos.
Die nötigen Dimensionen des
Code:
JTextArea
Code:
getTreeCellRenderer(...)
Java:
rendererComponent.setSize(availableWidth, Short.MAX_VALUE);
int neededHeight = rendererComponent.getPreferredSize().height();
rendererComponent.setSize(availableWidth, neededHeight);
Code:
getPreferredSize()
Code:
JTextArea
Code:
setSize(...)
(Diese Form benutzt z. B. auch BorderLayout beim Berechnen des Layouts.)
Mein Problem: Knoten mit html-text:
Code:
JTextArea
Code:
JLabel
Normalerweise berechnet auch
Code:
JLabel
Code:
getPreferredSize()
(JLabel macht scheinbar nur mit html-Text automatische Zeilenumbrüche, in plain text nie.)
Doch hier funktioniert das nicht: egal was ich mache, es gibt keine automatischen Zeilenumbrüche.
(Es sei denn sie werden vom html-code verlangt, wie z. B. mit "<br>")
Aus irgend einem Grund kann das
Code:
JLabel
Muss irgend etwas anderes vor dem Aufruf von
Code:
getPreferredSize()
(Layoutmanager scheinen den Vorgang öffter zu wiederholen, bis die korrekte Größe angegeben wird - was bei einer TreeCellRenderer-Component kaum möglich ist.)
- Bin für jede Hilfe und Gedankenanregung sehr dankbar! -
Habe in folgendem Beitrag schon mal versucht die Fragestellung um das
Code:
JLabel
http://www.java-forum.org/awt-swing-swt/136759-komponentenhoehe-html-inhalt-anpassen.html
Was passiert mit dem
Code:
JLabel
Doch... vielleicht ist mein Ansatz beim Erzeugen eines
Code:
TreeCellRenderers
Hier meine Testklasse, welche JTextArea und JLabel gegenüberstellt:
(JEditorPane oder JTextPane anstelle des JLabel führen zum gleichen Ergebnis)
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);
label.setBorder(BorderFactory.createLineBorder(Color.green));
textArea.setBorder(BorderFactory.createLineBorder(Color.green));
createFrame();
}
void setTheTextOfLabel(){
cellsText = JOptionPane.showInputDialog("Enter a Text", cellsText);
if(cellsText==null || cellsText.equals("")) return;
label.setText("<html>"+cellsText+"</html>");
textArea.setText(cellsText);
resizeTheLabelAndTheTextArea();
}
void resizeTheLabelAndTheTextArea(){
// Nehme die aktuelle Breite dieses JPanels (entspricht der des frames).
int availableWidth = getSize().width - 50; // 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.getPreferredSize().height;
int calculatedTextAreaHeight = textArea.getPreferredSize().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) {
resizeTheLabelAndTheTextArea();
}
};
/** 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 mit html-text:"));
DefaultMutableTreeNode childchild1 = new CellRenderingTreeNode(label);
child1.insert(childchild1, 0);
DefaultMutableTreeNode child2 = new CellRenderingTreeNode(new JLabel("JTextArea mit plain-text:"));
DefaultMutableTreeNode childchild2 = new CellRenderingTreeNode(textArea);
child2.insert(childchild2, 0);
root.insert(child1, 0);
root.insert(child2, 1);
return root;
}
/** Bringt das JTree lediglich in ein Frame hinein, und zeigt es.
* Änderungen der Größe des Frames lassen das JLabel und das JTextArea auch neu berechnen. */
void createFrame(){
final JButton changeTextButton = new JButton("Enter a new test-text");
changeTextButton.addActionListener(changeTextListener);
final JButton doLayoutButton = new JButton("Recalculate the sizes of the test-renderers");
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("LabelSizeTree");
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) {
resizeTheLabelAndTheTextArea();
}
});
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String a[]){
new LabelSizeTree();
}
}