gpt4 book ai didi

java - 如何防止 JComboBox 在使用自定义 ListCellRenderer 时变得无响应

转载 作者:行者123 更新时间:2023-11-30 09:49:16 28 4
gpt4 key购买 nike

我正在使用 JComboBox 和自定义 ListCellRenderer 制作字体选择器。我想JComboBox 显示所有可用字体,每个字体名称以其自己的字体显示。我目前使用大约 500 种字体。

提供此功能的 ListCellRenerer 示例:

private class ComboBoxRenderer extends JLabel implements ListCellRenderer {

private JLabel label = new JLabel("Test");

@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {

Font tempFont = label.getFont();
setFont(new Font((String) value, tempFont.getStyle(),
tempFont.getSize()));

setText((String) value);

return this;
}
}

问题是,当使用此渲染器时,JComboBox 在程序执行期间变得无响应。第一次单击组合框以显示列表时,加载列表需要几秒钟。第二次点击,列表立即显示。

如果有人评论该行

setFont(new Font((String) value, tempFont.getStyle(),tempFont.getSize()));

,组合框工作得很好。

如何防止这种 react 迟钝?

最佳答案

发生的是组合的内部尝试动态地找到首选大小。为此,它循环遍历列表中的所有项目,为渲染器提供项目以测量渲染组件的首选大小。

您可以通过设置用于测量的原型(prototype)值来防止这种情况,然后使用该原型(prototype)测量一次尺寸

 comboBox.setPrototypeDisplayValue(sampleFont);

编辑:正如@Boro 检测到的那样,这还不够——它只为组合框本身设置原型(prototype),而不是为弹出窗口中的列表设置原型(prototype)(它应该如此,这有多么疯狂……可能)。要破解,我们必须手动设置它,这里有一个代码片段可以玩

public class ComboWithPrototype {

private JComponent createContent() {
final Font[] systemFonts = GraphicsEnvironment
.getLocalGraphicsEnvironment().getAllFonts();

final JComboBox box = new JComboBox();
box.setRenderer(new ComboBoxRenderer());
box.setPrototypeDisplayValue(systemFonts[0]);
Accessible a = box.getUI().getAccessibleChild(box, 0);
if (a instanceof javax.swing.plaf.basic.ComboPopup) {
JList popupList = ((javax.swing.plaf.basic.ComboPopup) a).getList();
// route the comboBox' prototype to the list
// should happen in BasicComboxBoxUI
popupList.setPrototypeCellValue(box.getPrototypeDisplayValue());
}
Action action = new AbstractAction("set model") {

@Override
public void actionPerformed(ActionEvent e) {
box.setModel(new DefaultComboBoxModel(systemFonts));
}
};
JComponent panel = new JPanel(new BorderLayout());
panel.add(box);
panel.add(new JButton(action), BorderLayout.SOUTH);
return panel;
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ComboWithPrototype().createContent());
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
});
}

自定义 ListCellRenderer(略有更改,期望字体类型的项目)

private class ComboBoxRenderer extends DefaultListCellRenderer {

private Font baseFont = new JLabel("Test").getFont();

@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {

super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
if (value instanceof Font) {

Font font = (Font) value;
setFont(new Font(font.getName(), baseFont.getStyle(), baseFont.getSize()));
setText(font.getName());
}

return this;
}
}

关于java - 如何防止 JComboBox 在使用自定义 ListCellRenderer 时变得无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5896282/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com