最近我一直在做一个Java文本编辑器项目,我想使用JTextPane
更换旧的JTextArea
以实现语法高亮。然而,一个JTextPane
缺乏方法JTextArea
(例如append()
, getLineStartOffset()
等),我想在我的课堂上重新实现它们MyTextPane
(一个子类JTextPane
)但遇到了麻烦。
我当前的代码(只有一小部分独立部分):
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class MyTextPane extends JTextPane
{
public MyTextPane()
{
super();
}
public void append(String text)
{
try
{
Document doc = this.getDocument();
doc.insertString(doc.getLength(),text,null);
}
catch (BadLocationException ex)
{
//must succeed
throw new InternalError(ex.getMessage());
}
}
public void insert(String text, int pos)
{
try
{
this.getStyledDocument().insertString(pos,text,null);
}
catch (BadLocationException ex)
{
throw new IllegalArgumentException(ex);
}
}
public void replaceRange(String str, int start, int end)
{
try
{
Document doc = this.getDocument();
doc.remove(start,end-start);
doc.insertString(start,str,null);
}
catch (BadLocationException ex)
{
throw new IllegalArgumentException(ex);
}
}
public void setLineWrap(boolean isLineWrap)
{
/*
* implements later
*/
}
public boolean getLineWrap()
{
/*
* implements later
*/
return true;
}
public void setWrapStyleWord(boolean isWrapStyleWord)
{
/*
* implements later
*/
}
public boolean getWrapStyleWord()
{
/*
* implements later
*/
return true;
}
public void setTabSize(int size)
{
/*
* implements later
*/
}
public int getTabSize()
{
/*
* implements later
*/
return 4;
}
public int getLineCount()
{
//follow JTextArea implementation
Element root = this.getDocument().getDefaultRootElement();
return root.getElementCount();
}
public int getLineStartOffset(int line) throws BadLocationException
{
//follow JTextArea implementation
int count = this.getLineCount();
Document doc = this.getDocument();
if (line < 0)
{
throw new BadLocationException("Negative line", -1);
}
if (line >= count)
{
throw new BadLocationException("No such line", doc.getLength() + 1);
}
return doc.getDefaultRootElement().getElement(line).getStartOffset();
}
public int getLineEndOffset(int line) throws BadLocationException
{
//follow JTextArea implementation
int count = this.getLineCount();
Document doc = this.getDocument();
if (line < 0)
{
throw new BadLocationException("Negative line", -1);
}
if (line >= count)
{
throw new BadLocationException("No such line", doc.getLength() + 1);
}
int end = doc.getDefaultRootElement().getElement(line).getEndOffset();
return (line==count-1)?(end-1):end;
}
public int getLineOfOffset(int off) throws BadLocationException
{
//follow JTextArea implementation
Document doc = this.getDocument();
if (off < 0)
{
throw new BadLocationException("Can't translate offset to line", -1);
}
if (off > doc.getLength())
{
throw new BadLocationException("Can't translate offset to line", doc.getLength() + 1);
}
return doc.getDefaultRootElement().getElementIndex(off);
}
public static void main(String[] args)
{
final SimpleAttributeSet BOLD_SET = new SimpleAttributeSet();
StyleConstants.setBold(BOLD_SET, true);
StyleConstants.setForeground(BOLD_SET, new Color(0,0,125));
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
MyTextPane textPane = new MyTextPane();
frame.add(new JScrollPane(textPane), BorderLayout.CENTER);
frame.setSize(200,200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
正如你所看到的,我已经添加了一些方法,例如append()
。但是,我想不出任何方法来控制换行策略。
默认行为很奇怪:当有一个短单词和一个长单词时,
如果我连续输入没有空格的字符,
它首先看起来像是用文字包裹的。然而当我继续输入字符时,
它根本不包裹。
有没有什么优雅的方法来控制 a 的包装策略JTextPane
?换句话说,可以JTextPane
像 a 一样包裹单词JTextArea
?我发现了很多重复项(例如this https://stackoverflow.com/questions/4702891/toggling-text-wrap-in-a-jtextpane, this https://stackoverflow.com/questions/7156038/jtextpane-line-wrapping and this https://stackoverflow.com/questions/14636186/jtextpane-wont-wrap)但找不到解决方案。提前致谢。