3

多くの要素が取り込まれた Jlist を実装しています。各要素は画像に対応しているので、リストの各行内にサイズ変更されたプレビューを表示したいと思います。Jlabelを拡張するカスタムImageCellRendererを実装しました。 getListCellRendererComponentで、その要素に何もない場合はサムネイルを作成します。各行は、画像のパスと JLabel に適用されるアイコンを格納するPageクラスに対応します。PageオブジェクトはDefaultListModel内に配置され、JList に入力されます。レンダリング コードは次のようなものです。

        public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus)
    {
        Page page = (Page) value;

        if (page.getImgIcon() == null)
        {
            System.out.println(String.format("Creating thumbnail of %s", page.getImgFilename()));
            ImageIcon icon = new ImageIcon(page.getImgFilename());

            int thumb_width = icon.getIconWidth() > icon.getIconHeight() ? 128 : ((icon.getIconWidth() * 128) / icon.getIconHeight());
            int thumb_height = icon.getIconHeight() > icon.getIconWidth() ? 128 : ((icon.getIconHeight() * 128) / icon.getIconWidth());
            icon.setImage(getScaledImage(icon.getImage(), thumb_width, thumb_height));

            page.setImgIcon(icon);
        }

        setIcon(page.getImgIcon());

    }

セルレンダラーが呼び出されるリストで特定のアイテムのみが表示されると考えていましたが、ページオブジェクトをリストモデルに追加すると、すべてのサムネイルが作成されることがわかりました。アイテムをロードしようとしましたが、モデルを JList に設定した後、または最初にモデルを設定し、アイテムの追加を開始しましたが、結果は同じです。必要な場合にのみデータをロードする方法はありますか、それとも、各要素の可視性をチェックする内部に項目が積み重ねられた JScrollPanel のようなカスタム コントロールを作成する必要がありますか?

ありがとう

4

2 に答える 2

3

リストの適切なサイズを決定するために、JList はすべての項目をループし、レンダラーを呼び出すと思います。

setPrototypeCellValue(...) メソッドを使用すると、これを防ぐことができる場合があります。もちろん、スクロール ペインに表示されるすべてのアイテムに対してレンダラーが呼び出されます。

于 2009-11-02T17:57:18.300 に答える
1

犯人BasicListUIはその中にいるようupdateLayoutState()です。dataModelペイント操作中、updateLayoutStateNeededフラグが設定されると(そして、すべてのプロパティが変更された後、および間隔が追加および削除されたときに設定されます)、内部の各要素を繰り返し処理しますdataModel。各セルで、getListCellRendererComponentメソッドが呼び出され、アイコンが読み込まれます。JListインスタンスにfixedCellHeightandフィールドを設定すると、これが発生しないようにすることができます。fixedCellWidth

次の2つのパブリックメソッドを使用して、固定の高さと幅を設定してみてください。

  • setFixedCellHeight(int)
  • setFixedCellWidth(int)

余談ですが、一般に、ファイルシステムからのアイコンの読み込みは遅く、イベントディスパッチスレッドで実行するとGUIの動作が遅くなる可能性があります。これは通常、ファイルのロードに時間がかかる可能性がある大きな画像ではより問題になります。まだ行っていない場合は、別のスレッドにアイコンをロードすることを検討してください。これは、共有の「アイコン使用不可画像」を事前にロードすることで実行できます。Pageアイコンを照会されたときに、ページ固有のアイコンがnullの場合は、必要なファイルのロードをトリガーして、戻ることができます。 'アイコン使用不可画像'、およびPageがロードされたら、それをインスタンスに割り当てPage、再描画をトリガーします。ちょっとした考え。

于 2009-11-02T23:49:00.753 に答える