2016-09-03 5 views
0

Ich verwende eine JTextPane, um etwas HTML zu rendern. Ich verwende eine HTMLEditorKit und eine StyleSheet, um Regeln zu der code Eigenschaft hinzuzufügen, so dass es genau wie der Code auf StackOverflow aussieht. Das Problem besteht darin, dass JTextPane die Auffüllung des Codes (1 Pixel oben/unten, 5 Pixel links/rechts) nicht rendert, obwohl die padding Eigenschaft als eine der Eigenschaften aufgeführt wird, die von der Rendering-Engine unterstützt wird in the documentation. HierCSS-Padding nicht gerendert in JTextPane

ist, was ich zu erwarten (Wie this CSSDeck Lab gezeigt): Expected Output
↑ - ↑ ↑ - ↑
EDIT:
Ich habe umgeschaltet von der Nutzung der <code> Tags in mein HTML und habe auf Vorschlag von @Sharcoux auf <span> gewechselt. Dies machte die Schriftgröße des zu verwendenden Codes gleich wie der Text in den <pre> Tags, so dass der rote Hintergrund dieselbe Höhe wie der grüne Rand hat, das erwartete Ergebnis wird jedoch immer noch nicht erzeugt. Here ist das Originalbild, wenn Sie interessiert sind.

Dies ist, was tatsächlich erscheint: Actual Output

Ich habe auch versucht, mit dem Text der CSS inline bewegen, aber ohne Erfolg.

MCVE (auch Edited):

import java.awt.Dimension; 
import java.awt.EventQueue; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextPane; 
import javax.swing.text.html.HTMLEditorKit; 
import javax.swing.text.html.StyleSheet; 

public class CodePaddingMCVE { 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> { 
      JFrame frame = new JFrame("Code Padding Test"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

      JTextPane tp = new JTextPane(); 
      tp.setContentType("text/html"); 

      HTMLEditorKit kit = new HTMLEditorKit(); 
      tp.setEditorKit(kit); 
      StyleSheet sheet = kit.getStyleSheet(); 
      sheet.addRule("span {padding: 1px 5px; background-color: red}"); //Using span here 
      sheet.addRule("pre {padding: 0px; background-color: green}"); 
      tp.setDocument(kit.createDefaultDocument()); 
      tp.setText("<html><pre>NotCode<span>Code</span>NotCode</pre></html>"); //Using <span> here too 

      JScrollPane sp = new JScrollPane(tp) { 
       private static final long serialVersionUID = 1L; 

       @Override 
       public Dimension getPreferredSize() { 
        return new Dimension(250, 50); 
       } 

      }; 

      frame.getContentPane().add(sp); 
      frame.pack(); 
      frame.setVisible(true); 
     }); 
    } 

} 

Ich bin mit OS X Yosemite 10.10.15 Eclipse Mars.2 4.5.2 und Java 8 [1.8.0_66].

+0

Sie sollten ein span-Element anstelle von Code verwenden. Und ich bin mir nicht sicher, ob das Pre-Tag erkannt wird, aber ich erinnere mich nicht und bin gerade an meinem Telefon. – Sharcoux

Antwort

1

Sie haben Recht, der Rand und das Padding scheinen nicht auf Inline-Elemente angewendet zu werden. Sie haben 3 Möglichkeiten.

1) Geben Sie JTextPane auf und verwenden Sie stattdessen JavaFX WebView.

2) geben Sie HTMLDocument auf und verwenden Sie eine andere Implementierung.

3) versuchen Sie, HTMLFactory in HTMLEditorKit zu erweitern und InlineView zu erweitern. Es würde Ihnen etwas Ähnliches:

import java.awt.Dimension; 
import java.awt.EventQueue; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextPane; 
import javax.swing.text.AbstractDocument; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.Element; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.View; 
import javax.swing.text.ViewFactory; 
import javax.swing.text.html.HTML; 
import javax.swing.text.html.HTMLEditorKit; 
import javax.swing.text.html.InlineView; 
import javax.swing.text.html.StyleSheet; 

public class CodePaddingMCVE { 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       JFrame frame = new JFrame("Code Padding Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       JTextPane tp = new JTextPane(); 
       tp.setContentType("text/html"); 

       HTMLEditorKit kit = new HTMLEditorKit() { 
        public ViewFactory getViewFactory() { 
         return new HTMLFactory() { 
          public View create(Element elem) { 
           AttributeSet attrs = elem.getAttributes(); 
           Object elementName = 
            attrs.getAttribute(AbstractDocument.ElementNameAttribute); 
           Object o = (elementName != null) ? 
            null : attrs.getAttribute(StyleConstants.NameAttribute); 
           if (o instanceof HTML.Tag) { 
            HTML.Tag kind = (HTML.Tag) o; 
            if (kind == HTML.Tag.CONTENT) { 
             return new InlineView(elem) { 
              private short left; 
              private short right; 
              private short top; 
              private short bottom; 
              protected void setPropertiesFromAttributes() { 
               AttributeSet attr = getAttributes(); 
               if (attr != null) { 
                top = (short) StyleConstants.getSpaceAbove(attr); 
                left = (short) StyleConstants.getLeftIndent(attr); 
                bottom = (short) StyleConstants.getSpaceBelow(attr); 
                right = (short) StyleConstants.getRightIndent(attr); 
               } 
               super.setPropertiesFromAttributes(); 
              } 
              //TODO : use the top, left, bottom and right properties to draw the margin/padding 
             }; 
            } 
           } 
           return super.create(elem); 
          } 
         }; 
        } 
       }; 
       tp.setEditorKit(kit); 
       StyleSheet sheet = kit.getStyleSheet(); 
       sheet.addRule("span {padding: 5px 5px 5px 5px; background-color: red}"); //Using span here 
       sheet.addRule("pre {padding: 0px; background-color: green}"); 
       tp.setDocument(kit.createDefaultDocument()); 
       tp.setText("<html><pre>NotCode<span>Code</span>NotCode</pre></html>"); //Using <span> here too 

       JScrollPane sp = new JScrollPane(tp) { 
        private static final long serialVersionUID = 1L; 

        @Override 
        public Dimension getPreferredSize() { 
         return new Dimension(250, 50); 
        } 

       }; 

       frame.getContentPane().add(sp); 
       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 

Wenn Sie diesen Weg einschlagen wollen, müssen Sie in der Labelview und GlyphView graben, um zu sehen, wie man eine Polsterung oder eine Marge implementieren kann. Vielleicht könnten andere helfen, das zu beenden.

Viel Glück.

+0

Danke für Ihre Antwort! Ich ging mit dem JavaFX 'WebView', als wäre es der einfachste Ansatz. – MasterBlaster