当前位置: 首页 > 面试题库 >

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

葛书
2023-03-14
问题内容

我正在使用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()));

,组合框就可以了。

如何防止这种反应迟钝?


问题答案:

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

您可以通过设置用于测量的prototypeValue来防止这种情况,然后使用该原型对尺寸进行一次测量

 comboBox.setPrototypeDisplayValue(sampleFont);

编辑:正如@Boro检测到的那样,这还不够-
它仅为comboBox本身设置原型,而不是为弹出列表中的列表设置原型(应如此,这可能是多么疯狂的错误……)。要破解,我们必须手动设置它,这是一个可使用的代码

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(稍作更改,以期待Font类型的项目)

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;
    }
}


 类似资料:
  • 问题 如何使用自定义中间件在调用下一个上下文时获取响应正文? 到达await _next行后。从调试中调用(上下文); 不从操作结果返回 JSON 数据 获取用户菜单 我需要从上面的操作结果中得到响应体。 我的代码我试试: https://i.stack.imgur.com/PHUMs.png 当有效令牌时,它会在浏览器谷歌上返回如下数据 但在我的应用程序浏览器上返回无效令牌

  • 我目前正在开发一个JComboBox组件,我希望在其中的组合框中有一个JTable用于下拉选择。我扩展了ListCellRenderer,并且在弹出窗口中有一个表。 我想用两种不同的方式来呈现。第一个作为所选行的绑定列的标签,当弹出窗口不可见时。第二种是在弹出窗口可见时用JScrollPane显示表。 不幸的是,当我这样做时,弹出窗口被缩小到列表的行高,这只为表的列留下了空间。 如果我只是使用滚动

  • 问题内容: 这是一个非常常见的问题,但我尚未找到我要寻找的确切问题和答案。 我有一个表,该表具有指向其自己的PK的FK,以启用任意深度的层次结构,例如经典的tblEmployee,它的列是带有PK tblEmployee.EmployeeID的FK。 假设在我的应用中,用户 创建新员工Alice和Dave,没有经理,因为他们是CEO和总裁。这两个记录的NULL也是如此。 创建新员工Bob,并以Al

  • 我正在Azure API管理的一个实例中配置入站策略。 我想发送请求策略是有效的,结果存储在变量中。然后我想返回一个响应(仍然在入站中,当试图在出站中这样做时,我得到了500): 我的问题是它不起作用...它只是呈现。 也是如此: null 我的问题是:如何将我声明的变量添加到响应中?

  • 我正在使用react js和socket编写聊天应用程序。io库。 我订阅事件形成服务器并发出一些事件的所有逻辑都写在自定义钩子的使用效果中。 然后我从这个自定义钩子返回我需要的所有数据,并在我需要的组件中重用它。但是,我意识到,每次我将此自定义钩子导入到外部组件时,都会调用在use效应中编写的逻辑。 如果我将所有逻辑放在useEffect之外,调用它的次数甚至比导入自定义钩子的次数还要多。 如果

  • 问题内容: 我确实获得了响应数据,但是无法获得自定义HTTP标头数据。 是的,这是一个跨域请求。我正在用Javascript执行Ajax请求。我已经尝试过XMLHttpRequest和jQuery $ .ajax。我已经完成了服务器设置,在发送数据时已进行了以下设置: 我 确实 得到了想要的响应数据。但是我无法获得完整的HTTP标头响应。 使用PHP,我在发送文本响应之前设置了以下内容。因此,我假