Summary
Component上に重ねて配置した検索用ダイアログの位置をアニメーション付きで変更するレイアウトマネージャーを作成し、その表示非表示をキー入力で切り替えます。
Screenshot

Advertisement
Source Code Examples
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, KotlinDescription
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のノードを検索