JPanelの子コンポーネントを水平方向で折り返す
Total: 2578
, Today: 2
, Yesterday: 0
Posted by aterai at
Last-modified:
概要
JPanel
に配置した子コンポーネントを水平方向で折り返し、またそれらの水平間隔を動的に均等になるよう拡大します。
Screenshot
Advertisement
サンプルコード
class ScrollableWrapLayout extends FlowLayout {
private final int fixedHorizontalGap;
protected ScrollableWrapLayout(int align, int hgap, int vgap) {
super(align, hgap, vgap);
fixedHorizontalGap = hgap;
}
private int getPreferredHorizontalGap(Container target) {
Insets insets = target.getInsets();
int columns = 0;
int width = target.getWidth();
if (target.getParent() instanceof JViewport) {
width = target.getParent().getBounds().width;
}
width -= insets.left + insets.right + fixedHorizontalGap * 2;
for (int i = 0; i < target.getComponentCount(); i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
if (width - d.width - fixedHorizontalGap < 0) {
columns = i;
break;
}
width -= d.width + fixedHorizontalGap;
}
}
return fixedHorizontalGap + width / columns;
}
@Override public void layoutContainer(Container target) {
setHgap(getPreferredHorizontalGap(target));
super.layoutContainer(target);
}
@Override public Dimension preferredLayoutSize(Container target) {
Dimension dim = super.preferredLayoutSize(target);
synchronized (target.getTreeLock()) {
if (target.getParent() instanceof JViewport) {
dim.width = target.getParent().getBounds().width;
for (int i = 0; i < target.getComponentCount(); i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
dim.height = Math.max(dim.height, d.height + m.getY());
}
}
}
return dim;
}
}
}
View in GitHub: Java, Kotlin解説
- 上:
JPanel
+FlowLayout
- デフォルトの
JPanel
にFlowLayout
を設定してJScrollPane
に配置 - 水平方向に
JPanel
が拡張されて水平ScrollBar
が表示される
- デフォルトの
- 下:
ScrollableWrapPanel
+ScrollableWrapLayout
JPanel
にScrollable
を実装するScrollableWrapPanel
を作成し、これにFlowLayout#preferredLayoutSize(...)
などをオーバーライドするScrollableWrapLayout
を設定してJScrollPane
に配置ScrollableWrapPanel
の子コンポーネント間の水平間隔を親のリサイズに応じて動的・均等に拡大するようFlowLayout#layoutContainer(...)
メソッドをオーバーライド- 最小値は初期水平間隔
- 子コンポーネントはすべて同じ推奨サイズと想定
参考リンク
- JListのアイテムを範囲指定で選択
- 子コンポーネントのレイアウト方法は
JList.HORIZONTAL_WRAP
を使用する場合と水平間隔以外はほぼ同じになる
- 子コンポーネントのレイアウト方法は
- Wrap Layout « Java Tips Weblog