2

getListCellRendererComponent メソッドの仕組みを理解しようとしていますが、わかりません。BasicComboBoxRenderer を拡張する別のクラスを作成し、getListCellRendererComponent が呼び出されるたびに出力されるカウンターを追加しました。次に、カスタム レンダラー クラスを使用する JComboBox だけでフレームを表示する main メソッドを含むテスト クラスを実行します。このコンボボックスには合計 3 つの項目があり、setMaximumRowCount(2) を設定したので、そのうちの 2 つだけが表示されます。

  • プログラムを最初に実行し、コンボボックスを含むフレームが表示されると、カウンターは getListCellRendererComponent が 6 回呼び出されたことを通知します。
  • フレームがフォーカスを失ったとき (たとえば、デスクトップをクリックしたとき)、メソッドは 1 回実行されます。
  • フレームがフォーカスを取り戻すと (フレームをクリックして戻すと)、メソッドが 1 回実行されます。
  • 矢印ボタンをクリックしてドロップダウン リストが初めて表示されると、メソッドが 8 回実行されるとカウンターに表示されます。
  • 矢印ボタンをもう一度クリックしてリストが消えると、メソッドが 1 回呼び出されます (これは常に発生します)。
  • 初めて矢印ボタンをクリックすると、メソッドが5回呼び出されます。
  • スクロールバー ボタンをクリックして上下に移動すると、メソッドが 1 回実行されます。
  • リストの選択されていない項目にカーソルを移動すると、メソッドが2回実行され、1秒後にさらに1回実行されます(これは最もばかげています)
  • リストの項目をクリックすると、メソッドが 4 回実行されます。

最初は、このメソッドはリスト内の項目の数 (およびコンボボックスの表示領域に表示されるもう 1 つ) の数だけ実行されると思っていました。

しかし、おそらく新しいアイテムがレンダリングされるため、スクロールバーのボタンをクリックしてメソッドが 1 回実行される場合など、上記の 1 つまたは 2 つのケースしか理解できません。残りは狂っているように見える...

4

2 に答える 2

2

一度に n + 1 回のレンダラーの反復が呼び出されることを期待します。

コンポーネントは

  1. コンテンツに最適なサイズを見つけます。これは、プロトタイプ値を使用するか、何も指定されていない場合は、すべてのアイテムを反復して最大境界を見つけることで実現できます (つまり 3 回)。
  2. 選択したアイテムが存在する場合は +1 回レンダリングする
  3. ポップアップが +3 回表示されている場合は、リストをレンダリングします
  4. おそらくツールチップを探します

= 可能な 7 回の繰り返し

フォーカスを失うと、コンポーネントは選択された項目を +1 レンダリングする必要があります

フォーカスを取り戻すと、コンポーネントは選択されたアイテムを再度レンダリングしようとします +1

ポップアップが表示されたら、最初の部分を参照してください

2 回目は、コンポーネントが最初のポップアップ アクションの結果をキャッシュしたことを示している可能性があります (コンポーネントがフォーカス イベント間で内部キャッシュを無効にしている可能性があります)。

スクロールペインのビューを変更するたびに、以前に画面に表示されていなかったアイテムをレンダリングする必要があります。これは、最適化のために行われます (数百のアイテムを持つ lst を想像してみてください。それらすべてをレンダリングするのは時間の無駄です。したがって、プロトタイプ値を含む)

マウス アクションは、一連の異なるアクション (マウス イン、マウス アウト、マウス移動) をトリガーすることができます。最も可能性が高いのは、ツールヒントが利用可能かどうかを判断しようとするツールヒント マネージャとコンポーネントに関係しています。

プロトタイプ値を設定してみて、コンポーネントがポップアップを表示するときの反復回数が変わるかどうかを確認してください

于 2012-07-11T20:36:43.510 に答える
1
  1. Object(s)で作成または再作成する方法と方法を説明するのを忘れたと思いますRenderer

  2. SSCCEフォームRendererであなたの意見をここに送信するのを忘れました

  3. それなら、すべてがアカデミックレベルで、あなたについて何かを書くのは難しすぎますRenderer...

  4. RenderereveryMouseおよびKeyeventsに反応する

  5. Rendererすべての重要なメソッドからの出力をプレーンにSystem.out.println("yyyy")

.

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();
            }
        });
    }
}
于 2012-07-11T21:10:40.747 に答える