Изменение цвета выделенного текста в jTextPane
Я создаю текстовый редактор с использованием JTextPane, который позволяет пользователю изменять цвет выделенного текста. Но когда пользователь выбирает текст, затем выбирает опцию изменения цвета (скажем, на красный), текст не отображается красным, пока текст не будет выделен. Я пытался использовать setSelectedTextColor, чтобы изменить цвет выделенного текста, но это не работает, поскольку при каждом выборе текста текст меняется на красный. Есть ли способ, чтобы выбранный текст отображался как его фактический цвет? Или как в Word, где это не фактический цвет текста, но при выделении текста разных цветов они отображаются разными цветами, даже если они выделены.
Я использую следующий код для настройки 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);
Дайте мне знать, если вам нужно больше исходного кода, чтобы понять вопрос. Благодарю вас!
5 ответов
Посмотрите на 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()
, В методе просто проверьте, выделен ли текст, и используйте атрибуты выбранных элементов, чтобы получить желаемый цвет. Если ничего не выбрано, просто верните super.getSelectedColor()
ОБНОВЛЕНИЕ: На самом деле применение цветов для выделения используется на общедоступной пустотной краске GlyphView (Graphics g, Shape a) {... JTextComponent tc = (JTextComponent) c; Color 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 (highlight, tc).
В источниках 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 и художника. Если вы определите своего нового художника, цвет не будет использоваться.
Похоже, что вы можете использовать что-то, кроме имени семейства шрифтов. Я пересмотрел этот пример, чтобы использовать JTextPane
и увидел ожидаемый результат. Как отмечено там, действия требуют названия семейства шрифтов, например, по умолчанию или face=SansSerif
как указано в FontFamilyAction
класс, вложенный в StyledEditorKit
,
JTextPane textPane = new JTextPane();
Самый простой способ изменить цвет выделенного текста:
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);
Добавляю свой взгляд. Это может быть еще проще, чем описанные выше подходы.
JEditorPane ep = new JEditorPane() {
@Override
public Color getSelectionColor() {
return COLOR_YOU_WANT;
}
@Override
public Color getSelectedTextColor() {
return COLOR_YOU_WANT;
}
};
Я думаю, что вы ищете то, что я ищу здесь, спустя 9 лет после вашего вопроса; в принципе не иметьselectedTextColor
. Я нигде не нашел решения, но в отчаянии попробовал следующее:
JTextPane thePane = ...;
thePane.setSelectedTextColor(null);
И это просто работает! Фон выделенного текста изменен наselectionColor
, но текстовые буквы сохраняют исходный цвет переднего плана. Я пишу собственный маркер кода, поэтому мне нужно, чтобы он сохранял основные моменты (применяется через диапазоны HTMLDocument с классом CSS). Это выглядит так: