1

我必须将样式文本转换为包装的简单文本(用于 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", "") );
        }
    }

} 

我的开放性问题(不是那么重要),为什么包含 jtextarea 的 100px 宽度的框架比没有具有相同宽度的框架的 jtextarea 更晚地包装文本。对此有什么想法?

4

3 回答 3

3

JTextArea不支持带样式的文本,但它确实支持对其模型的面向行的访问PlainDocument,如下所示。以供参考,

  • 不要不必要地混合 AWT ( Frame) 和 Swing ( ) 组件。JTextArea
  • Swing GUI 对象应该事件分派线程上构建和操作。
  • 如此处所述,该getLineCount()方法计算line.separator分隔行,而不是换行。
  • BasicTextUI处理外观和感觉相关的渲染;方法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();
            }
        });
    }
}
于 2012-06-02T00:40:14.587 回答
2

JTextArea 确实有一个 : getLines() 方法,这对你不起作用吗?

于 2012-06-01T23:51:42.167 回答
2

使用 Utilities.getRowEnd() 传递 0 作为起始偏移量,然后是上一行的结束偏移量 +1

于 2012-06-02T15:06:21.807 回答