2011-08-01 25 views
0

我一直在使用一個JTextPane(或者我的一個子版本),因此我一直在使用樣式。我的程序沒有按照我想要的方式行事,我跟蹤了我認爲是AttributeSet.containsAttributes(AttributeSet屬性)方法中的一個錯誤的行爲。我寫了以下短程序來說明它:我在Java中發現了一個錯誤嗎?關於屬性集

import javax.swing.JTextPane; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.Style; 

public class StyleBug { 
    public static void main(String[] args) { 

     JTextPane textPane = new JTextPane(); 
     textPane.setText("This is a test string"); 

     Style bold = textPane.addStyle(BOLD, null); 
     StyleConstants.setBold(bold, true); 

     Style italic = textPane.addStyle(ITALIC, null); 
     StyleConstants.setItalic(italic, true); 

     int start = 5; 
     int end = 10; 

     textPane.getStyledDocument().setCharacterAttributes(start, end - start, textPane.getStyle(BOLD), false); 
     textPane.getStyledDocument().setCharacterAttributes(start, end - start, textPane.getStyle(ITALIC), false); 

     for(int i = start; i < end; i++) 
      System.out.println(textPane.getStyledDocument().getCharacterElement(i).getAttributes() 
      .containsAttributes(textPane.getStyle(BOLD))); //all print false 
    } 

    private static final String BOLD = "Bold"; 
    private static final String ITALIC = "Italic"; 
} 

這是一個錯誤,還是我在這裏丟失了一些東西?

+0

您是否指靜態初始化? – Mikaveli

+0

textPane.getStyle(BOLD)和textPane.getStyle(ITALIC), –

+0

@Mikaveli,我提到的錯誤是,containsAttributes方法表示文本不是粗體,即使我使用了Bold屬性的樣式。 – Mark

回答

4

如果我註釋掉這一行:

// textPane.getStyledDocument().setCharacterAttributes(start, end - start, textPane.getStyle(ITALIC), false); 

然後打印所有的元素都是如此。根據Javadoc的setCharacterAttributes它使用了所傳遞的樣式中的所有屬性,因此您只需使用ITALIC選擇覆蓋BOLD選擇。

編輯:

我拉起調試,並得到該數組的屬性爲getCharacterElement(5)

[0] javax.swing.text.StyleConstants$FontConstants "italic" 
[1] java.lang.Boolean "true" 
[2] javax.swing.text.StyleConstants "name" 
[3] java.lang.String "Italic" 
[4] javax.swing.text.StyleConstants$FontConstants "bold" 
[5] java.lang.Boolean "true" 

正如你所看到的,屬性是在2 italic組順序設置爲true,bold設置爲true,並且name設置爲"Italic"。這可能意味着只有一個名稱被允許用於爲角色設置命名屬性。請注意,未命名的屬性已正確合併,所以即使您無法查看某個特定的命名屬性是否應用於某個字符,它也是您想要的。

+1

謝謝你幫我解決這個問題。 是的,我也注意到了。但是當我添加斜體屬性時,我期望它保持大膽的屬性。我在setCharacterAttributes中使用的第四個參數應該確定新屬性是覆蓋舊屬性還是與它們合併。 來自Javadoc: 布爾替換 - 指示在設置新屬性之前是否應清除先前屬性。如果爲true,則該操作將完全替換先前的屬性。如果爲false,則新屬性將與之前的屬性合併。 – Mark

+0

(對不起,這是我第一次發佈) – Mark

+0

@Mark我已經編輯了我的答案,現在你已經指出了。它看起來像你不能依賴風格的名稱,如果你要合併風格在一起(這是有道理的)。 – Bringer128

2

Bringer128發現了上面的問題,但我會澄清一點。

將樣式添加到JTextPane時,作爲參數傳遞的字符串實際上被放置爲樣式作爲屬性(毫不奇怪,NameAttribute)。將樣式應用於一系列字符時,NameAttribute與樣式上設置的任何其他屬性一起應用。所以當我應用BOLD風格時,該範圍內的每個字符都將其BoldAttribute設置爲true,並將其NameAttribute設置爲「粗體」。然後,當我應用了ITALIC Style時,每個角色的ItalicAttribute設置爲true,然後將其NameAttribute設置爲「Italic」。然後,如果containsAttributes()檢查了我的BOLD風格中的所有屬性是否應用於這些字符,則返回false,因爲它們的NameAttributes已從「粗體」更改爲「斜體」。我希望這不會讓任何人感到困惑。

這是我的工作(我認爲它實際上比原始代碼簡單)。它的要點是我從來不使用Styles或JTextPane.addStyle();我只是保持常量MutableAttributeSets。

import javax.swing.JTextPane; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.MutableAttributeSet; 
import javax.swing.text.SimpleAttributeSet; 

public class StyleBugFix { 
    public static void main(String[] args) { 

     JTextPane textPane = new JTextPane(); 
     textPane.setText("This is a test string"); 

     StyleConstants.setBold(BOLD, true); 

     StyleConstants.setItalic(ITALIC, true); 

     int start = 5; 
     int end = 10; 

     textPane.getStyledDocument().setCharacterAttributes(start, end - start, BOLD, false); 
     textPane.getStyledDocument().setCharacterAttributes(start, end - start, ITALIC, false); 
     for(int i = start; i < end; i++) 
      System.out.println(textPane.getStyledDocument().getCharacterElement(i).getAttributes() 
       .containsAttributes(BOLD)); //all now print true 
    } 

    private static final MutableAttributeSet BOLD = new SimpleAttributeSet(); 
    private static final MutableAttributeSet ITALIC = new SimpleAttributeSet(); 
} 

再次感謝Bringer128的全力幫助。

+0

用於發佈最終解決方案作爲答案。這應該有助於其他任何碰到此問題的人。 – Bringer128

相關問題