似乎在文本区域中显示具有多个样式的文本的唯一方法是使用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,然后在计算之后立即生成列表的其余部分时间不会导致显示滞后?是否有一个不同的组件可以更好地工作?