我有一个问题,在给定固定宽度的情况下,如何轻松计算JTextPane的首选大小/高度。到目前为止,我所做的是将我的JTextPane放在JScrollPane中,每当我更新文本时,我都会更新JScrollPane的大小。现在,这很有效(尽管我发现我的代码有点扭曲,但它很有效),但当我添加新行时,我的更新滚动窗格高度的代码需要调用两次:一次立即调用,第二次使用invokeLater
调用。我正在寻找避免invokeLater()
的方法。任何事情都可以,包括在组件上调度事件、重写Swing方法等。
以下是说明这一切的狙击手:
import java.awt.AWTEvent;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class Test {
private static MyEventQueue queue;
private static final class MyEventQueue extends EventQueue {
public boolean log = false;
@Override
protected void dispatchEvent(AWTEvent event) {
if (log) {
System.err.println(event.getClass().getName() + " " + event.getSource());
}
super.dispatchEvent(event);
}
}
public static class WrapApp extends JFrame {
JTextPane edit = new JTextPane() {
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
};
private JScrollPane comp;
protected void updateVPSize() {
updateSize(true);
}
protected void updateSize(boolean repeat) {
edit.setSize(150, 1000);
Dimension size = edit.getPreferredScrollableViewportSize();
System.err.println("Before " + size);
size.width = 150;
comp.setSize(size);
if (repeat) {
queue.log = true;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
queue.log = false;
updateSize(false);
}
});
}
}
public WrapApp() {
super("Forced wrap/no wrap example");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(null);
edit.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
updateVPSize();
}
@Override
public void insertUpdate(DocumentEvent e) {
updateVPSize();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateVPSize();
}
});
comp = new JScrollPane(edit) {
@Override
public void setSize(int width, int height) {
super.setSize(width, height);
};
};
comp.setBorder(null);
comp.setLocation(0, 0);
comp.setViewportBorder(null);
comp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
edit.setText("Some long text that needs to be wrapped on several lines.nnBut this is not the end of it, it can go on and on and on and on...Some long text that needs to be wrapped on several lines.nnBut this is not the end of it, it can go on and on and on and on...");
getContentPane().add(comp);
setSize(300, 700);
setLocationRelativeTo(null);
updateVPSize();
}
}
public static void main(String[] args) {
Toolkit.getDefaultToolkit().getSystemEventQueue().push(queue = new MyEventQueue());
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
WrapApp m = new WrapApp();
m.setVisible(true);
}
});
}
}
不要介意里面剩下的所有东西,我试了很多东西
试试这个http://java-sl.com/tip_text_height_measuring.html