2012-10-25 44 views
9

Tôi đã tìm kiếm này trong một thời và cho đến nay tất cả những gì tôi có thể đưa ra là làm thế nào để tạo ra một phong cách và áp dụng nó vào một nhân vật như vậy:Làm cách nào để đặt từng ký tự thành màu nền/màu nền khác nhau trong 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); 

này rất hữu ích nếu bạn chỉ có một vài kiểu trong tài liệu của mình và muốn lưu trữ chúng theo tên để bạn có thể áp dụng chúng một cách dễ dàng sau này. Trong ứng dụng của tôi, tôi muốn có thể thiết lập màu nền trước (một trong số chỉ một vài giá trị) và màu nền (thang độ xám, nhiều giá trị khác nhau) một cách độc lập cho mỗi ký tự trong văn bản. Nó có vẻ như một sự lãng phí rất lớn để tạo ra hàng trăm/hàng ngàn phong cách khác nhau cho việc này. Có cách nào để đặt các thuộc tính này mà không phải tạo kiểu mới mỗi lần không? Sẽ dễ dàng hơn nhiều nếu tôi chỉ phải hiển thị văn bản nhưng tôi cũng cần phải chỉnh sửa văn bản. Có cách nào để làm điều này với JTextPane, hoặc là có một lớp swing cung cấp chức năng này?

Trả lời

14

Nếu bạn muốn thay đổi phong cách cho mỗi nhân vật trong một textpane, đây là một cách ngẫu nhiên hoàn chỉnh để làm điều đó. Bạn tạo một thuộc tính khác nhau được đặt cho mỗi ký tự. Tùy thuộc vào bạn để tìm sự kết hợp thích hợp (tương phản nền trước/nền, không quá nhiều sự khác biệt về kích thước của ký tự, v.v.). Bạn cũng có thể lưu trữ các kiểu khác nhau mà bạn đã áp dụng để bạn không sử dụng cùng một kiểu hai lần.

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

bất kỳ vấn đề bản quyền nào với văn bản? Rất thích sử dụng nó trong bài kiểm tra SwingX utils :-) – kleopatra

+0

@ kleopatra AFAIK "Lorem ipsum" thuộc phạm vi công cộng vì nó tồn tại hơn 500 năm. –

+1

@kleopatra không tôi lấy nó từ [đây] (http://www.lipsum.com/) –

9

Tôi không chắc chắn ý bạn là gì, nhưng bạn không thể lặp qua từng ký tự trong JtextPane và trong vòng lặp đó lặp qua tất cả các chữ cái/ký tự bạn muốn đánh dấu v.v. thiết lập Style cho phù hợp.

Dưới đây là một ví dụ tôi làm tôi chỉ thực hiện nó cho các nhân vật hw cho các mục đích trình diễn:

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

Cảm ơn David. Việc đặt từng nhân vật riêng lẻ không phải là quá nhiều vấn đề, nó chỉ là mỗi nhân vật cần phải là một phong cách mới mà có thể không được chia sẻ với bất kỳ nhân vật nào khác. Tôi cần phải làm điều này cho vài nghìn ký tự và do đó có thể sẽ cần hàng trăm kiểu. Tôi chỉ muốn làm điều này mà không cần phải thêm một phong cách mới được đặt tên mỗi lần. Tuy nhiên, sẽ chỉ có một vài màu nền trước, vì vậy tôi đoán tôi có thể đặt văn bản trên nền mà tôi tự vẽ. – JaredL

0

Tôi nghĩ rằng cách tốt nhất mà bạn phải làm điều này cũng giống như chúng tôi có trong biên tập viên với điểm nhấn, không đuổi theo cho các ký tự, nhưng có một mô hình, ví dụ:

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); 
} 
Các vấn đề liên quan