Могут ли другие методы использовать область просмотра 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, а затем генерировать оставшуюся часть списка сразу после этого, чтобы время вычислений не вызывало задержки при отображении? Есть ли другой компонент, который будет работать лучше?