Swing/JWindowFocus のバックアップ(No.2)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/JWindowFocus へ行く。
- 1 (2021-02-22 (月) 08:24:00)
- 2 (2021-03-01 (月) 01:01:49)
- 3 (2021-03-02 (火) 14:32:41)
- category: swing folder: JWindowFocus title: JWindow内にフォーカス可能なコンポーネントを配置する tags: [JWindow, Focus, JFrame, JPopupMenu] author: aterai pubdate: 2021-02-22T08:23:09+09:00 description: JWindowや装飾なしのJFrame、JPopupMenuなどにフォーカス可能なコンポーネントを配置するテストを実行します。 image: https://drive.google.com/uc?id=1tjnD9mtXy7CD07S9aW8kNU7FyC25yk00
概要
JWindow
や装飾なしのJFrame
、JPopupMenu
などにフォーカス可能なコンポーネントを配置するテストを実行します。
Screenshot
Advertisement
サンプルコード
JButton button4 = new JButton("JWindow(owner)");
button4.addActionListener(e -> {
JButton b = (JButton) e.getSource();
resetEditor(editor, b);
Point p = b.getLocation();
p.y += b.getHeight();
SwingUtilities.convertPointToScreen(p, b.getParent());
Window window = new JWindow(SwingUtilities.getWindowAncestor(b));
window.setFocusableWindowState(true);
window.setAlwaysOnTop(true);
window.add(editor);
window.pack();
window.setLocation(p);
window.setVisible(true);
editor.requestFocusInWindow();
});
View in GitHub: Java, Kotlin解説
JPopupMenu
JPopupMenu
内にフォーカス可能なコンポーネントとしてJTextArea
を配置- 親
JFrame
のタイトルバーなどをクリックすると自動的にJPopupMenu
が非表示になる JPopupMenu
内に配置した子コンポーネントのJTextArea
からJPopupMenu
が開けない- 親
JFrame
内にポップアップするLightWeightPopup
でJPopupMenu#pack()
を実行すると子のJTextArea
からフォーカスが移動してしまうのでJTextArea#requestFocusInWindow()
で再設定する必要がある - 親
JFrame
外にポップアップするHeavyWeightPopup
でJPopupMenu#pack()
を実行すると一瞬親JFrame
タイトルバーの描画などが乱れる
button1.addActionListener(e -> {
JButton b = (JButton) e.getSource();
resetEditor(editor, b);
JPopupMenu popup = new JPopupMenu();
popup.setBorder(BorderFactory.createEmptyBorder());
popup.add(editor);
popup.pack();
Point p = b.getLocation();
p.y += b.getHeight();
popup.show(this, p.x, p.y);
editor.requestFocusInWindow();
});
JFrame#setUndecorated(true)
JFrame#setUndecorated(true)
でタイトルバーなどの装飾を非表示にしたJFrame
にフォーカス可能なコンポーネントとしてJTextArea
を配置- 親
JFrame
がアクティブWindow
でなくなるためグローバルフォーカスが外れて親JFrame
のタイトルバーの描画などが変化する JTextArea
外をクリックして編集終了と合わせてJFrame
を閉じる場合、親JFrame
にMouseListener
やComponentListener
を追加する必要がある- 親
JFrame
のタイトルバーをクリックしてもそのイベントを取得する方法がない?ため、その動作でJTextArea
を閉じることができない
- 親
JButton button2 = new JButton("JFrame#setUndecorated(true)");
button2.addActionListener(e -> {
JButton b = (JButton) e.getSource();
resetEditor(editor, b);
JFrame window = new JFrame();
window.setUndecorated(true);
window.setAlwaysOnTop(true);
window.add(editor);
window.pack();
Point p = b.getLocation();
p.y += b.getHeight();
SwingUtilities.convertPointToScreen(p, b.getParent());
window.setLocation(p);
window.setVisible(true);
editor.requestFocusInWindow();
});
JWindow()
JWindow
にフォーカス可能なコンポーネントとしてJTextArea
を配置- 親
JFrame
を指定していないので非表示のJFrame
が親フレームになり、JWindow
に配置したコンポーネントがフォーカスを取得できない JWindow#setFocusableWindowState(true)
を指定しても効果がない?- 非表示の
JFrame
が別途表示された後(このサンプルではbutton2
やbutton4
が実行された後)ならマウスでJTextArea
の文字列を選択することなどが可能になる
JButton button3 = new JButton("JWindow()");
button3.addActionListener(e -> {
JButton b = (JButton) e.getSource();
resetEditor(editor, b);
Window window = new JWindow();
window.setFocusableWindowState(true);
window.setAlwaysOnTop(true);
window.add(editor);
window.pack();
Point p = b.getLocation();
p.y += b.getHeight();
SwingUtilities.convertPointToScreen(p, b.getParent());
window.setLocation(p);
window.setVisible(true);
editor.requestFocusInWindow();
});
JWindow(owner)
- 表示中の親
JFrame
を所有フレームにしてJWindow
を作成し、これにフォーカス可能なコンポーネントとしてJTextArea
を配置 - 親
JFrame
がアクティブWindow
のままになるのでそのタイトルバーの描画などは変化しない JTextArea
外をクリックして編集終了と合わせてJWindow
を閉じる場合、親JFrame
にMouseListener
やComponentListener
を追加する必要がある- 装飾なしの
JFrame
と同様に親JFrame
のタイトルバーをクリックしてもそのイベントを取得する方法がない?ため、その動作でJTextArea
を閉じることができない
- 装飾なしの
- 表示中の親
参考リンク
- How to Use the Focus Subsystem (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Other Swing Features)
- JTextAreaとJFrameで幅固定、文字列の折り返し、親枠外まで高さ拡大可能なセルエディタを作成する