概要
Component
上に重ねて配置した検索用ダイアログの位置をアニメーション付きで変更するレイアウトマネージャーを作成し、その表示非表示をキー入力で切り替えます。
Screenshot
Advertisement
サンプルコード
JPanel p = new JPanel() {
@Override public boolean isOptimizedDrawingEnabled() {
return false;
}
};
p.setLayout(new BorderLayout(0, 0) {
@Override public void layoutContainer(Container parent) {
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int width = parent.getWidth();
int height = parent.getHeight();
int top = insets.top;
int bottom = height - insets.bottom;
int left = insets.left;
int right = width - insets.right;
Component nc = getLayoutComponent(parent, BorderLayout.NORTH);
if (Objects.nonNull(nc)) {
Dimension d = nc.getPreferredSize();
int vsw = UIManager.getInt("ScrollBar.width");
nc.setBounds(right - d.width - vsw, yy - d.height, d.width, d.height);
}
Component cc = getLayoutComponent(parent, BorderLayout.CENTER);
if (Objects.nonNull(cc)) {
cc.setBounds(left, top, right - left, bottom - top);
}
}
}
});
p.add(searchBox, BorderLayout.NORTH);
p.add(new JScrollPane(tree));
View in GitHub: Java, Kotlin解説
BorderLayout#layoutContainer(...)
メソッドをオーバーライドし、BorderLayout.NORTH
で追加した検索ダイアログをOverlayLayout
のようにBorderLayout.CENTER
で追加したJTree
に重ねて配置BorderLayout.CENTER
とBorderLayout.NORTH
のみ対応- 検索ダイアログの幅は
BorderLayout
のBorderLayout.NORTH
配置のように親コンポーネントの幅まで拡張せず、FlowLayout
などと同様にPreferredSize
固定 UIManager.getInt("ScrollBar.width")
で取得したスクロールバーの幅だけ右側に余白を作成して検索ダイアログを配置
Timer
を使った検索ダイアログ位置変更によるスライドインアニメーションJTree
を配置したJScrollPane
と検索用ダイアログ(JPanel
)といった子コンポーネント同士がオーバーラップするので、親のJPanel
のisOptimizedDrawingEnabled()
がfalse
を返すようにオーバーライドする必要がある- 検索用ダイアログが開くと内部の
JTextField
にフォーカスが移動するようにAncestorListener
を設定 JTree
のノード検索- 参考: JTreeのノードを検索する
- Ctrl+F: 検索用ダイアログの表示非表示切り替え
- Esc: 検索用ダイアログを閉じる
- Enter:
JTree
のノードを検索