2012-10-25 113 views
9

我一直在尋找這一段時間,到目前爲止,所有的我已經能夠拿出的是如何創建一個樣式,並將其應用到一個字符,像這樣:如何在JTextPane中將每個字符設置爲不同的顏色/背景顏色?

StyledDocument doc = (StyledDocument) new DefaultStyledDocument(); 
JTextPane textpane = new JTextPane(doc); 
textpane.setText("Test"); 
javax.swing.text.Style style = textpane.addStyle("Red", null); 
StyleConstants.setForeground(style, Color.RED); 
doc.setCharacterAttributes(0, 1, textpane.getStyle("Red"), true); 

這是非常有用如果您的文檔中只有幾種樣式,並希望按名稱存儲它們,以便稍後可以輕鬆應用它們。在我的應用程序中,我希望能夠爲文本中的每個字符獨立設置前景顏色(只有幾個值之一)和背景顏色(灰度,許多不同的值)。爲此創建潛在的數百/數千種不同風格似乎是一項巨大的浪費。有沒有辦法設置這些屬性,而不必每次都創建一個新的樣式?如果我只需要渲染文本就會容易得多,但我也需要使其可編輯。有沒有辦法做到這一點JTextPane,還是有另一個擺動類,提供這種功能?

回答

14

如果你想改變風格爲每個字符在文本面板中,這是一個完全隨機的方式來完成它。您爲每個角色創建一個不同的屬性集。你可以找到合適的組合(前景/背景對比度,字符大小沒有太大差異等)。您還可以存儲已應用的不同樣式,以免兩次使用相同的樣式。

enter image description here

import java.awt.Color; 
import java.util.Random; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextPane; 
import javax.swing.text.DefaultStyledDocument; 
import javax.swing.text.SimpleAttributeSet; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.StyledDocument; 

public class TestDifferentStyles { 
    private void initUI() { 
     JFrame frame = new JFrame(TestDifferentStyles.class.getSimpleName()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     StyledDocument doc = new DefaultStyledDocument(); 
     JTextPane textPane = new JTextPane(doc); 
     textPane.setText("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has " 
       + "been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of " 
       + "type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the " 
       + "leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the" 
       + " release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing " 
       + "software like Aldus PageMaker including versions of Lorem Ipsum."); 

     Random random = new Random(); 
     for (int i = 0; i < textPane.getDocument().getLength(); i++) { 
      SimpleAttributeSet set = new SimpleAttributeSet(); 
      // StyleConstants.setBackground(set, new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256))); 
      StyleConstants.setForeground(set, new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256))); 
      StyleConstants.setFontSize(set, random.nextInt(12) + 12); 
      StyleConstants.setBold(set, random.nextBoolean()); 
      StyleConstants.setItalic(set, random.nextBoolean()); 
      StyleConstants.setUnderline(set, random.nextBoolean()); 

      doc.setCharacterAttributes(i, 1, set, true); 
     } 

     frame.add(new JScrollPane(textPane)); 
     frame.setSize(500, 400); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 

     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new TestDifferentStyles().initUI(); 
      } 
     }); 
    } 

} 
+0

有關文本的任何版權問題?願意在SwingX測試工具中使用它:-) – kleopatra

+0

@kleopatra AFAIK「Lorem ipsum」在公共領域已有500多年的歷史。 –

+1

@kleopatra不,我從[這裏](http://www.lipsum.com/) –

9

我不知道你的意思,但你不能通過在JtextPane,並通過所有字母循環迭代中的每個字符循環要突出顯示等/字符有一個如果語句檢查字符,然後相應地設置Style

這裏是我做了一個例子,我只是實現它的人物^h瓦特用於演示目的:

enter image description here

//necessary imports 
import java.awt.Color; 
import java.util.ArrayList; 
import javax.swing.JFrame; 
import javax.swing.JTextPane; 
import javax.swing.text.DefaultStyledDocument; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.StyledDocument; 

public class Test { 

    /** 
    * Default constructor for Test.class 
    */ 
    public Test() { 
     initComponents(); 
    } 

    public static void main(String[] args) { 

     /** 
     * Create GUI and components on Event-Dispatch-Thread 
     */ 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       Test test = new Test(); 
      } 
     }); 
    } 

    /** 
    * Initialize GUI and components (including ActionListeners etc) 
    */ 
    private void initComponents() { 
     JFrame jFrame = new JFrame(); 
     jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     StyledDocument doc = (StyledDocument) new DefaultStyledDocument(); 
     JTextPane textPane = new JTextPane(doc); 
     textPane.setText("Hello, world! :)"); 

     //create necessary styles for various characters 
     javax.swing.text.Style style = textPane.addStyle("Red", null); 
     StyleConstants.setForeground(style, Color.RED); 
     javax.swing.text.Style style2 = textPane.addStyle("Blue", null); 
     StyleConstants.setForeground(style2, Color.BLUE); 

     //create array of characters to check for and style 
     String[] lettersToEdit = new String[]{"h", "w"}; 

     //create arraylist to hold each character in textPane 
     ArrayList<String> strings = new ArrayList<>(); 

     //get all text 
     String text = textPane.getText(); 

     //populate arraylist 
     for (int i = 0; i < text.length(); i++) { 
      strings.add(text.charAt(i) + ""); 
     } 

     //declare variabe to hold position 
     int position = 0; 

     for (String s1 : strings) {//for each character in the textpane text 
      for (String s2 : lettersToEdit) {//for each character in array to check (lettersToEdit) 
       if (s2.toLowerCase().equalsIgnoreCase(s1)) {//if there was a match 

        System.out.println("found a match: " + s1); 
        System.out.println("counter: " + position + "/" + (position + 1)); 

        //check which chacacter we matched 
        if (s1.equalsIgnoreCase(lettersToEdit[0])) { 
         //set appropriate style 
         doc.setCharacterAttributes(position, 1, textPane.getStyle("Red"), true); 
        } 
        if (s1.equalsIgnoreCase(lettersToEdit[1])) { 
         doc.setCharacterAttributes(position, 1, textPane.getStyle("Blue"), true); 
        } 
       } 
      } 
      //increase position after each character on textPane is parsed 
      position++; 
     } 

     jFrame.add(textPane); 
     //pack frame (size JFrame to match preferred sizes of added components and set visible 
     jFrame.pack(); 
     jFrame.setVisible(true); 
    } 
} 
+0

謝謝大衛。單獨設置每個角色並不是一個太大的問題,只是每個角色需要成爲一種新的風格,可能不會與任何其他角色共享。我需要爲數千個角色完成此操作,因此可能需要數百種樣式。我只想這樣做,而不必每次都添加一個新的命名樣式。雖然只有少數幾種前景顏色之一,所以我想我可以把文字放在我自己渲染的背景上。 – JaredL

0

我認爲你必須做到這一點的最好辦法是像我們在與亮點,而不是追逐字符,但具有圖案編輯器,例如:

private static HashMap<Pattern, Color> patternColors; 
private static String GENERIC_XML_NAME = "[A-Za-z]+[A-Za-z0-9\\-_]*(:[A-Za-z]+[A-Za-z0-9\\-_]+)?"; 
private static String TAG_PATTERN = "(</?" + GENERIC_XML_NAME + ")"; 
private static String TAG_END_PATTERN = "(>|/>)"; 
private static String TAG_ATTRIBUTE_PATTERN = "(" + GENERIC_XML_NAME + ")\\w*\\="; 
private static String TAG_ATTRIBUTE_VALUE = "\\w*\\=\\w*(\"[^\"]*\")"; 
private static String TAG_COMMENT = "(<\\!--[\\w ]*-->)"; 
private static String TAG_CDATA = "(<\\!\\[CDATA\\[.*\\]\\]>)"; 

private static final Color COLOR_OCEAN_GREEN = new Color(63, 127, 127); 
private static final Color COLOR_WEB_BLUE = new Color(0, 166, 255); 
private static final Color COLOR_PINK = new Color(127, 0, 127); 

static { 
    // NOTE: the order is important! 
    patternColors = new LinkedHashMap<Pattern, Color>(); 
    patternColors.put(Pattern.compile(TAG_PATTERN), Color.BLUE); // COLOR_OCEAN_GREEN | Color.BLUE 
    patternColors.put(Pattern.compile(TAG_CDATA), COLOR_WEB_BLUE); 
    patternColors.put(Pattern.compile(TAG_ATTRIBUTE_PATTERN), COLOR_PINK); 
    patternColors.put(Pattern.compile(TAG_END_PATTERN), COLOR_OCEAN_GREEN); 
    patternColors.put(Pattern.compile(TAG_COMMENT), Color.GRAY); 
    patternColors.put(Pattern.compile(TAG_ATTRIBUTE_VALUE), COLOR_OCEAN_GREEN); //Color.BLUE | COLOR_OCEAN_GREEN 
} 




public XmlView(Element element) { 

    super(element); 

    // Set tabsize to 4 (instead of the default 8). 
    getDocument().putProperty(PlainDocument.tabSizeAttribute, 4); 
}