我必须将样式文本转换为包装的简单文本(用于SVG自动换行)。我无法相信,JTextArea
无法提取包装信息(包含多少行,哪些是换行符)。所以我创建了一个小框架程序:
package bla;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTextArea;
public class Example1 extends WindowAdapter {
private static String content = "01234567890123456789\n" + "0123456 0123456 01234567 01234567";
JTextArea text;
public Example1() {
Frame f = new Frame("TextArea Example");
f.setLayout(new BorderLayout());
Font font = new Font("Serif", Font.ITALIC, 20);
text = new JTextArea();
text.setFont(font);
text.setForeground(Color.blue);
text.setLineWrap(true);
text.setWrapStyleWord(true);
f.add(text, BorderLayout.CENTER);
text.setText(content);
// Listen for the user to click the frame's close box
f.addWindowListener(this);
f.setSize(100, 511);
f.show();
}
public static List<String> getLines( JTextArea text ) {
//WHAT SHOULD I WRITE HERE
return new ArrayList<String>();
}
public void windowClosing(WindowEvent evt) {
List<String> lines = getLines(text);
System.out.println( "Number of lines:" + lines.size());
for (String line : lines) {
System.out.println( line );
}
System.exit(0);
}
public static void main(String[] args) {
Example1 instance = new Example1();
}
}
如果你运行它,你会看到:
我期望输出:
Number of lines:6
0123456789
0123456789
0123456
0123456
01234567
01234567
我应该写什么来代替评论?
那么,基于接受的答案的完整解决方案实际上没有显示框架(注意,你应该从结果中删除实际的换行符):
package bla;
import java.awt.Color;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.swing.text.Utilities;
public class Example1 {
private static String content = "01234567890123456789\n" + "0123456 0123456 01234567 01234567";
public static List<String> getLines( String textContent, int width, Font font ) throws BadLocationException {
JTextArea text;
text = new JTextArea();
text.setFont(font);
text.setForeground(Color.blue);
text.setLineWrap(true);
text.setWrapStyleWord(true);
text.setText(content);
text.setSize(width, 1);
int lastIndex = 0;
int index = Utilities.getRowEnd(text, 0);
List<String> result = new ArrayList<String>();
do {
result.add( textContent.substring( lastIndex, Math.min( index+1, textContent.length() ) ) );
lastIndex = index + 1;
}
while ( lastIndex < textContent.length() && ( index = Utilities.getRowEnd(text, lastIndex) ) > 0 );
return result;
}
public static void main(String[] args) throws BadLocationException {
Font font = new Font("Serif", Font.ITALIC, 20);
Example1 instance = new Example1();
for (String line : getLines(content,110,font)) {
System.out.println( line.replaceAll( "\n", "") );
}
}
}
在我身上打开问题(不是那么重要),为什么宽度为100px且包含jtextarea的框架比没有框架的jtextarea包含文本的宽度相同。这个想法?
答案 0 :(得分:3)
JTextArea
不支持样式文本,但它确实支持对其模型PlainDocument
的面向行的访问,如下所示。供参考,
Frame
)和Swing(JTextArea
)组件。getLineCount()
方法计算line.separator
分隔线,而非包裹线。BasicTextUI
处理Look&amp;感觉依赖渲染;方法viewToModel()
和viewToModel()
在两个坐标系之间进行转换。控制台:
01234567890123456789 0123456 0123456 01234567 01234567
代码:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
public class Example2 {
private static final Character SEP = Character.LINE_SEPARATOR;
private static String content = ""
+ "01234567890123456789" + SEP
+ "0123456 0123456" + SEP
+ "01234567 01234567";
private JTextArea text;
public Example2() {
JFrame f = new JFrame("TextArea Example");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Font font = new Font("Serif", Font.ITALIC, 20);
text = new JTextArea(4, 8);
text.setFont(font);
text.setForeground(Color.blue);
text.setLineWrap(true);
text.setWrapStyleWord(true);
text.setText(content);
f.add(new JScrollPane(text));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
for (String s : getLines(text)) {
System.out.println(s);
}
}
private List<String> getLines(JTextArea text) {
PlainDocument doc = (PlainDocument) text.getDocument();
List<String> list = new ArrayList<String>();
for (int i = 0; i < text.getLineCount(); i++) {
try {
int start = text.getLineStartOffset(i);
int length = text.getLineEndOffset(i) - start;
list.add(doc.getText(start, length));
} catch (BadLocationException ex) {
ex.printStackTrace(System.err);
}
}
return list;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Example2 instance = new Example2();
}
});
}
}
答案 1 :(得分:2)
JTextArea确实有:getLines() method,这不适合你吗?
答案 2 :(得分:2)
使用Utilities.getRowEnd() 将0作为起始偏移,然后将前一行的结束偏移+1