Swing/LineWrapListEditor のバックアップ(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/LineWrapListEditor へ行く。
- 1 (2021-02-15 (月) 00:27:22)
- 2 (2021-02-15 (月) 15:28:10)
- 3 (2021-02-22 (月) 08:30:49)
- 4 (2021-02-28 (日) 18:31:18)
- category: swing folder: LineWrapListEditor title: JTextAreaとJFrameで幅固定、文字列の折り返し、親枠外まで高さ拡大可能なセルエディタを作成する tags: [JTextArea, JFrame, JPopupMenu, JList] author: aterai pubdate: 2021-02-15T00:26:19+09:00 description: JTextAreaを幅固定、文字列の長さに応じた折り返しで高さ伸縮可能に設定し、これをJFrameに配置して親枠外でも表示可能なJListセルラベルエディタとして使用します。 image: https://drive.google.com/uc?id=
概要
JTextAreaを幅固定、文字列の長さに応じた折り返しで高さ伸縮可能に設定し、これをJFrameに配置して親枠外でも表示可能なJListセルラベルエディタとして使用します。
Screenshot
Advertisement
サンプルコード
// private final Container glassPane = new EditorGlassPane();
// private final JPopupMenu popup = new JPopupMenu();
private final JFrame window = new JFrame();
// private final JTextField editor = new JTextField();
private final JTextArea editor = new JTextArea();
// ...
window.setUndecorated(true);
window.setAlwaysOnTop(true);
window.addWindowListener(new WindowAdapter() {
@Override public void windowDeactivated(WindowEvent e) {
if (editor.isEditable()) {
renameTitle.actionPerformed(new ActionEvent(editor, ActionEvent.ACTION_PERFORMED, ""));
}
}
});
window.add(editor);
editor.setBorder(BorderFactory.createLineBorder(Color.BLACK));
editor.setLineWrap(true);
editor.setFont(UIManager.getFont("TextField.font"));
editor.setComponentPopupMenu(new TextComponentPopupMenu());
editor.getDocument().addDocumentListener(new DocumentListener() {
private int prev = -1;
private void update() {
EventQueue.invokeLater(() -> {
int h = editor.getPreferredSize().height;
if (prev != h) {
Rectangle rect = editor.getBounds();
rect.height = h;
editor.setBounds(rect);
window.pack(); // popup.pack();
editor.requestFocusInWindow();
}
prev = h;
});
}
@Override public void insertUpdate(DocumentEvent e) {
update();
}
@Override public void removeUpdate(DocumentEvent e) {
update();
}
@Override public void changedUpdate(DocumentEvent e) {
update();
}
});
View in GitHub: Java, Kotlin解説
GlassPane
+JTextField
JTextField#setHorizontalAlignment(SwingConstants.CENTER)
を設定して中央揃えが可能JTextField
を使用するため1
行エディタになる- 参考: JListのセルに配置したJLabelのテキストを編集する
GlassPane
+JTextArea
JTextArea#setLineWrap(true)
を設定すれば、幅固定で文字列長に応じて行方向に拡大縮小が可能になるJTextArea
の折り返しが変化すると推奨サイズの高さが更新される
JTextArea
を使用するため中央揃えが不可- 行数が増加して親
JFrame
外になるとエディタが途切れてしまう
JPopupMenu
+JTextArea
- 親
JFrame
外にエディタを配置可能 - エディタの折り返しが変化すると
JPopupMenu#pack()
を使用してJPopupMenu
のサイズをJTextArea
と同じになるよう更新JPopupMenu#pack()
を実行すると子のJTextArea
からフォーカスが移動してしまうのでJTextArea#requestFocusInWindow()
で再設定する必要がある- 親
JFrame
外に表示さている場合(HeavyWeightWindow
(JWindow
)に配置されている場合)一瞬親JFrame
タイトルバーの描画などが乱れる
JPopupMenu
にPopupMenuListener
を追加してエディタでの編集のコミットを実行JPopupMenu
内のJTextArea
からJPopupMenu
を開くことができない
- 親
JFrame
+JTextArea
JFrame#setUndecorated(true)
とJFrame#setAlwaysOnTop(true)
を設定したJFrame
をJPopupMenu
の代わりに使用JFrame
ではなくJWindow
を使用すると子コンポーネントがフォーカスが取得できない- 親
JFrame
がアクティブWindow
でなくなるためグローバルフォーカスが外れる
JFrame
内のJTextArea
からJPopupMenu
を開くことが可能になるJFrame
にWindowListener
を追加してエディタでの編集のコミットを実行- 編集キャンセルの場合はコミットせずに
JFrame
を非表示にするよう注意が必要
- 編集キャンセルの場合はコミットせずに