metodos - Java Swing: ¿Cómo invocar stopCellEditing() antes de TreeListeners: valueChanged?
propiedades slider java (2)
Esta es una continuación de estas preguntas anteriores:
- Cómo detener la edición con DefaultCellEditor cuando se presiona un JBtton por separado
- Sun Bug 4724980: JTable: agregue API para controlar qué ocurre con las ediciones cuando la tabla pierde el foco.
Cuando uso la propiedad terminateEditOnFocusLost
, como a continuación, mi CellEditor deja de editar correctamente cuando la tabla pierde el foco:
jtable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
También funciona con mis JButtons. Se stopCellEditing()
método stopCellEditing()
para mi TableCellEditor antes de que se procese la acción de presionar el botón. Pero cuando lo uso con un JTree, y la selección de árbol cambia, se TreeSelectionListener.valueChanged
método stopCellEditing()
antes de stopCellEditing()
.
¿ stopCellEditing()
sabe si hay una manera de forzar a stopCellEditing()
primero, o debería simplemente stopCellEditing()
problema?
JTree
no tiene propiedad de cliente similar en Swing
. Pero JXTree
, una clase derivada de JTree
, en SwingX
sí SwingX
hace: invokeStopEditing
.
Si no puede usar SwingX
, siempre puede ver el código fuente de JXTree
y ver cómo funciona este mecanismo JXTree SwingX 1.0 API Documentation and Javadoc
: JXTree SwingX 1.0 API Documentation and Javadoc
(go to Source tab)
Especialmente, a partir de la línea 974
, se crea un oyente para monitorear el cambio de propiedad " permanentFocusOwner
" en KeyboardFocusManager
etc ...
No estoy seguro de entender su pregunta con respecto al TreeSelectionListener
y cómo se relaciona con el stopCellEditing()
timing stopCellEditing()
que se está llamando. ¿Estás creando un TreeCellEditor
personalizado? Si es así, sería útil algo más de información sobre la configuración de este editor.
Sin embargo, también hizo referencia a un elemento anterior que pertenecía a la edición de celda en una JTable
, su pérdida de enfoque a un componente externo y el efecto de esto en la celda de edición. Lo he tomado como una pista de que le gustaría una solución similar para JTree
...
Como se indicó, JTree
no implementa el manejo de la propiedad para "terminateEditOnFocusLost"
de fábrica. Esto no significa que puedas hacerlo tú mismo.
Mirando el código de JTable
, es bastante sencillo. Se crea una clase cuyo único trabajo es identificar si JTree
todavía tiene foco cuando hay un cambio de foco, y si no, llama a stopEditing()
y si eso falla llama a cancelEditing()
. Aquí está, adaptado para un árbol:
class CellEditorRemover implements PropertyChangeListener {
KeyboardFocusManager focusManager;
public CellEditorRemover(KeyboardFocusManager fm) {
this.focusManager = fm;
}
public void propertyChange(PropertyChangeEvent ev) {
if (!tree.isEditing() ||
tree.getClientProperty("terminateEditOnFocusLost") != Boolean.TRUE)
{
return;
}
Component c = focusManager.getPermanentFocusOwner();
while (c != null) {
if (c == tree) { // focus remains inside the tree
return;
} else if ((c instanceof Window)
|| (c instanceof Applet && c.getParent() == null))
{
if (c == SwingUtilities.getRoot(tree)) {
if (!tree.getCellEditor().stopCellEditing()) {
tree.getCellEditor().cancelCellEditing();
}
}
break;
}
c = c.getParent();
}
}
}
Notarás que tu árbol debe ser accesible de alguna manera a esta clase. Hay un par de llamadas de configuración para realizar para que esto funcione:
tree.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
KeyboardFocusManager fm =
KeyboardFocusManager.getCurrentKeyboardFocusManager();
editorRemover = new CellEditorRemover(fm);
fm.addPropertyChangeListener("permanentFocusOwner", editorRemover);
Esto debería tener el beneficio adicional de hacer que su JTree
comporte de la misma manera que su JTable
comporta cuando presiona un JButton
.