JEditorPane textausrichtung nach settext funktioniert nicht mehr

washpuda123

Mitglied
Hi, ich habe ein kleines Problem und hoffe jemand kann mir helfen. Ich habe ein JEditorPane vom Typ "text/html" zur Texteingabe. Über Buttons möchte ich die horizontale Textausrichtung für den selektierten Textabschnitt anpassen. Dies funktioniert einwandfrei, solange kein text mit setText(txt) gesetzt wurde (z.B. gespeicherten Text weiterbearbeiten möchte). Optisch funktioniert dies zwar weiterhin, jedoch gibt mir Methode getText() nur die Paragraphen mit den alten Ausrichtungen wieder (die Ausrichtung im p-Tag wird dann einfach nicht mehr übernommen, andere Attribute z.B. Textfarbe sind kein Problem). Mit der Schaltfläche "print to console" kann ich mir den HTML-Text auf der Console anzeigen lassen.

1671983732015.png
Ausgabe als HTML Text der Methode getText vom JEditorPane:
<html>
<head>

</head>
<body>
<p align="left" style="margin-top: 0">
A
</p>
<p align="center" style="margin-top: 0">
B
</p>
<p align="right" style="margin-top: 0">
C
</p>
</body>
</html>

Mit der Schaltfläche "setText" wird ePane.setText(ePane.getText) aufgerufen, danach wird die Ausrichtung im HTML-Text nicht mehr korrekt gesetzt.

Beispiel Quellcode.

Java:
import java.awt.BorderLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Element;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;

public class EditorPaneAlignTest implements CaretListener {

    JToggleButton tBtnAlignLeft = null, tBtnAlignCenter = null, tBtnAlignRight = null, tBtnAlignBlock = null;
    JEditorPane ePane;

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

    public EditorPaneAlignTest() {

        JPanel pane = new JPanel(new BorderLayout(5, 5));
        ePane = new JEditorPane("text/html", null);
        ePane.addCaretListener(this);

        JScrollPane sPane = new JScrollPane(ePane);
        pane.add(sPane, BorderLayout.CENTER);
        JToolBar toolBar = new JToolBar();
        pane.add(toolBar, BorderLayout.NORTH);

        ButtonGroup btnGroupAlign = new ButtonGroup();

        tBtnAlignLeft = new JToggleButton();
        tBtnAlignLeft.setToolTipText("Text linksbündig ausrichten");
        tBtnAlignLeft.setAction(new StyledEditorKit.AlignmentAction("left", StyleConstants.ALIGN_LEFT));
        tBtnAlignLeft.setFocusable(false);
        toolBar.add(tBtnAlignLeft);
        btnGroupAlign.add(tBtnAlignLeft);

        tBtnAlignCenter = new JToggleButton();
        tBtnAlignCenter.setToolTipText("Text linksbündig ausrichten");
        tBtnAlignCenter.setAction(new StyledEditorKit.AlignmentAction("center", StyleConstants.ALIGN_CENTER));
        tBtnAlignCenter.setFocusable(false);
        toolBar.add(tBtnAlignCenter);
        btnGroupAlign.add(tBtnAlignCenter);

        tBtnAlignRight = new JToggleButton();
        tBtnAlignRight.setToolTipText("Text linksbündig ausrichten");
        tBtnAlignRight.setAction(new StyledEditorKit.AlignmentAction("right", StyleConstants.ALIGN_RIGHT));
        tBtnAlignRight.setFocusable(false);
        toolBar.add(tBtnAlignRight);
        btnGroupAlign.add(tBtnAlignRight);

        tBtnAlignBlock = new JToggleButton();
        tBtnAlignBlock.setToolTipText("Textblock");
        tBtnAlignBlock.setAction(new StyledEditorKit.AlignmentAction("block", StyleConstants.ALIGN_JUSTIFIED));
        tBtnAlignBlock.setFocusable(false);
        toolBar.add(tBtnAlignBlock);
        btnGroupAlign.add(tBtnAlignBlock);

        JButton btnPrintText = new JButton("print text to console");
        btnPrintText.addActionListener(a -> System.out.println(ePane.getText()));
        toolBar.add(btnPrintText);

        JButton btnSetText = new JButton("setText");
        btnSetText.addActionListener(a -> ePane.setText(ePane.getText()));
        toolBar.add(btnSetText);

        JFrame frame = new JFrame("Align-Test");
        frame.setBounds(100, 100, 600, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(pane);
        frame.setVisible(true);
    }

    @Override
    public void caretUpdate(CaretEvent e) {

        DefaultStyledDocument styleDoc = (DefaultStyledDocument) ePane.getDocument();
        Element element = styleDoc.getCharacterElement(ePane.getCaretPosition() - 1);
        AttributeSet attribSet = element.getAttributes();

        switch (StyleConstants.getAlignment(attribSet)) {
        case StyleConstants.ALIGN_LEFT:
            tBtnAlignLeft.setSelected(true);
            break;
        case StyleConstants.ALIGN_CENTER:
            tBtnAlignCenter.setSelected(true);
            break;
        case StyleConstants.ALIGN_RIGHT:
            tBtnAlignRight.setSelected(true);
            break;
        case StyleConstants.ALIGN_JUSTIFIED:
            tBtnAlignBlock.setSelected(true);
            break;
        }
    }
}
 

Anhänge

  • 1671983723560.png
    1671983723560.png
    11 KB · Aufrufe: 0

KonradN

Super-Moderator
Mitarbeiter
Mit der Schaltfläche "setText" wird ePane.setText(ePane.getText) aufgerufen, danach wird die Ausrichtung im HTML-Text nicht mehr korrekt gesetzt.
Bei mir funktioniert es. Ich kann auf meinem System den Knopf drücken und der Text behält die Ausrichtung bei.

Ich nutze einen M1 Mac und habe es sowohl mit GralVM 17 als auch Temurin 17 getestet.
 

washpuda123

Mitglied
Hi,
dies ist auch richtig, aber wenn du danach zum Beispiel das B selektierst und rechtsbündig ausrichtest, dann erfolgt dies nur optisch. Im HTML-Text über getText() bleibt die Ausrichtung für B weiterhin auf Center. Dies ist ein Problem beim Speichern und späterem Wiederherstellung des Textes.
 

KonradN

Super-Moderator
Mitarbeiter
Ahh ja, das hatte ich dann nicht richtig nachvollzogen. Das Verhalten kann ich nun bestätigen.

So auf Anhieb habe ich da aber auch keine Erklärung geschweige denn eine Lösung. Ich muss es mir später noch einmal mehr im Detail ansehen.
 

Neumi5694

Top Contributor
Habe damit zugegebenermaßen nicht viel Erfahrung, aber ich denke denke, das kommt daher, dass der Editor nicht html als Grundlage verwendet, bzw. nicht den Html-Text, den du übergeben hast. Den rendert er zwar, packt außen rum aber nochmal eine eigene Formatierung, Stichwort OuterHtml.
Weis einfach mal A,B,C zu ohne Html. Auch die kannst du nach Belieben rumschieben und mit der genannten Methode wirst du kein html rauskriegen.

Ich denke, du musst dir das HtmlDocument des Editors holen und dort die einzelnen Elemente untersuchen.
 

KonradN

Super-Moderator
Mitarbeiter
Also die Methoden getText / setText geben html bzw. nehmen html. Dabei ist es egal, ob man da <html> und <body> mitgibt oder nicht.

Es ist also möglich, den Code zur Erzeugung des JEditorPane z.B. so zu verändern:
Java:
        ePane = new JEditorPane("text/html",
                "    <p style=\"margin-top: 0\">\n" +
                "      aaa\n" +
                "    </p>\n" +
                "    <p align=\"center\" style=\"margin-top: 0\">\n" +
                "      bbb\n" +
                "    </p>\n" +
                "    <p align=\"right\" style=\"margin-top: 0\">\n" +
                "      ccc\n" +
                "    </p>\n");

Das führt dann intern bei getText() zu der Ausgabe:
HTML:
<html>
  <head>
    
  </head>
  <body>
    <p style="margin-top: 0">
      aaa
    </p>
    <p align="center" style="margin-top: 0">
      bbb
    </p>
    <p align="right" style="margin-top: 0">
      ccc
    </p>
  </body>
</html>

Das nimmt das Control also. Aber wenn man dann bei der Zeile bbb das Allignment ändert, dann bleibt es bei dem align="center" bei dem getText Aufruf.

Da bin ich auch gerade etwas ratlos. Denn die Anzeige passt er ja an. Nur eben die Grundlage der Daten wird irgendwie nicht angepasst.

Wenn man sich also das zugrunde liegende Dokument ausgeben lässt (was aber getText() ja auch nur macht), dann sieht man, dass das Dokument ebenso falsch ist:
Java:
            HTMLDocument doc = (HTMLDocument) ePane.getDocument();
            EditorKit kit = ePane.getEditorKit();
            StringWriter writer = new StringWriter();
            try {
                kit.write(writer, doc, 0, doc.getLength());
                System.out.println(writer.toString());
            } catch (Exception ex) {
                ex.printStackTrace();
            }

Ich bin also etwas ratlos, was das Problem hier angeht.
 

mihe7

Top Contributor
Wenn ich es richtig sehe (das ist eher eine Vermutung), besteht das Problem, weil die Stile "asymmetrisch" behandelt werden. Bei setText() wird die Methode StyleSheet#addAttributes aufgerufen:
Code:
     * Adds a set of attributes to the element.  If any of these attributes
     * are StyleConstants attributes, they will be converted to CSS prior
     * to forwarding to the superclass behavior.
D. h. das HTML-Attribut "align" wird geparst, und kommt dann zusätzlich als CSS-Stil zu den vorhandenen Attributen, zu denen auch das HTML-Attribut "align" zählt. Geändert wird dann das CSS-Attribut und bei der Ausgabe scheint wohl das align-Attribut verwendet zu werden, sofern vorhanden.

Das könnte man ggf. mal testen, indem man alle HTML-Attribute "align" nach setText() entfernt.
 

washpuda123

Mitglied
Hallo Danke erstmal,

wie kann ich den dass Align nach dem setzen entfernen? Vor dem Setzen ist es einfach, da ich einfach die Methode setText() vom Editor überschreiben kann und die Ausrichtung dort rauslöschen kann. Dann wird alles jedoch erwartungsgemäß linksbündig angezeigt. Nachträglich müsste ich ja direkt das HTML bearbeiten.

Java:
    @Override
            public void setText(String t) {
                if (t != null) {
                    String txtWithoutAlign = t.replace("align=\"center\"", "").replace("align=\"justify\"", "")
                            .replace("align=\"right\"", "").replace("align=\"left\"", "");
                    Utils.print(txtWithoutAlign);
                    super.setText(txtWithoutAlign);
                } else {
                    super.setText(null);
                }
            }
 

mihe7

Top Contributor
Nicht schön aber selten:

Java:
        btnSetText.addActionListener(a -> {
            ePane.setText(ePane.getText());
            Document doc = ePane.getDocument();
            replaceAlignByTextAlign(doc.getRootElements());
        });

Mit
Java:
    private void replaceAlignByTextAlign(Element[] siblings) {
        for (Element parent : siblings) {
            AttributeSet attributeSet = parent.getAttributes();
            if (attributeSet.isDefined(HTML.Attribute.ALIGN)) {
                setAttributes(parent, toTextAlign(parent.getAttributes()));
            }
            
            Element[] children = new Element[parent.getElementCount()];
            for (int i = 0; i < children.length; i++) {
                children[i] = parent.getElement(i);
            }
            
            replaceAlignByTextAlign(children);
        }
    }
    
    private void setAttributes(Element elem, AttributeSet newAttributes) {
        int start = elem.getStartOffset();
        HTMLDocument html = (HTMLDocument) elem.getDocument();
        html.setParagraphAttributes(start, 0, newAttributes, true);
    }
    
    private AttributeSet toTextAlign(AttributeSet attributes) {
        MutableAttributeSet attrs = new SimpleAttributeSet(attributes);
        String value = attrs.getAttribute(HTML.Attribute.ALIGN).toString();
        attrs.removeAttribute(HTML.Attribute.ALIGN);
        attrs.addAttribute(CSS.Attribute.TEXT_ALIGN, value);
        return attrs;
    }
 

washpuda123

Mitglied
Vielen Dank euch beiden. Die Lösung von Mihe7 funktioniert (zumindest ab da, wo ich drauf gekommen bin, das Löschen der Ausrichtung in der Methode setText() wieder zu entfernen). Ich musste jetzt nur noch die Methode caretUpdate() anpassen, damit auch die Schaltflächen korrekt gesetzt werden.

Java:
@Override
    public void caretUpdate(CaretEvent e) {
        DefaultStyledDocument styleDoc = (DefaultStyledDocument) ePane.getDocument();
        Element element = styleDoc.getCharacterElement(ePane.getCaretPosition());
        if (element.getParentElement().getName().equalsIgnoreCase("p")) {
            AttributeSet attribSetPara = element.getParentElement().getAttributes();
            Object obj = attribSetPara.getAttribute(CSS.Attribute.TEXT_ALIGN);
            if (obj == null) {
                tBtnAlignLeft.setSelected(true);
            } else {
                switch (obj.toString()) {
                case "left":
                    tBtnAlignLeft.setSelected(true);
                    break;
                case "center":
                    tBtnAlignCenter.setSelected(true);
                    break;
                case "right":
                    tBtnAlignRight.setSelected(true);
                    break;
                case "justify":
                    tBtnAlignBlock.setSelected(true);
                    break;
                }
            }
        }
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
O Soll ich einen JEditorPane verwenden ? AWT, Swing, JavaFX & SWT 5
E wie Schriftfarbe in JEditorPane verändern? AWT, Swing, JavaFX & SWT 10
P Swing JEditorPane in Kombination mit JScrollPane AWT, Swing, JavaFX & SWT 29
L Ausgabe in JEditorPane mittels HTMLEditorKit zeigt auf bestimmten Systemen falsche Zeichen AWT, Swing, JavaFX & SWT 1
N JEditorPane und automatische Scrollposition AWT, Swing, JavaFX & SWT 2
K JEditorPane Text einfügen 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
C JEditorPane und Gifs AWT, Swing, JavaFX & SWT 2
B Swing JEditorPane ohne Zeilenumbruch nach InputStream 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
S JEditorPane Zeilen zählen AWT, Swing, JavaFX & SWT 5
C Swing JEditorPane: Caret nach Rechtsklick neu setzen AWT, Swing, JavaFX & SWT 4
X JEditorPane Größe in JDialog automatisch anpassen AWT, Swing, JavaFX & SWT 2
C JTextPane / JEditorPane ohne Keywords farbig machen AWT, Swing, JavaFX & SWT 4
S JEditorPane oder JTextPane? AWT, Swing, JavaFX & SWT 2
M Swing JEditorPane: Text formatieren AWT, Swing, JavaFX & SWT 2
F Swing JEditorPane Bild mittig einbinden AWT, Swing, JavaFX & SWT 5
H Swing HTML in einem JEditorPane zeilenweise hinzufügen ohne Inhalt jedes Mal neu zu laden AWT, Swing, JavaFX & SWT 4
B 2D-Grafik Zeilen drehen im JEditorPane AWT, Swing, JavaFX & SWT 3
H Plain Text in RTF JEditorPane? AWT, Swing, JavaFX & SWT 3
D Informationen über JEditorPane gesucht AWT, Swing, JavaFX & SWT 2
C Swing Scrollbalken in JEditorPane - WIE? AWT, Swing, JavaFX & SWT 3
destroflyer Swing UTF-8 in JEditorPane darstellen AWT, Swing, JavaFX & SWT 5
J Swing JEditorPane flackert AWT, Swing, JavaFX & SWT 2
F Swing Performanceproblem mit JEditorpane AWT, Swing, JavaFX & SWT 3
S Swing HTML-Text in JEditorPane einfärben AWT, Swing, JavaFX & SWT 5
I JTextPane und Hyperlink (ohne JEditorPane) AWT, Swing, JavaFX & SWT 5
P Swing JEditorPane mit HTMLDocument - Text hinzufügen AWT, Swing, JavaFX & SWT 2
T Swing JEditorPane Groesse berechnen AWT, Swing, JavaFX & SWT 2
N Swing JEditorPane mit Farbe und Font AWT, Swing, JavaFX & SWT 2
T Swing JTextArea, JTextPane, JEditorPane...Unterschied?! AWT, Swing, JavaFX & SWT 3
B JEditorPane - Absätze werden nicht gespeichert AWT, Swing, JavaFX & SWT 12
K Verweise in JEditorPane AWT, Swing, JavaFX & SWT 6
B JEditorPane - Text und Graphik in HTML speichern AWT, Swing, JavaFX & SWT 4
D Swing JEditorPane wort zu lang AWT, Swing, JavaFX & SWT 11
X Swing Inhalt einer JEditorPane in Datei abspeichern AWT, Swing, JavaFX & SWT 5
D Swing JEditorPane mit HTML aber ohne Bilder AWT, Swing, JavaFX & SWT 3
Developer_X Swing JEditorPane.paste(Lokale_HTML); AWT, Swing, JavaFX & SWT 11
W Swing dynamisch Buttons in JEditorPane erstellen AWT, Swing, JavaFX & SWT 2
H JScrollPane (mit JEditorpane ) resizing AWT, Swing, JavaFX & SWT 2
E Swing File lesen und in JEditorpane AWT, Swing, JavaFX & SWT 2
D GridBagLayout und JEditorPane (mehrere fragen) AWT, Swing, JavaFX & SWT 2
S JEditorPane soll HTML und dann Text anzeigen..? AWT, Swing, JavaFX & SWT 5
T HTML und JEditorPane AWT, Swing, JavaFX & SWT 6
Daniel_L jEditorPane - Formatierten Text in Zwischenablage kopieren? AWT, Swing, JavaFX & SWT 2
R JEditorPane Schriftart und Schriftgröße AWT, Swing, JavaFX & SWT 3
K Instanz von JEditorPane starten AWT, Swing, JavaFX & SWT 3
W HTML-Text mit relativer URL in JEditorPane einlesen AWT, Swing, JavaFX & SWT 10
J Flackern in JEditorPane() AWT, Swing, JavaFX & SWT 14
& eigene Schriftart in JEditorpane AWT, Swing, JavaFX & SWT 2
M JEditorPane lädt HTML ohne Bilder AWT, Swing, JavaFX & SWT 2
M JEditorPane lädt HTML ohne Bilder AWT, Swing, JavaFX & SWT 2
DeeDee0815 JEditorPane + HTML + <img src=file> + JAR = FALSE AWT, Swing, JavaFX & SWT 3
G JEditorPane + F6 AWT, Swing, JavaFX & SWT 2
I Anordnungsprobleme bei JEditorPane AWT, Swing, JavaFX & SWT 5
ChMaster JEditorPane / HTMLEditorKit AWT, Swing, JavaFX & SWT 3
G JEditorPane | Homepage wird nicht richtig angezeigt AWT, Swing, JavaFX & SWT 8
J JEditorPane zeigt nicht alles AWT, Swing, JavaFX & SWT 2
I JEditorPane vorladen der Seiten unterbinden AWT, Swing, JavaFX & SWT 2
P JEditorPane mit HTMLEditorKit Text ausrichten AWT, Swing, JavaFX & SWT 2
T Projekt - ChatClient - JEditorPane - Smilies, Vektor AWT, Swing, JavaFX & SWT 2
N java.awt.Color zu HTML Farbcode (JEditorPane) AWT, Swing, JavaFX & SWT 1
T Grösse einer JEditorPane ändern AWT, Swing, JavaFX & SWT 5
G JEditorPane Zeilenumbruch verhindern AWT, Swing, JavaFX & SWT 2
F wie funktionier JEditorPane AWT, Swing, JavaFX & SWT 8
M jEditorPane String to html AWT, Swing, JavaFX & SWT 2
T DataFlavor für HTML-formatierten Text im JEditorPane AWT, Swing, JavaFX & SWT 8
G Welchen Listener für JEditorPane ? AWT, Swing, JavaFX & SWT 3
G HTML aus JEditorPane drucken AWT, Swing, JavaFX & SWT 2
F Frage zu JEditorPane und Text einfügen AWT, Swing, JavaFX & SWT 2
G JEditorPane HTML-Email versenden AWT, Swing, JavaFX & SWT 2
C getText() sinnlos bei HTMLEditorKit und JEditorPane! AWT, Swing, JavaFX & SWT 11
F Das Standardbild beim JEditorPane ersetzen? AWT, Swing, JavaFX & SWT 8
M Image-Objekte in JEditorPane anzeigen? AWT, Swing, JavaFX & SWT 3
U Bild in JEditorPane oder Aus "" mach' "/&quot AWT, Swing, JavaFX & SWT 2
I how to implement.(About JTable and the JEditorPane) AWT, Swing, JavaFX & SWT 6
S JEditorPane HTML-Text auslesen AWT, Swing, JavaFX & SWT 2
M JEditorPane und HyperLinks AWT, Swing, JavaFX & SWT 9
B JEditorPane: Höhe für bestimmte Breite bestimmen AWT, Swing, JavaFX & SWT 4
S Link in JEditorPane AWT, Swing, JavaFX & SWT 5
M JEditorPane und Bild als html? AWT, Swing, JavaFX & SWT 7
F Link aus JEditorPane ausführen AWT, Swing, JavaFX & SWT 2
S HTML-Datei in Anwendung (JEditorPane) AWT, Swing, JavaFX & SWT 5
M Jeditorpane + zeilenumbruch AWT, Swing, JavaFX & SWT 2
N File von HDD in JEditorPane laden? AWT, Swing, JavaFX & SWT 2
B In JScrollPane eingebettetes JEditorPane scrollen AWT, Swing, JavaFX & SWT 2
L Image Problems with JEditorPane AWT, Swing, JavaFX & SWT 7
D Kann jeditorPane CSS Style-Sheets und javascript AWT, Swing, JavaFX & SWT 2
T JEditorPane-content drucken AWT, Swing, JavaFX & SWT 2
T HTML in JEditorPane darstellen AWT, Swing, JavaFX & SWT 5
C JEditorPane, HTML EditorKit und HTMLDocument AWT, Swing, JavaFX & SWT 8
bernd Zeilenumbruch in JEditorPane AWT, Swing, JavaFX & SWT 10
S JEditorPane: Benachrichtigung, wenn Inhalt geladen AWT, Swing, JavaFX & SWT 2
M JEditorPane und Strg - z? AWT, Swing, JavaFX & SWT 2
S JEditorPane setText() Problem mit String übergeben AWT, Swing, JavaFX & SWT 3
S JEditorPane Tags löschen AWT, Swing, JavaFX & SWT 3
S JEditorPane AWT, Swing, JavaFX & SWT 2
S Textausrichtung in gedrehtem JLabel AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen

Neue Themen


Oben