JSplitPaneの分割割合を維持する
Total: 685, Today: 1, Yesterday: 0
Posted by aterai at
Last-modified:
Summary
JSplitPaneのサイズが変更されてもその分割割合を維持するよう設定します。
Screenshot

Advertisement
Source Code Examples
class SplitPaneWrapper extends JPanel {
private final JSplitPane splitPane;
protected SplitPaneWrapper(JSplitPane splitPane) {
super(new BorderLayout());
this.splitPane = splitPane;
add(splitPane);
}
private static int getOrientedSize(JSplitPane sp) {
return sp.getOrientation() == JSplitPane.VERTICAL_SPLIT
? sp.getHeight() - sp.getDividerSize()
: sp.getWidth() - sp.getDividerSize();
}
@Override public void doLayout() {
int size = getOrientedSize(splitPane);
int loc = splitPane.getDividerLocation();
BigDecimal ratio = BigDecimal.valueOf(loc / (double) size)
.setScale(2, RoundingMode.HALF_UP);
super.doLayout();
if (splitPane.isShowing()) {
EventQueue.invokeLater(() -> {
int sz = getOrientedSize(splitPane);
int iv = (int) (.5 + sz * ratio.doubleValue());
splitPane.setDividerLocation(iv);
});
}
}
}
View in GitHub: Java, KotlinDescription
Default(ResizeWeight:0.5)- デフォルトの
JSplitPaneにJSplitPane#setResizeWeight(.5)を設定し、余分なスペースの配分方法を左右均等に設定 JSplitPaneのリサイズ(このサンプルの場合親JFrameのリサイズ)を繰り返していると余りや誤差?が常に左側のコンポーネントに積み重なるので、子コンポーネントの推奨サイズに基づいた分割割合から大きくズレてしまう場合がある
- デフォルトの
SplitPaneWrapper(Keep ratio)JSplitPaneをJPanelでラップし、そのJPanel#doLayout()をオーバーライドしてJSplitPaneの分割割合を補正BasicSplitPaneUI.BasicHorizontalLayoutManager#distributeSpace(int space, boolean keepHidden)はオーバーライドしづらいのでJSplitPaneのDividerの位置を最大化後に変更すると同様にJPanelをラップして対応super.doLayout()で再レイアウトする前のJSplitPane分割割合を保存super.doLayout()実行後にJSplitPaneの新規サイズと保存していた分割割合からディバイダーの位置を計算JSplitPane#setDividerLocation(...)を実行してリサイズ前の分割割合を復元
- この方法でも誤差は発生するので完全に分割割合を維持することはできない
Reference
- java - How do you get JSplitPane to keep the same proportional location if the user has moved the location of the divider - Stack Overflow
- JSplitPaneのDividerの位置を最大化後に変更する