概要

JScrollPane内に組み込まれたJListを表示するために必要なビューポートの推奨サイズを設定します。

サンプルコード

String[] model1 = IntStream.range(0, 20)
    .mapToObj(Objects::toString)
    .toArray(String[]::new);
JList<String> list1 = new JList<>(model1);
list1.setVisibleRowCount(visibleRowCount);
list1.setPrototypeCellValue(prototypeCellValue);

String[] model2 = {"looooooooooooooong"};
JList<String> list2 = new JList<>(model2);
list2.setVisibleRowCount(visibleRowCount);
list2.setPrototypeCellValue(prototypeCellValue);

JList<String> list3 = new JList<String>(model2) {
  @Override public Dimension getPreferredScrollableViewportSize() {
    Dimension d = super.getPreferredScrollableViewportSize();
    d.width = 60;
    return d;
  }
};
list3.setVisibleRowCount(visibleRowCount);
list3.setPrototypeCellValue(prototypeCellValue);
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、レイアウトの方向がVERTICALに設定されているJListJScrollPaneに組み込まれている場合の表示サイズをテストしています。

  • 上段: プロトタイプアイテム(PrototypeCellValue)がnull
    • PrototypeCellValuenullfixedCellWidthfixedCellHeightがデフォルトの-1
    • 高さ: JList#getVisibleRowCount()fixedCellHeight0の以下なので代わりに固定値16を掛けた値とJList#getInsets()topbottomを足した値になる
      • 水平JScrollBarの高さは推奨ビューポートの高さに含まれない
    • 上段左と上段中の幅: それぞれモデル内で最大の幅を持つアイテムの幅が推奨ビューポートの幅になる
    • 上段右の幅: JList#getPreferredScrollableViewportSize()をオーバーライドして固定値60を推奨ビューポートの幅に設定
  • 下段: プロトタイプアイテム(PrototypeCellValue)が設定済み(MMMMMMM)
    • PrototypeCellValueが存在し、fixedCellWidthfixedCellHeight0以上の値
    • 高さ: JList#getVisibleRowCount()JList#getFixedCellHeight()を掛けた値とJList#getInsets()topbottomを足した値になる
    • 下段左の幅: JList#setPrototypeCellValue(...)で設定したプロトタイプアイテムの幅が推奨ビューポートの幅になる
      • 垂直JScrollBarの幅は推奨ビューポートの幅に含まれない
    • 下段中の幅: JList#setPrototypeCellValue(...)で設定したプロトタイプアイテムの幅が推奨ビューポートの幅になる
    • 下段右の幅: JList#getPreferredScrollableViewportSize()をオーバーライドして固定値60を推奨ビューポートの幅に設定
      • 別途JList#setPrototypeCellValue(...)で設定したアイテムの幅で文字列が省略されているが、その幅が60以上なので水平JScrollBarが表示されている

参考リンク

コメント