JTextPane предпочтительный размер с фиксированной шириной - PullRequest
4 голосов
/ 26 марта 2012

У меня есть вопрос о том, как можно легко вычислить предпочтительный размер / высоту 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.\n\nBut 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.\n\nBut 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);

            }
        });
    }

}

Не обращайте внимания на всевещи остались там, я попробовал кучу вещей

1 Ответ

4 голосов
/ 26 марта 2012
...