其他方法可以使用JScrollPane的视口吗?

时间:2017-04-28 16:01:17

标签: java swing user-interface jscrollpane jscrollbar

似乎在文本区域中显示具有多个样式的文本的唯一方法是使用JEditorPane。为了探索这个,我写了一个小应用程序列出其字体中的所有字体。

一切正常,列表显示在JSdrollPane内的JEditorPane中。

但是,启动和重新填充需要几秒钟,因为它会在显示之前生成整个新列表。代码如下,遵循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 个答案:

没有答案