Swing/OverlayBorderLayout の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/OverlayBorderLayout へ行く。
- Swing/OverlayBorderLayout の差分を削除
--- category: swing folder: OverlayBorderLayout title: Component上に重ねて配置したダイアログの表示状態をアニメーション付きで切り替える tags: [LayoutManager, JPanel, Timer, Animation, InputMap, ActionMap] author: aterai pubdate: 2015-08-10T13:10:18+09:00 description: Component上に重ねて配置した検索用ダイアログの位置をアニメーション付きで変更するレイアウトマネージャーを作成し、その表示非表示をキー入力で切り替えます。 image: https://lh3.googleusercontent.com/-gEMKmLyIHno/VcgZ2tpTyMI/AAAAAAAAN-0/HLb8wuLN_LE/s800-Ic42/OverlayBorderLayout.png --- * 概要 [#summary] `Component`上に重ねて配置した検索用ダイアログの位置をアニメーション付きで変更するレイアウトマネージャーを作成し、その表示非表示をキー入力で切り替えます。 #download(https://lh3.googleusercontent.com/-gEMKmLyIHno/VcgZ2tpTyMI/AAAAAAAAN-0/HLb8wuLN_LE/s800-Ic42/OverlayBorderLayout.png) * サンプルコード [#sourcecode] #code(link){{ 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)); }} * 解説 [#explanation] - `BorderLayout#layoutContainer(...)`メソッドをオーバーライドし、`BorderLayout.NORTH`で追加した検索ダイアログを`OverlayLayout`のように`BorderLayout.CENTER`で追加した`JTree`に重ねて配置 -- `BorderLayout.CENTER`と`BorderLayout.NORTH`のみ対応 -- 検索ダイアログの幅は`BorderLayout`の`BorderLayout.NORTH`配置のように親コンポーネントの幅まで拡張せず、`FlowLayout`などと同様に`PreferredSize`固定 -- `UIManager.getInt("ScrollBar.width")`で取得したスクロールバーの幅だけ右側に余白を作成して検索ダイアログを配置 - `Timer`を使った検索ダイアログ位置変更によるスライドインアニメーション -- 参考: [[JToolBarの半透明化とアニメーション>Swing/TranslucentToolBar]]、[[JTextAreaをキャプションとして画像上にスライドイン>Swing/EaseInOut]] -- [[JToolBarの半透明化とアニメーション>Swing/TranslucentToolBar]] -- [[JTextAreaをキャプションとして画像上にスライドイン>Swing/EaseInOut]] - `JTree`を配置した`JScrollPane`と検索用ダイアログ(`JPanel`)といった子コンポーネント同士がオーバーラップするので、親の`JPanel`の`isOptimizedDrawingEnabled()`が`false`を返すようにオーバーライドする必要がある -- 参考: [[JScrollBarを半透明にする>Swing/TranslucentScrollBar]] - 検索用ダイアログが開くと内部の`JTextField`にフォーカスが移動するように`AncestorListener`を設定 -- 参考: [[JOptionPaneのデフォルトフォーカス>Swing/OptionPaneDefaultFocus]] - `JTree`のノード検索 -- 参考: [[JTreeのノードを検索する>Swing/SearchBox]] -- KBD{Ctrl+F}: 検索用ダイアログの表示非表示切り替え -- KBD{Esc}: 検索用ダイアログを閉じる -- KBD{Enter}: `JTree`のノードを検索 * 参考リンク [#reference] - [[JScrollBarを半透明にする>Swing/TranslucentScrollBar]] - [[JOptionPaneのデフォルトフォーカス>Swing/OptionPaneDefaultFocus]] - [[JTreeのノードを検索する>Swing/SearchBox]] * コメント [#comment] #comment #comment