2013-09-30 4 views
3

Я создаю текстовый редактор с использованием JTextPane, который позволяет пользователю изменять цвет выделенного текста. Но когда пользователь выбирает текст, затем выбирает вариант изменения цвета (например, красного), текст не отображается как красный, пока текст не будет выбран. Я попытался использовать setSelectedTextColor для изменения цвета выделенного текста, но это не сработало, так как после этого текст изменяется на красный, когда текст выбран. Есть ли способ, чтобы выбранный текст отображался как фактический цвет? Или как способ работы в Word, где это не фактический цвет текста, но при выборе текста разных цветов они отображаются как разные цвета, даже если они выбраны.Изменение цвета выделенного текста в jTextPane

Я использую следующий код для настройки JTextPane и кнопки, которая изменяет выделенный текст в красный цвет:

JButton redButton = new JButton(new StyledEditorKit.ForegroundAction("red", Color.RED)); 
redButton.setFocusable(false); 
buttonPanel.add(redButton); 

JTextPane настроенный, как с типом HTML контента и использует HTMLEditorKit:

p=new JTextPane(); 
p.setSize(300, 300); 
kit = new HTMLEditorKit(); 
p.setEditorKit(kit); 
p.setDocument(kit.createDefaultDocument()); 

p.setContentType("text/html"); 
p.setEditable(true); 

Дайте мне знать, если вам нужно больше исходного кода, чтобы понять вопрос. Спасибо!

ответ

3

Похоже, что вы можете использовать нечто иное, кроме фамилии шрифта. Я повторил этот example, чтобы использовать JTextPane и увидел ожидаемый результат. Как отмечено в этом документе, для действий требуется имя фамилии шрифта, например. по умолчанию или face=SansSerif, как определено классом FontFamilyAction, вложенным в StyledEditorKit.

image

JTextPane textPane = new JTextPane(); 
+0

Я могу воссоздать свой предыдущий пример, используя setSelectedText (цвет). Но мой вопрос в том, поддерживает ли Java переменные цвета текста или поддерживает только один. Поэтому, если я выбрал 2 слова, один черный текст и один красный текст, и я установил выделенный цвет текста на красный (setSelectedTextColor (Color.RED)), то оба слова будут отображаться красным, если выделено, но я хотел бы получить черное слово по-прежнему отображается как черный, даже если подсвечивается. – smith8ar

+0

Я не уверен, чего вы пытаетесь достичь; действия «EditorKit» предназначены для работы над выбором, сохраняя при этом четкость. – trashgod

+0

Моя проблема с выполнением действий над выбранным текстом, а скорее с тем, как текст отображается, когда он подсвечен. В вашем примере выделенный текст отображается красным. Но скажем в оригинале, невыбранный текст «Стек» красный, а «OverFlow» - черный. Когда выделено, оно все равно будет отображаться как все красное, как на скриншоте. Поэтому мне интересно, есть ли способ, чтобы часть слова «OverFlow» по-прежнему отображалась как черная, когда выделено, и «Stack» по-прежнему остается красным. – smith8ar

3

Посмотрите на DefaultHighlightPainter внутренний класс DefaultHighlighter.

Метод

public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) { 
     Rectangle alloc = bounds.getBounds(); 
     try { 
      // --- determine locations --- 
      TextUI mapper = c.getUI(); 
      Rectangle p0 = mapper.modelToView(c, offs0); 
      Rectangle p1 = mapper.modelToView(c, offs1); 

      // --- render --- 
      Color color = getColor(); 

      if (color == null) { 
       g.setColor(c.getSelectionColor()); 
      } 
      else { 
       g.setColor(color); 
      } 

Как вы можете видеть, он использует либо getColor() или getSelectionColor(). Вы можете расширить класс и адаптировать подсветку.

Или используйте более простой подход для переопределения JTextPane's getSelectionColor(). В методе просто проверьте, выбран ли текст, и используйте атрибуты выбранных элементов для получения желаемого ccolor. Если ничего не выбрано просто вернуть super.getSelectedColor()

UPDATE: фактического применение цветов для выбора используются на низком уровень GlyphView в общественных аннулируются краски (график г, форма а) { ... JTextComponent дц = (JTextComponent) с; Цвет selFG = tc.getSelectedTextColor();

 if (// there's a highlighter (bug 4532590), and 
      (tc.getHighlighter() != null) && 
      // selected text color is different from regular foreground 
      (selFG != null) && !selFG.equals(fg)) { 

      Highlighter.Highlight[] h = tc.getHighlighter().getHighlights(); 
      if(h.length != 0) { 
       boolean initialized = false; 
       int viewSelectionCount = 0; 
       for (int i = 0; i < h.length; i++) { 
        Highlighter.Highlight highlight = h[i]; 
        int hStart = highlight.getStartOffset(); 
        int hEnd = highlight.getEndOffset(); 
        if (hStart > p1 || hEnd < p0) { 
         // the selection is out of this view 
         continue; 
        } 
        if (!SwingUtilities2.useSelectedTextColor(highlight, tc)) { 
         continue; 
        } 

...

Как вы можете видеть, применение цвета выбора против цвета просмотра по умолчанию определяется в SwingUtilities2.useSelectedTextColor (изюминка, дц)

В источниках http://kickjava.com/src/com/sun/java/swing/SwingUtilities2.java.htm

public static boolean useSelectedTextColor(Highlighter.Highlight JavaDoc h, JTextComponent JavaDoc c) { 
    Highlighter.HighlightPainter JavaDoc painter = h.getPainter(); 
    String JavaDoc painterClass = painter.getClass().getName(); 
    if (painterClass.indexOf("javax.swing.text.DefaultHighlighter") != 0 && 
      painterClass.indexOf("com.sun.java.swing.plaf.windows.WindowsTextUI") != 0) { 
     return false; 
    } 
    try { 
     DefaultHighlighter.DefaultHighlightPainter JavaDoc defPainter = 
       (DefaultHighlighter.DefaultHighlightPainter JavaDoc) painter; 
     if (defPainter.getColor() != null && 
       !defPainter.getColor().equals(c.getSelectionColor())) { 
      return false; 
     } 
    } catch (ClassCastException JavaDoc e) { 
     return false; 
    } 
    return true; 
} 

Таким образом, использование цвета зависит от L & F и художник. Если вы определяете своего художника, цвет не будет использоваться.

+0

В моем случае я пытаюсь заставить цвет фактического текста вести себя по-другому, а не цвет выделения. Как если бы я выделил два слова, одно слово - черный текст, другой - красный текст. Когда выделено, я хочу, чтобы цвет текста отображался как правильный цвет, а цвет выделения оставался неизменным. Но я не нашел никаких доказательств того, что Java поддерживает 2 разных цвета выделенного текста, так как существует метод setSelectedText, который позволяет мне изменить выделенный цвет текста только на один цвет и не использовать переменные цвета. Имеет ли это смысл? – smith8ar

+0

Не могли бы вы опубликовать SSCCE с разными цветами? Для меня вы должны заменить стандартный HighlighPainter своим собственным, где вы рисуете не только фоновый, но и текст fo для выбора желаемых цветов. – StanislavL

0

Простейший способ изменить цвет выделенного текста:

int start = textPane.getSelectionStart(); 
int end = textPane.getSelectionEnd(); 
int selectedLength = end - start; 
StyleDocument style = pane.getStyledDocument(); 

//this give your attribute set of selected Text. 
AttributeSet oldSet = style.getCharacterElement(end-1).getAttributes(); 

//StyleContext for creating attribute set 
StyleContext sc = StyleContext.getDefaultStyleContext(); 

// Attribute set which contains new color with old attributes 
AttributeSet s = sc.addAttribute(oldSet, StyleConstants.Foreground, Color.RED); 
//This set the color of the Text 
style.setCharacterAttributes(start, selectedLength, s, true); 
Смежные вопросы