diff --git a/README.md b/README.md index c52e6a7..513d684 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ public class LongFormat implements Format { FormatRegistry.register(Long.class, new LongFormat()); // Formats must be stateless and thread safe. ``` -The FormatRegisty is used by all components, STextField, STable, STree, SButtonGroup, ..., +The FormatRegistry is used by all components, STextField, STable, STree, SButtonGroup, ..., so it is only necessary to register a format once. This also is true for domain entities, like for example a "City" or "Employee". @@ -271,7 +271,7 @@ Just include a dependency in your project. For the latest version see [Maven cen * Binding uses Karsten Lentzsch's JGoodies underneath (https://www.jgoodies.com/freeware/libraries/binding/). * STable's filter header is provided by Coderazzi (https://coderazzi.net/tablefilter/). * STable's navigation bar is based on CoMedia's implementation (project is no longer available online). -* Mikael Grev's excelent MigLayout is used for several layouts (https://www.miglayout.com/). +* Mikael Grev's excellent MigLayout is used for several layouts (https://www.miglayout.com/). And if icons are needed in an application Ikonli is highly suggested! (https://kordamp.org/ikonli/) diff --git a/src/main/java/org/tbee/sway/STable.java b/src/main/java/org/tbee/sway/STable.java index 34b9e6e..750ad01 100644 --- a/src/main/java/org/tbee/sway/STable.java +++ b/src/main/java/org/tbee/sway/STable.java @@ -9,6 +9,7 @@ import org.tbee.sway.format.Format; import org.tbee.sway.format.FormatAsJavaTextFormat; import org.tbee.sway.format.FormatRegistry; +import org.tbee.sway.support.BeanUtil; import org.tbee.sway.support.SwayUtil; import org.tbee.sway.table.FormatCellRenderer; import org.tbee.sway.table.STableCore; @@ -34,7 +35,6 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -532,17 +532,16 @@ public STable onSelectionChanged(Consumer> onSelectio // =========================================================================== // BINDING - private Method addPropertyChangeListenerMethod = null; - private Method removePropertyChangeListenerMethod = null; - private boolean boundToBean = false; + private BeanUtil.PropertyChangeConnector propertyChangeConnector = null; + private boolean registerToAllBeans = false; /** - * bindToBean + * */ public void setMonitorBean(Class v) { // unregister if already registered - if (monitorBean != null) { + if (registerToAllBeans) { unregisterFromAllBeans(); } @@ -550,23 +549,8 @@ public void setMonitorBean(Class v) { monitorBean = v; // Find the binding methods - addPropertyChangeListenerMethod = null; - removePropertyChangeListenerMethod = null; - if (monitorBean != null) { - try { - addPropertyChangeListenerMethod = monitorBean.getMethod("addPropertyChangeListener", new Class[]{PropertyChangeListener.class}); - } - catch (NoSuchMethodException e) { - // ignore silently throw new RuntimeException(e); - } - try { - removePropertyChangeListenerMethod = monitorBean.getMethod("removePropertyChangeListener", new Class[]{PropertyChangeListener.class}); - } - catch (NoSuchMethodException e) { - // ignore silently throw new RuntimeException(e); - } - boundToBean = (addPropertyChangeListenerMethod != null && removePropertyChangeListenerMethod != null); - } + propertyChangeConnector = BeanUtil.getPropertyChangeConnector(v); + registerToAllBeans = propertyChangeConnector.isComplete(); // Register registerToAllBeans(); @@ -605,37 +589,21 @@ public STable monitorBean(Class v) { }; protected void registerToAllBeans() { - if (!boundToBean) { + if (!registerToAllBeans) { return; } for (Object record : data) { - try { - if (LOGGER.isDebugEnabled()) LOGGER.debug("Register to " + record); - addPropertyChangeListenerMethod.invoke(record, beanPropertyChangeListener); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - catch (InvocationTargetException e) { - throw new RuntimeException(e); - } + if (LOGGER.isDebugEnabled()) LOGGER.debug("Register to " + record); + propertyChangeConnector.register(record, beanPropertyChangeListener); } } protected void unregisterFromAllBeans() { - if (!boundToBean) { + if (!registerToAllBeans) { return; } for (Object record : data) { - try { - if (LOGGER.isDebugEnabled()) LOGGER.debug("Unregister from " + record); - removePropertyChangeListenerMethod.invoke(record, beanPropertyChangeListener); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - catch (InvocationTargetException e) { - throw new RuntimeException(e); - } + if (LOGGER.isDebugEnabled()) LOGGER.debug("Unregister from " + record); + propertyChangeConnector.unregister(record, beanPropertyChangeListener); } } diff --git a/src/main/java/org/tbee/sway/support/BeanUtil.java b/src/main/java/org/tbee/sway/support/BeanUtil.java new file mode 100644 index 0000000..6214923 --- /dev/null +++ b/src/main/java/org/tbee/sway/support/BeanUtil.java @@ -0,0 +1,56 @@ +package org.tbee.sway.support; + +import java.beans.PropertyChangeListener; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class BeanUtil { + + public record PropertyChangeConnector(Method addPropertyChangeListenerMethod, Method removePropertyChangeListenerMethod) { + public boolean isComplete() { + return (addPropertyChangeListenerMethod != null && removePropertyChangeListenerMethod != null); + } + + public void register(Object bean, PropertyChangeListener propertyChangeListener) { + try { + addPropertyChangeListenerMethod.invoke(bean, propertyChangeListener); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + public void unregister(Object bean, PropertyChangeListener propertyChangeListener) { + try { + removePropertyChangeListenerMethod.invoke(bean, propertyChangeListener); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + + static public PropertyChangeConnector getPropertyChangeConnector(Class bean) { + Method addPropertyChangeListenerMethod = null; + Method removePropertyChangeListenerMethod = null; + try { + addPropertyChangeListenerMethod = bean.getMethod("addPropertyChangeListener", new Class[]{PropertyChangeListener.class}); + } + catch (NoSuchMethodException e) { + // ignore silently + } + try { + removePropertyChangeListenerMethod = bean.getMethod("removePropertyChangeListener", new Class[]{PropertyChangeListener.class}); + } + catch (NoSuchMethodException e) { + // ignore silently + } + return new PropertyChangeConnector(addPropertyChangeListenerMethod, removePropertyChangeListenerMethod); + } +}