我試圖超過2天實現對文本編輯器窗口中的具體要求......可惜沒有成功,到目前爲止:(突出顯示當前行中的JTextPane
的目標是獲得一個文本編輯器窗口這將突出顯示當前行,就像其他文本編輯器一樣。對於當前行,我指的是當前光標/光標所在的行。
我已經找到了兩種不同的方法,但不幸的是我無法採用它們他們按預期工作
第一種方法是覆蓋DefaultHighlighter
(http://snippets.dzone.com/posts/show/6688)。 在第二種方法中,HighlighterPainter
將被覆蓋,而不是(http://www.jroller.com/santhosh/date/20050622)。
現在我正試圖在我的項目中採用第一種方法,但正如我所說的那樣,它不能按需要工作。
在本文末尾,我發佈了一個小示例應用程序,演示了這個問題。
- 如果我啓動該程序,插入符號將被放置在第一行的開頭。但是,該行不突出顯示。
- 現在我輸入一些字符。那些字符將突出顯示,但只有那些字符不是完整的行
- 我按Enter鍵移動到下一行。第一行不再突出顯示什麼是正確的。第二行也沒有突出顯示,什麼是不正確的。再次,當我輸入一些字符時,這些字符會被加亮,但不是完整的字符。
- 當我現在將插入符號移回第一行時,無論是通過向上鍵還是鼠標單擊,完整的第一行都將突出顯示,而不僅僅是現有的字符。這是我從一開始就想要的行爲。
我希望任何人都可以告訴我在這裏做錯了什麼......或者解釋爲什麼根本無法解決這個問題。任何替代解決方案我如何能夠實現突出顯示的行也非常感謝!
感謝很多提前 乾杯 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();
}
}
}
非常感謝......它看起來真的很喜歡它的工作就像一個魅力。 – Preachie 2011-03-23 14:35:08
不客氣。 :) – spedsal 2011-03-23 14:42:52