Нашел ли я ошибку в Java? Относительно AttributeSet - PullRequest
0 голосов
/ 01 августа 2011

Я использую JTextPane (или мою субклассированную версию) в приложении, которое я пишу, и поэтому я работаю со стилями.Моя программа работала не так, как я хотел, и я отследил поведение, которое, на мой взгляд, является ошибкой в ​​методе AttributeSet.containsAttributes (AttributeSet attribute).Я написал следующую короткую программу, чтобы проиллюстрировать это:

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";
}

Это ошибка, или я что-то здесь упускаю?

Ответы [ 2 ]

4 голосов
/ 01 августа 2011

Если я закомментирую эту строку:

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

Тогда он печатает истину для всех элементов. Согласно Javadoc для setCharacterAttributes он использует все атрибуты из стиля, который вы передаете, поэтому вы просто переопределяете выбор BOLD с выбором ITALIC.

EDIT:

Я включил отладчик и получил этот массив атрибутов для 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". Вероятно, это означает, что для именованного атрибута, заданного для символа, разрешено только одно имя. Обратите внимание, что безымянные атрибуты были объединены правильно, так что это то, что вам нужно, даже если вы не видите, применяется ли определенный именованный атрибут к персонажу.

2 голосов
/ 02 августа 2011

Bringer128 обнаружил проблему выше, но я просто уточню немного.

Когда стиль добавляется в JTextPane, строка, передаваемая в качестве аргумента, фактически помещается в стиль в качестве атрибута (что неудивительно, атрибут NameAttribute). Когда Стиль применяется к диапазону символов, NameAttribute применяется вместе со всеми другими Атрибутами, которые были установлены в Стиле. Поэтому, когда мой стиль BOLD был применен, каждый символ в этом диапазоне имел свой BoldAttribute, установленный в true, и его NameAttribute, установленный в "Bold". Затем, когда был применен мой стиль ITALIC, каждый символ имел свой ItalicAttribute, установленный в true, а затем его NameAttribute, установленный в "Italic". Затем, когда containsAttributes () проверило, все ли атрибуты в моем стиле BOLD были применены к этим символам, он вернул false, поскольку их атрибуты NameAttributes были изменены с «Bold» на «Italic». Надеюсь, это никого не смутило.

Вот моя работа (я думаю, что это на самом деле проще, чем оригинальный код). Суть в том, что я никогда не использую 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 за всю его помощь.

...