""" Java java.beans standard library APIs implemented in Python. java.beans package - BeanInfo, Introspector, PropertyChange, etc. """ from __future__ import annotations from .._core import Stub, AndroidOnlyError from .lang import RuntimeException import typing as _typing __all__ = [ "BeanInfo", "IntrospectionException", "Introspector", "BeanDescriptor", "EventSetDescriptor", "MethodDescriptor", "ParameterDescriptor", "PropertyChangeListener", "PropertyChangeSupport", "PropertyChangeEvent", "PropertyChangeListenerProxy", "PropertyDescriptor", "SimpleBeanInfo", "FeatureDescriptor", "PropertyEditor", "PropertyEditorManager", "PropertyEditorSupport", "VetoableChangeListener", "VetoableChangeSupport", "IndexedPropertyChangeEvent", "IndexedPropertyDescriptor", "EventHandler", "ExceptionListener", "AppletInitializer", "Beans", "Customizer", "DesignMode", "Visibility", ] # ============================================================ # Exceptions # ============================================================ class IntrospectionException(Exception): """java.beans.IntrospectionException""" def __init__(self, message): super().__init__(message) # ============================================================ # FeatureDescriptor # ============================================================ class FeatureDescriptor(Stub): """java.beans.FeatureDescriptor""" def __init__(self): super().__init__() self._name = None self._display_name = None self._short_description = None self._preferred = False self._expert = False self._hidden = False self._attributes = {} self._bound = False self._constrained = False def getName(self): return self._name def setName(self, name): self._name = name def getDisplayName(self): return self._display_name or self._name or "" def setDisplayName(self, name): self._display_name = name def getShortDescription(self): return self._short_description or self.getDisplayName() def setShortDescription(self, text): self._short_description = text def isPreferred(self): return self._preferred def setPreferred(self, preferred): self._preferred = preferred def isExpert(self): return self._expert def setExpert(self, expert): self._expert = expert def isHidden(self): return self._hidden def setHidden(self, hidden): self._hidden = hidden def setValue(self, attribute_name, value): self._attributes[attribute_name] = value def getValue(self, attribute_name): return self._attributes.get(attribute_name) def attributeNames(self): return list(self._attributes.keys()) # ============================================================ # BeanDescriptor # ============================================================ class BeanDescriptor(FeatureDescriptor): """java.beans.BeanDescriptor""" def __init__(self, bean_class, customizer_class=None): super().__init__() self._bean_class = bean_class self._customizer_class = customizer_class def getBeanClass(self): return self._bean_class def getCustomizerClass(self): return self._customizer_class # ============================================================ # EventSetDescriptor # ============================================================ class EventSetDescriptor(FeatureDescriptor): """java.beans.EventSetDescriptor""" def __init__(self, source_class, event_set_name, listener_type, listener_methods, add_listener_method=None, remove_listener_method=None): super().__init__() self._source_class = source_class self._event_set_name = event_set_name self._listener_type = listener_type self._listener_methods = listener_methods or [] self._add_listener_method = add_listener_method self._remove_listener_method = remove_listener_method self._unicast = False self._in_default_event_set = False def getListenerType(self): return self._listener_type def getListenerMethods(self): return self._listener_methods def getAddListenerMethod(self): return self._add_listener_method def getRemoveListenerMethod(self): return self._remove_listener_method def isUnicast(self): return self._unicast def setUnicast(self, unicast): self._unicast = unicast def isInDefaultEventSet(self): return self._in_default_event_set def setInDefaultEventSet(self, in_default): self._in_default_event_set = in_default # ============================================================ # MethodDescriptor / ParameterDescriptor # ============================================================ class MethodDescriptor(FeatureDescriptor): """java.beans.MethodDescriptor""" def __init__(self, method, parameter_descriptors=None): super().__init__() self._method = method self._parameter_descriptors = parameter_descriptors or [] def getMethod(self): return self._method def getParameterDescriptors(self): return self._parameter_descriptors class ParameterDescriptor(FeatureDescriptor): """java.beans.ParameterDescriptor""" pass # ============================================================ # PropertyDescriptor # ============================================================ class PropertyDescriptor(FeatureDescriptor): """java.beans.PropertyDescriptor""" def __init__(self, property_name, bean_class, getter_name=None, setter_name=None): super().__init__() self._property_name = property_name self._bean_class = bean_class self._getter_name = getter_name self._setter_name = setter_name self._property_type = None self._read_method = None self._write_method = None self._bound = False self._constrained = False self._property_editor_class = None def getPropertyType(self): return self._property_type def setPropertyType(self, prop_type): self._property_type = prop_type def getReadMethod(self): return self._read_method def setReadMethod(self, method): self._read_method = method def getWriteMethod(self): return self._write_method def setWriteMethod(self, method): self._write_method = method def isBound(self): return self._bound def setBound(self, bound): self._bound = bound def isConstrained(self): return self._constrained def setConstrained(self, constrained): self._constrained = constrained def getPropertyEditorClass(self): return self._property_editor_class def setPropertyEditorClass(self, cls): self._property_editor_class = cls class IndexedPropertyDescriptor(PropertyDescriptor): """java.beans.IndexedPropertyDescriptor""" def __init__(self, property_name, bean_class, getter_name=None, setter_name=None, indexed_getter_name=None, indexed_setter_name=None): super().__init__(property_name, bean_class, getter_name, setter_name) self._indexed_read_method = None self._indexed_write_method = None self._indexed_property_type = None def getIndexedReadMethod(self): return self._indexed_read_method def setIndexedReadMethod(self, method): self._indexed_read_method = method def getIndexedWriteMethod(self): return self._indexed_write_method def setIndexedWriteMethod(self, method): self._indexed_write_method = method def getIndexedPropertyType(self): return self._indexed_property_type def setIndexedPropertyType(self, prop_type): self._indexed_property_type = prop_type # ============================================================ # Introspector # ============================================================ class Introspector(Stub): """java.beans.Introspector""" @staticmethod def getBeanInfo(bean_class, stop_class=None, flags=None): bean_descriptor = BeanDescriptor(bean_class) bean_info = SimpleBeanInfo() props = [] methods = [] events = [] for name in dir(bean_class): if name.startswith('_'): continue attr = getattr(bean_class, name, None) if callable(attr): methods.append(MethodDescriptor(attr)) if name.startswith('get') and not name.startswith('getClass'): prop_name = name[3].lower() + name[4:] pd = PropertyDescriptor(prop_name, bean_class, getter_name=name) props.append(pd) bean_info._property_descriptors = props bean_info._method_descriptors = methods bean_info._event_set_descriptors = events bean_info._bean_descriptor = bean_descriptor return bean_info @staticmethod def decapitalize(name): if len(name) == 0: return name if len(name) > 1 and name[1].islower(): return name[0].lower() + name[1:] return name.lower() @staticmethod def flushCaches(): pass @staticmethod def flushFromCaches(cls): pass USE_ALL_BEANINFO = 1 IGNORE_IMMEDIATE_BEANINFO = 2 IGNORE_ALL_BEANINFO = 3 # ============================================================ # SimpleBeanInfo / BeanInfo # ============================================================ class BeanInfo(Stub): """java.beans.BeanInfo""" ICON_COLOR_16x16 = 1 ICON_COLOR_32x32 = 2 ICON_MONO_16x16 = 3 ICON_MONO_32x32 = 4 def getBeanDescriptor(self): return None def getEventSetDescriptors(self): return [] def getDefaultEventIndex(self): return -1 def getMethodDescriptors(self): return [] def getDefaultMethodIndex(self): return -1 def getPropertyDescriptors(self): return [] def getDefaultPropertyIndex(self): return -1 def getIcon(self, icon_kind): return None def getAdditionalBeanInfo(self): return None class SimpleBeanInfo(BeanInfo): """java.beans.SimpleBeanInfo""" def __init__(self): super().__init__() self._bean_descriptor = None self._property_descriptors = [] self._method_descriptors = [] self._event_set_descriptors = [] self._default_property_index = -1 self._default_event_index = -1 self._default_method_index = -1 def getBeanDescriptor(self): return self._bean_descriptor def getPropertyDescriptors(self): return self._property_descriptors def getMethodDescriptors(self): return self._method_descriptors def getEventSetDescriptors(self): return self._event_set_descriptors def getDefaultPropertyIndex(self): return self._default_property_index def getDefaultEventIndex(self): return self._default_event_index def getIcon(self, icon_kind): return None def loadBeanInfo(self, bean_info_class): return self # ============================================================ # PropertyChangeEvent / IndexedPropertyChangeEvent # ============================================================ class PropertyChangeEvent(Stub): """java.beans.PropertyChangeEvent""" def __init__(self, source, property_name, old_value, new_value): super().__init__() self._source = source self._property_name = property_name self._old_value = old_value self._new_value = new_value self._propagation_id = None def getPropertyName(self): return self._property_name def getOldValue(self): return self._old_value def getNewValue(self): return self._new_value def setPropagationId(self, propagation_id): self._propagation_id = propagation_id def getPropagationId(self): return self._propagation_id def toString(self): return (f"PropertyChangeEvent[property={self._property_name}, " f"old={self._old_value}, new={self._new_value}]") class IndexedPropertyChangeEvent(PropertyChangeEvent): """java.beans.IndexedPropertyChangeEvent""" def __init__(self, source, property_name, old_value, new_value, index): super().__init__(source, property_name, old_value, new_value) self._index = index def getIndex(self): return self._index # ============================================================ # Listener Interfaces # ============================================================ class PropertyChangeListener(Stub): """java.beans.PropertyChangeListener""" def propertyChange(self, evt): pass class PropertyChangeListenerProxy(PropertyChangeListener): """java.beans.PropertyChangeListenerProxy""" def __init__(self, property_name, listener): super().__init__() self._property_name = property_name self._listener = listener def propertyChange(self, evt): if self._listener: self._listener(evt) def getPropertyName(self): return self._property_name def getListener(self): return self._listener class VetoableChangeListener(Stub): """java.beans.VetoableChangeListener""" def vetoableChange(self, evt): pass # ============================================================ # PropertyChangeSupport # ============================================================ class PropertyChangeSupport(Stub): """java.beans.PropertyChangeSupport""" def __init__(self, source_bean): super().__init__() self._source = source_bean self._listeners = [] def addPropertyChangeListener(self, listener, property_name=None): if property_name is not None: self._listeners.append(PropertyChangeListenerProxy(property_name, listener)) else: self._listeners.append(listener) def removePropertyChangeListener(self, listener, property_name=None): if property_name is not None: self._listeners = [ l for l in self._listeners if not (isinstance(l, PropertyChangeListenerProxy) and l.getListener() == listener and l.getPropertyName() == property_name) ] else: self._listeners = [ l for l in self._listeners if l != listener ] def getPropertyChangeListeners(self, property_name=None): if property_name is not None: return [l for l in self._listeners if isinstance(l, PropertyChangeListenerProxy) and l.getPropertyName() == property_name or not isinstance(l, PropertyChangeListenerProxy)] return self._listeners def firePropertyChange(self, property_name_or_evt, old_value=None, new_value=None): if isinstance(property_name_or_evt, PropertyChangeEvent): evt = property_name_or_evt else: evt = PropertyChangeEvent(self._source, property_name_or_evt, old_value, new_value) for listener in self._listeners: if isinstance(listener, PropertyChangeListenerProxy): if listener.getPropertyName() == evt.getPropertyName(): listener.propertyChange(evt) else: listener.propertyChange(evt) def hasListeners(self, property_name): for listener in self._listeners: if isinstance(listener, PropertyChangeListenerProxy): if listener.getPropertyName() == property_name: return True return False # ============================================================ # VetoableChangeSupport # ============================================================ class VetoableChangeSupport(Stub): """java.beans.VetoableChangeSupport""" def __init__(self, source_bean): super().__init__() self._source = source_bean self._listeners = [] def addVetoableChangeListener(self, listener, property_name=None): if property_name is not None: self._listeners.append(PropertyChangeListenerProxy(property_name, listener)) else: self._listeners.append(listener) def removeVetoableChangeListener(self, listener, property_name=None): if property_name is not None: self._listeners = [ l for l in self._listeners if not (isinstance(l, PropertyChangeListenerProxy) and l.getListener() == listener and l.getPropertyName() == property_name) ] else: self._listeners = [l for l in self._listeners if l != listener] def fireVetoableChange(self, property_name_or_evt, old_value=None, new_value=None): if isinstance(property_name_or_evt, PropertyChangeEvent): evt = property_name_or_evt else: evt = PropertyChangeEvent(self._source, property_name_or_evt, old_value, new_value) for listener in self._listeners: if isinstance(listener, PropertyChangeListenerProxy): if listener.getPropertyName() == evt.getPropertyName(): listener.propertyChange(evt) else: listener.propertyChange(evt) def hasListeners(self, property_name): for listener in self._listeners: if isinstance(listener, PropertyChangeListenerProxy): if listener.getPropertyName() == property_name: return True return False # ============================================================ # PropertyEditor # ============================================================ class PropertyEditor(Stub): """java.beans.PropertyEditor""" def setValue(self, value): pass def getValue(self): return None def isPaintable(self): return False def paintValue(self, gfx, box): pass def getJavaInitializationString(self): return "" def getAsText(self): return "" def setAsText(self, text): pass def getTags(self): return None def getCustomEditor(self): return None def supportsCustomEditor(self): return False def addPropertyChangeListener(self, listener): pass def removePropertyChangeListener(self, listener): pass class PropertyEditorSupport(PropertyEditor): """java.beans.PropertyEditorSupport""" def __init__(self, source=None): super().__init__() self._source = source self._value = None self._listeners = [] def setValue(self, value): self._value = value self._fire_property_change() def getValue(self): return self._value def getAsText(self): if self._value is None: return "null" return str(self._value) def setAsText(self, text): self._value = text self._fire_property_change() def getSource(self): return self._source def addPropertyChangeListener(self, listener): self._listeners.append(listener) def removePropertyChangeListener(self, listener): if listener in self._listeners: self._listeners.remove(listener) def _fire_property_change(self): evt = PropertyChangeEvent(self._source, "", None, self._value) for listener in self._listeners: listener.propertyChange(evt) class PropertyEditorManager(Stub): """java.beans.PropertyEditorManager""" _editors = {} @staticmethod def findEditor(target_type): return PropertyEditorSupport() @staticmethod def registerEditor(target_type, editor_class): PropertyEditorManager._editors[target_type] = editor_class @staticmethod def getEditorSearchPath(): return [] @staticmethod def setEditorSearchPath(path): pass # ============================================================ # EventHandler # ============================================================ class EventHandler(Stub): """java.beans.EventHandler""" def __init__(self, target, action, event_property_name, listener_method_name): super().__init__() self._target = target self._action = action self._event_property_name = event_property_name self._listener_method_name = listener_method_name @staticmethod def create(listener_interface, target, action, event_property_name=None, listener_method_name=None): return target def invoke(self, proxy, method, arguments): if self._target and self._action: action_fn = getattr(self._target, self._action, None) if action_fn: return action_fn() # ============================================================ # ExceptionListener # ============================================================ class ExceptionListener(Stub): """java.beans.ExceptionListener""" def exceptionThrown(self, e): pass # ============================================================ # AppletInitializer # ============================================================ class AppletInitializer(Stub): """java.beans.AppletInitializer""" def initialize(self, applet_bean, bean_context): pass def activate(self, applet_bean): pass # ============================================================ # Beans / Customizer / DesignMode / Visibility # ============================================================ class Beans(Stub): """java.beans.Beans""" @staticmethod def instantiate(cls_loader, bean_name, bean_context=None, bean_arg=None): return None @staticmethod def designTime(): return False @staticmethod def isDesignTime(): return False @staticmethod def setDesignTime(is_design_time): pass @staticmethod def isGuiAvailable(): return False @staticmethod def setGuiAvailable(is_gui_available): pass class Customizer(Stub): """java.beans.Customizer""" def setObject(self, bean): pass def addPropertyChangeListener(self, listener): pass def removePropertyChangeListener(self, listener): pass class DesignMode(Stub): """java.beans.DesignMode""" PROPERTYNAME = "designTime" def isDesignTime(self): return False def setDesignTime(self, design_time): pass class Visibility(Stub): """java.beans.Visibility""" def needsGui(self): return False def dontUseGui(self): pass def okToUseGui(self): pass def avoidingGui(self): return True