Swing/TerminateEdit のバックアップの現在との差分(No.7)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/TerminateEdit へ行く。
- 1 (2007-04-16 (月) 16:28:55)
- 2 (2007-04-17 (火) 11:52:32)
- 3 (2007-04-19 (木) 14:07:18)
- 4 (2007-04-20 (金) 13:37:39)
- 5 (2007-04-20 (金) 18:40:13)
- 6 (2007-05-31 (木) 19:51:20)
- 7 (2007-06-01 (金) 17:30:34)
- 8 (2007-10-23 (火) 21:40:58)
- 9 (2008-04-04 (金) 00:35:14)
- 10 (2008-04-04 (金) 14:11:01)
- 11 (2009-09-07 (月) 13:52:10)
- 12 (2010-09-18 (土) 10:37:50)
- 13 (2011-03-16 (水) 20:01:39)
- 14 (2011-11-01 (火) 18:36:05)
- 15 (2012-02-23 (木) 03:58:34)
- 16 (2012-02-23 (木) 14:48:57)
- 17 (2012-06-26 (火) 20:36:21)
- 18 (2013-02-09 (土) 23:51:53)
- 19 (2013-07-26 (金) 01:56:34)
- 20 (2013-08-20 (火) 14:26:43)
- 21 (2014-11-01 (土) 00:46:09)
- 22 (2014-12-18 (木) 17:08:05)
- 23 (2016-03-18 (金) 15:08:10)
- 24 (2016-09-02 (金) 12:33:23)
- 25 (2016-09-28 (水) 17:10:24)
- 26 (2017-11-02 (木) 15:34:40)
- 27 (2017-11-08 (水) 13:54:11)
- 28 (2019-06-26 (水) 22:03:19)
- 29 (2021-03-02 (火) 14:35:54)
- 30 (2022-08-20 (土) 22:15:25)
- 31 (2022-10-01 (土) 04:56:39)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JTableのセルの編集をコミット #navi(../) *JTableのセルの編集をコミット [#bb49aeec] >編集者:[[Terai Atsuhiro>terai]]~ 作成日:2007-04-16~ 更新日:&lastmod; --- category: swing folder: TerminateEdit title: JTableのセルの編集をコミット tags: [JTable, Focus, JTableHeader, TableCellEditor] author: aterai pubdate: 2007-04-16T12:24:10+09:00 description: セルの編集中、フォーカスが別のコンポーネントに移動した場合、その編集を確定する方法をテストします。 image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTVKX5loMI/AAAAAAAAAnM/hbhZT30xAgc/s800/TerminateEdit.png --- * 概要 [#summary] セルの編集中、フォーカスが別のコンポーネントに移動した場合、その編集を確定する方法をテストします。 #contents #download(https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTVKX5loMI/AAAAAAAAAnM/hbhZT30xAgc/s800/TerminateEdit.png) **概要 [#e5533a8a] セルの編集中、フォーカスが別のコンポーネントに移動した場合、その編集を確定する方法をテストします。 * サンプルコード [#sourcecode] #code(link){{ table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); }} #screenshot * 解説 [#explanation] デフォルトの`JTable`では、KBD{Tab}キーやマウスのクリックなどで同じテーブルの別セルにフォーカスが移動すると編集が確定しますが、別のコンポーネントにフォーカスが移動しても編集は確定しません。 **サンプルコード [#lc14b0a2] - `terminateEditOnFocusLost` -- `table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);`を設定 -- 同じフレームを親に持つコンポーネントにフォーカスが移動したとき編集が確定する -- 別フレームのコンポーネントにフォーカスが移動しても編集中の状態が継続する -- ヘッダをクリックしたり、列の入れ替え、サイズ変更を実行すると編集はキャンセルされる - `DefaultCellEditor:focusLost` -- `DefaultCellEditor`からエディタコンポーネントを取得してこれに`FocusListener`を設定し、セルが編集中なら`table.getCellEditor().stopCellEditing();`を実行 -- 別フレームのコンポーネントにフォーカスが移動したときも、編集が確定する -- ヘッダのクリック、入れ替え、サイズ変更などで編集はキャンセルされる #code{{ table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); DefaultCellEditor dce = (DefaultCellEditor)table.getDefaultEditor(Object.class); DefaultCellEditor dce = (DefaultCellEditor) table.getDefaultEditor(Object.class); dce.getComponent().addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent e) { if(!focusCheck.isSelected()) return; if(table.isEditing()) { @Override public void focusLost(FocusEvent e) { if (!focusCheck.isSelected()) { return; } if (table.isEditing()) { table.getCellEditor().stopCellEditing(); } } }); }} - `TableHeader:mousePressed` -- `TableHeader`に`MouseListener`を設定してセルが編集中なら`table.getCellEditor().stopCellEditing();` を実行 -- ヘッダをクリックしたとき編集が確定する -- `JDK 1.7.0`ではこのような`MouseListener`を`TableHeader`に設定しなくても編集が確定するように修正されている -- [https://bugs.openjdk.org/browse/JDK-4330950 Bug ID: 4330950 Lost newly entered data in the cell when resizing column width] #code{{ table.getTableHeader().addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { if(!headerCheck.isSelected()) return; if(table.isEditing()) { @Override public void mousePressed(MouseEvent e) { if (!headerCheck.isSelected()) { return; } if (table.isEditing()) { table.getCellEditor().stopCellEditing(); } } }); }} -&jnlp; -&jar; -&zip; **解説 [#rf7adb29] デフォルトのJTableでは、タブキーやマウスのクリックなどで同じテーブルの別セルにフォーカスが移動すると編集が確定しますが、別のコンポーネントにフォーカスが移動しても編集は確定しません。 ---- - %%親フレームの状態変化でテーブルのヘッダのサイズ変更が発生する場合、ヘッダのリサイズモデルによって編集中のセルの状態変化が異なる%% -- `JDK 1.7.0`で修正済: [https://bugs.openjdk.org/browse/JDK-4330950 Bug ID: 4330950 Lost newly entered data in the cell when resizing column width] -table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);とすると、 --同じフレームを親に持つコンポーネントにフォーカスが移動したとき、編集が確定するようになります。 --別フレームのコンポーネントにフォーカスが移動しても編集中のままです。 --ヘッダをクリック、入れ替え、サイズ変更すると、編集はキャンセルされます。 - `JTable.AUTO_RESIZE_OFF` -- 親フレームのリサイズや最大化は編集中のまま - `JTable.AUTO_RESIZE_ALL_COLUMNS`など -- 親フレームのリサイズや最大化を行うとヘッダのサイズが変化するため、キャンセル扱い - ヘッダのサイズが変化しない場合は、どちらの設定でも以下のようになる -- 親フレームの最小化(アイコン化)は編集中のまま -- 親フレームを閉じる場合はキャンセル扱い -DefaultCellEditorからエディタコンポーネントを取得し、FocusListenerを設定して、セルが編集中ならtable.getCellEditor().stopCellEditing();とすると、 --別フレームのコンポーネントにフォーカスが移動したときも、編集が確定するようになります。 --ヘッダをクリック、入れ替え、サイズ変更すると、編集はキャンセルされます。 -TableHeaderにMouseListenerを設定して、セルが編集中ならtable.getCellEditor().stopCellEditing();とすると、 --ヘッダをクリックしたとき、編集が確定するようになります。 ---- 親フレームの状態変化でテーブルのヘッダのサイズ変更が発生する場合、ヘッダのリサイズモデルによって、編集中のセルの状態変化が異なります。 -JTable.AUTO_RESIZE_OFF --親フレームのリサイズや最大化は編集中のまま -JTable.AUTO_RESIZE_ALL_COLUMNSなど --親フレームのリサイズや最大化を行うとヘッダのサイズが変化するため、キャンセル扱い - 親フレームの状態変化に応じて編集の確定を行う場合は、以下のように`JTable#columnMarginChanged`メソッドなどをオーバーライドしたり、各種リスナーを設定する必要がある ヘッダのサイズが変化しない場合は、どちらの設定でも以下のようになります。 -親フレームの最小化(アイコン化)は編集中のまま -親フレームを閉じる場合はキャンセル扱い 親フレームの状態変化に応じて編集の確定を行う場合は、以下のように、JTable#columnMarginChangedメソッドなどをオーバーライドしたり、各種リスナーを設定する必要があります。 #code{{ table = new JTable(sorter) { public void columnMarginChanged(ChangeEvent e) { if(table.isEditing()) { @Override public void columnMarginChanged(ChangeEvent e) { if (table.isEditing()) { table.getCellEditor().stopCellEditing(); } super.columnMarginChanged(e); } }; frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { if(table.isEditing()) { @Override public void windowClosing(WindowEvent e) { if (table.isEditing()) { table.getCellEditor().stopCellEditing(); } } }); frame.addWindowStateListener(new WindowStateListener() { public void windowStateChanged(WindowEvent e) { if(frame.getExtendedState()==JFrame.MAXIMIZED_BOTH && table.isEditing()) { @Override public void windowStateChanged(WindowEvent e) { if (frame.getExtendedState() == JFrame.MAXIMIZED_BOTH && table.isEditing()) { table.getCellEditor().stopCellEditing(); } } }); }} //**参考リンク **コメント [#l4f43e84] - どわー。助かりましたっ! -- [[shun]] &new{2007-05-31 (木) 19:51:20}; * 参考リンク [#reference] - [https://bugs.openjdk.org/browse/JDK-4330950 Bug ID: 4330950 Lost newly entered data in the cell when resizing column width] -- [https://hg.openjdk.java.net/jdk7/jdk7/jdk/rev/e753db9c4416 changeset 2709:e753db9c4416 4330950: Lost newly entered data in the cell when resizing column width] * コメント [#comment] #comment - どわー。助かりましたっ! -- &user(shun); &new{2007-05-31 (木) 19:51:20}; -- お役に立てて何よりです(自分もこの辺りよく混乱します)。 -- &user(aterai); &new{2007-06-01 (金) 17:30:34}; - `columnMarginChanged`、役に立ちました。ありがとうございます。 -- &user(はじめ); &new{2008-04-04 (金) 00:35:14}; -- どうもです。`JTable#columnMarginChanged`メソッドの`JavaDoc`の説明では、"If a cell is being edited, then editing is stopped and the cell is redrawn."となっているので、`JTable#editingStopped`メソッドを使っている(現在の文字列が新しい値となる)のかなと思ったら、実際は、`JTable#editingCanceled`メソッド(=`JTable#removeEditor`メソッド)でキャンセルしている(編集内容は適用されない)ので、ちょっと混乱してしまいます。 -- &user(aterai); &new{2008-04-04 (金) 14:11:01}; -- `1.7.0`では、[https://bugs.openjdk.org/browse/JDK-4330950 Bug ID: 4330950 Lost newly entered data in the cell when resizing column width] で、修正済みになっているのですが、`getCellEditor().cancelCellEditing()`を使うように変更されているので、編集が消えてしまうのは同じような・・・。 -- &user(aterai); &new{2012-02-23 (木) 14:59:49}; #comment