Могут ли другие методы использовать область просмотра JScrollPane?

Кажется, что единственный способ отобразить текст с несколькими стилями в текстовой области - это использовать JEditorPane. Чтобы изучить это, я написал небольшое приложение, чтобы перечислить все шрифты в их шрифте.

Все работает, и список отображается в JEditorPane, который находится внутри JScrollPane.

Однако для запуска и повторного заполнения требуется несколько секунд, поскольку перед его отображением создается весь новый список. Код ниже, следующий за MCV. Сведение к минимуму только сообщения и текста сделало меньше работы, поэтому задержка уже не так заметна, но мой вопрос (ниже) был больше о рендеринге и отслеживании положения JScrollPane, чем об этом приложении.

FontFrame.java

public class FontFrame extends JFrame {
    private FontFrame() {
        JFrame frame = new JFrame("Fonts Displayer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        FontPanel fontPanel = new FontPanel();
        frame.getContentPane().add(fontPanel);
        frame.getRootPane().setDefaultButton(fontPanel.getDefaultButton());

        frame.setMinimumSize(new Dimension(600, 600));
        frame.setPreferredSize(new Dimension(1000, 700));
        frame.pack();
        frame.setVisible(true);
    }


    public static FontFrame launchFontFrame() {
        return new FontFrame();
    }

    public static void main(String[] args) {
        FontFrame.launchFontFrame();
    }
}

FontPanel.java

class FontPanel extends JPanel {
    private String message = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz";

    private JEditorPane fontPane;
    private JTextField messageInput;
    private JButton changeButton;

    protected FontPanel() {
        buildPanel();
    }

    private void buildPanel() {
        setLayout(new BorderLayout());

        // Build message input panel
        JPanel inputPanel = new JPanel();
        messageInput = new JTextField(message);
        messageInput.setFont(new Font("SansSerif", Font.PLAIN, 14));
        messageInput.setColumns(40);

        JLabel messageLabel = new JLabel("Message:");

        changeButton = new JButton("Change");
        changeButton.addActionListener((ActionEvent e) -> {
            String text = messageInput.getText();
            if (!text.isEmpty() && !text.equals(message)) {
                message = text;
                refreshFontList();
            }
        });

        inputPanel.add(messageLabel);
        inputPanel.add(messageInput);
        inputPanel.add(changeButton);


        // Build scrolling text pane for fonts display
        fontPane = new JEditorPane();
        fontPane.setContentType("text/html");
        fontPane.setEditable(false);
        fontPane.setVisible(true);
        JScrollPane scrollPane = new JScrollPane(fontPane);
        refreshFontList();

        // Add components to main panel
        add(inputPanel, BorderLayout.NORTH);
        add(scrollPane, BorderLayout.CENTER);
    }


    private void refreshFontList() {
        String[] list = GraphicsEnvironment.getLocalGraphicsEnvironment()
                                                .getAvailableFontFamilyNames();
        StringBuilder messages = new StringBuilder();

        // Set global table style settings
        messages.append("<table>");

        // Make a row for each font
        for (String font : list) {
            messages.append("<tr>");

            //Append data cells
            messages.append("<td>").append(font).append("</td>")
                    .append("<td style=\"font-family:").append(font).append("\">")
                        .append(message)
                    .append("</td>");

            messages.append("</tr>");
        }

        messages.append("</table>");

        fontPane.setText(messages.toString());
    }

    JButton getDefaultButton() {
        return changeButton;
    }
}

Есть ли способ переделать refreshFontList так что он может генерировать только то, что fontPane будет сначала показываться в своем окне просмотра, возможно, с помощью JScrollBar, а затем генерировать оставшуюся часть списка сразу после этого, чтобы время вычислений не вызывало задержки при отображении? Есть ли другой компонент, который будет работать лучше?

0 ответов

Другие вопросы по тегам