Я пытаюсь в течение более 2 дней реализовать конкретное требование для окна текстового редактора ... к сожалению, пока безуспешно: (
Цель - получить окно текстового редактора, которое выделиттекущая строка, как это делают другие текстовые редакторы. Под текущей строкой я подразумеваю строку, в которой в данный момент расположен курсор / каретка.
Я уже нашел два разных подхода, но, к сожалению, я не могу принять их, поэтому ониработать как ожидалось.
Первый подход заключается в перезаписи DefaultHighlighter
(http://snippets.dzone.com/posts/show/6688).. Во втором подходе вместо него будет перезаписан HighlighterPainter
(http://www.jroller.com/santhosh/date/20050622).
Rightсейчас я пытаюсь принять первый подход в своем проекте, но, как я уже сказал, он не работает должным образом.
В конце этого поста я публикую небольшой пример приложения, демонстрирующего проблему.
- Если я запускаю программу, каретка ставится в начале первой строки, однако строка не подсвечивается.
- Теперь я набираю некоторые персонажи.Эти символы будут выделены, но только те символы, которые не являются полной строкой
- Я нажимаю Enter, чтобы перейти к следующей строке.Первая строка больше не подсвечивается, что правильно.Вторая строка также не выделена, что не правильно.Опять же, когда я набираю некоторые символы, они будут выделены, но не всей строкой.
- Когда я сейчас переместу каретку на первую строку, либо клавишей курсора вверх или щелчком мыши, полная первая строкабудут выделены не только существующие символы.Это поведение, которое я хочу с самого начала.
Я надеюсь, что кто-нибудь может сказать мне, что я делаю здесь неправильно ... или объяснить, почему вообще невозможно решить эту проблему.Любые альтернативные решения, как я мог бы реализовать подсветку линии, также высоко ценятся!
Заранее большое спасибо Cheers Preachie
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
public class HighlightProblem extends JFrame {
private static final long serialVersionUID = 1L;
private final JTextPane textPane;
private final Highlighter.HighlightPainter cyanPainter;
public HighlightProblem() {
cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.CYAN);
textPane = new JTextPane();
textPane.setPreferredSize(new Dimension(500, 300));
textPane.setHighlighter(new LineHighlighter());
textPane.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
setHighlight(e);
}
});
getContentPane().add(textPane);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
new HighlightProblem();
}
public void setHighlight(CaretEvent e) {
textPane.getHighlighter().removeAllHighlights();
int currentLine = getLineFromOffset(textPane, e.getDot());
int startPos = getLineStartOffsetForLine(textPane, currentLine);
int endOffset = getLineEndOffsetForLine(textPane, currentLine);
try {
textPane.getHighlighter().addHighlight(startPos, endOffset, cyanPainter);
} catch (Exception ex) {
ex.printStackTrace();
}
textPane.repaint();
}
public int getLineFromOffset(JTextComponent component, int offset) {
return component.getDocument().getDefaultRootElement().getElementIndex(offset);
}
public int getLineStartOffsetForLine(JTextComponent component, int line) {
return component.getDocument().getDefaultRootElement().getElement(line).getStartOffset();
}
public int getLineEndOffsetForLine(JTextComponent component, int line) {
return component.getDocument().getDefaultRootElement().getElement(line).getEndOffset();
}
public class LineHighlighter extends DefaultHighlighter {
private JTextComponent component;
@Override
public final void install(final JTextComponent c) {
super.install(c);
this.component = c;
}
@Override
public final void deinstall(final JTextComponent c) {
super.deinstall(c);
this.component = null;
}
@Override
public final void paint(final Graphics g) {
final Highlighter.Highlight[] highlights = getHighlights();
final int len = highlights.length;
for (int i = 0; i < len; i++) {
Highlighter.Highlight info = highlights[i];
if (info.getClass().getName().indexOf("LayeredHighlightInfo") > -1) {
// Avoid allocing unless we need it.
final Rectangle a = this.component.getBounds();
final Insets insets = this.component.getInsets();
a.x = insets.left;
a.y = insets.top;
// a.width -= insets.left + insets.right + 100;
a.height -= insets.top + insets.bottom;
final Highlighter.HighlightPainter p = info.getPainter();
p.paint(g, info.getStartOffset(), info.getEndOffset(), a, this.component);
}
}
}
@Override
public void removeAllHighlights() {
textPane.repaint(0, 0, textPane.getWidth(), textPane.getHeight());
super.removeAllHighlights();
}
}
}