调用getListCellRendererComponent多少次?

时间:2012-07-11 19:52:39

标签: java swing jcombobox listcellrenderer

我试图理解getListCellRendererComponent方法是如何工作的,但是我没理解。我创建了一个扩展BasicComboBoxRenderer的独立类,我添加了一个计数器,每次调用getListCellRendererComponent时都会打印一个。然后我运行一个带有main方法的测试类,该方法显示一个框架,其中只有一个使用我的自定义渲染器类的JComboBox。这个组合框总共有3个项目,我设置了setMaximumRowCount(2),所以它只显示了2个。

  • 当我第一次运行程序并出现带有组合框的框架时,计数器会通知getListCellRendererComponent被调用6次。
  • 当框架失去焦点时(例如,当我点击我的桌面时),该方法执行1次。
  • 当框架重新获得焦点时(单击我的框架上),该方法将执行1次。
  • 当我点击箭头按钮并且第一次出现下拉列表时,计数器表示该方法执行了8次。
  • 当我再次点击箭头按钮并且列表消失时,该方法被称为1次(这种情况总是发生)。
  • 当我第一次点击箭头按钮后,该方法被调用5次。
  • 当我点击滚动条按钮上下移动时,该方法执行1次。
  • 当我将光标移动到列表中未选中的项目时,该方法执行2次,之后再执行1次(这是最荒谬的)
  • 当我点击列表中的某个项目时,该方法会执行4次。

起初我认为这个方法将被执行的次数与列表中项目的数量一样多(再加上组合框显示区域中的一个项目)。

但我只能理解上面的一两个案例,例如当我点击滚动条按钮并且该方法执行一次时,可能是因为渲染了一个新项目。其余的人似乎疯了......

2 个答案:

答案 0 :(得分:1)

我希望在任何时候都可以调用渲染器的n + 1次迭代。

该组件需要

  1. 找出内容的最佳尺寸。这可以通过使用原型值来实现,或者,如果没有指定,则迭代遍历所有项目以找到最大边界(这是3次)
  2. 如果存在+1次
  3. ,则渲染所选项目
  4. 如果弹出窗口可见+3次
  5. ,则渲染列表
  6. 可能寻找工具提示
  7. =可能的7次迭代

    当失去焦点时,组件需要呈现所选项目+1

    重新获得焦点时,组件将再次尝试渲染选定项目+1

    显示弹出窗口时,请参阅第一部分

    第二次可能表示组件缓存了第一个弹出操作的结果(组件可能使焦点事件之间的内部缓存无效)

    每次更改滚动窗格的视图时,都需要渲染之前未在屏幕上显示的任何项目,这是出于优化原因(想象一下有100个项目的lst,渲染所有这些都是浪费时间) ,因此包含原型值)

    鼠标操作可以触发一系列不同的操作,鼠标输入,鼠标移出,鼠标移动。最可能的是这些与工具提示管理器和组件有关,试图确定工具提示是否可用

    尝试设置原型值&看看当组件显示弹出窗口时是否会改变迭代次数

答案 1 :(得分:1)

  1. 我认为您忘记在Object(s)

  2. 中描述您创建或重新创建Renderer的方式和方式
  3. 您忘了在SSCCE表单

  4. 中发送了关于Renderer的观点
  5. 然后一切都处于学术水平,而且很难写出关于你的Renderer ...

  6. Renderer对每个MouseKey事件作出反应

  7. 普通Renderer,其中包含所有重要方法的输出System.out.println("yyyy")

  8. import java.awt.Component;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    import javax.swing.plaf.basic.BasicComboBoxRenderer;
    
    public class ComboBoxHoverOver {
    
        private JComboBox combo = new JComboBox();
    
        public ComboBoxHoverOver() {
            combo.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXX");
            combo.setRenderer(new ComboToolTipRenderer(combo));
            combo.addItemListener(new ItemListener() {
    
                @Override
                public void itemStateChanged(ItemEvent e) {
                    System.out.println("itemStateChanged");
                }
            });
            combo.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("actionPerformed");
                }
            });
            combo.addItem("");
            combo.addItem("Long text 4");
            combo.addItem("Long text 3");
            combo.addItem("Long text 2");
            combo.addItem("Long text 1");
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(combo);
            f.pack();
            f.setVisible(true);
        }
    
        private class ComboToolTipRenderer extends BasicComboBoxRenderer {
    
            private static final long serialVersionUID = 1L;
            private JComboBox combo;
            private JList comboList;
    
            ComboToolTipRenderer(JComboBox combo) {
                this.combo = combo;
            }
    
            @Override
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                System.out.println(value + ", " + index + ", " + isSelected + ", " + cellHasFocus);
                if (comboList == null) {
                    comboList = list;
                    KeyAdapter listener = new KeyAdapter() {
    
                        @Override
                        public void keyReleased(KeyEvent e) {
                            if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_UP) {
                                int x = 5;
                                int y = comboList.indexToLocation(comboList.getSelectedIndex()).y;
                                System.out.println("keyReleased " + comboList.getSelectedIndex());
                            }
                        }
                    };
                    combo.addKeyListener(listener);
                    combo.getEditor().getEditorComponent().addKeyListener(listener);
                    comboList.addListSelectionListener(new ListSelectionListener() {
    
                        public void valueChanged(ListSelectionEvent e) {
                            if (e.getValueIsAdjusting()) {
                                JList list = (JList) e.getSource();
                                int item = list.getSelectedIndex();
                                if (item > -1) {
                                    String string = list.getSelectedValue().toString();
                                    System.out.println("valueChanged " + list.getSelectedValue().toString());
                                }
                            }
                        }
                    });
                }
                if (isSelected) {
                    System.out.println("isSelected " + value.toString());
                }
                return this;
            }
        }
    
        public static void main(String[] args) {
    
            java.awt.EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    ComboBoxHoverOver comboBoxHoverOver = new ComboBoxHoverOver();
                }
            });
        }
    }