JTextAreaとJFrameで幅固定、文字列の折り返し、親枠外まで高さ拡大可能なセルエディタを作成する
Total: 3394, Today: 2, Yesterday: 6
Posted by aterai at
Last-modified:
Summary
JTextAreaを幅固定、文字列の長さに応じた折り返しで高さ伸縮可能に設定し、これをJFrameに配置して親枠外でも表示可能なJListセルラベルエディタとして使用します。
Screenshot

Advertisement
Source Code Examples
// 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, KotlinDescription
GlassPane+JTextFieldJTextField#setHorizontalAlignment(SwingConstants.CENTER)を設定して中央揃えが可能JTextFieldを使用するため1行エディタになる- 参考: JListのセルに配置したJLabelのテキストを編集する
GlassPane+JTextAreaJTextArea#setLineWrap(true)を設定すれば、幅固定で文字列長に応じて行方向に拡大縮小が可能になるJTextAreaの折り返しが変化すると推奨サイズの高さが更新される
JTextAreaを使用するため中央揃えが不可- 本文スタイルに中央揃え属性を設定し、かつ折り返し設定を変更した
JTextPaneで代用可能 - JTextPaneで中央揃え、行折返し可能なリストセルエディタを作成するに移動
- 本文スタイルに中央揃え属性を設定し、かつ折り返し設定を変更した
- 行数が増加して親
JFrame外になるとエディタが途切れてしまう
JPopupMenu+JTextArea- 親
JFrame外にエディタを配置可能 - エディタの折り返しが変化すると
JPopupMenu#pack()を使用してJPopupMenuのサイズをJTextAreaと同じになるよう更新JPopupMenu#pack()を実行すると子のJTextAreaからフォーカスが移動してしまうのでJTextArea#requestFocusInWindow()で再設定する必要がある- 親
JFrame外に表示さている場合(HeavyWeightWindow(JWindow)に配置されている場合)一瞬親JFrameタイトルバーの描画などが乱れる
JPopupMenuにPopupMenuListenerを追加してエディタでの編集のコミットを実行JPopupMenu内のJTextAreaからJPopupMenuを開くことができない
- 親
JFrame+JTextAreaJFrame#setUndecorated(true)とJFrame#setAlwaysOnTop(true)を設定したJFrameをJPopupMenuの代わりに使用JWindow内にフォーカス可能なコンポーネントを配置するのように所有フレームを表示中のJFrameではなくJWindowを使用すると子コンポーネントがフォーカスが取得できないJFrameを指定してJWindowを作成すれば子コンポーネントがフォーカス取得可能になる- 親
JFrameがアクティブWindowでなくなるためグローバルフォーカスが外れる
JFrame内のJTextAreaからJPopupMenuを開くことが可能になるJFrameにWindowListenerを追加してエディタでの編集のコミットを実行- 編集キャンセルの場合はコミットせずに
JFrameを非表示にするよう注意が必要
- 編集キャンセルの場合はコミットせずに
JFrameのタイトルバーをクリックしても編集終了できない
Reference
- JListのセルに配置したJLabelのテキストを編集する
- JTextArea#setLineWrap(boolean) (Java Platform SE 8)
- JWindow内にフォーカス可能なコンポーネントを配置する
- JTextPaneで中央揃え、行折返し可能なリストセルエディタを作成する