Print

Print


Hi!

I have been trying to implement a simple own Properties Class to be able 
to declare my Properties in a way I like better than declaring lots of 
methods.

Maybe one could think about adding the possibility of Java Annotations 
to declare the domain, description etc.? Or would this break with Masons 
JDK compatbility target?

The disadvantage of reflection would still be that there is not ordering 
of the properties - at least I don't think that reflecting on a class 
would guarantee any ordering of the properties that reflects the 
ordering in the code.

Anyway, I have produce a class derive from sim.util.Properties that 
delivers the information and made my inspected class implement 
Propertied. For the source code see below. It' in Scala but that should 
not be the reason for any of my problems.

When using this combination with SimpleInspector and a Domain-Slider I 
get into an endless loop in SimpleInspector of
- PropertyField.newValue calling
- SimpleInspector.this.state.controller.refresh() calling
- SimpleInspector.updateInspector() calling
- SimpleInspector.generateProperties(start) calling
- PropertyField.newValue calling
...


The responsible lines of code in SimpleInspector.generateProperties are:

if (SimpleInspector.this.state.controller != null)
	SimpleInspector.this.state.controller.refresh();

If I just comment them out everything seems to be just fine. There is 
not problems with the display not refreshing whatsoever.

Strange enough this kind of endless loop does not happen with the 
standard SimpleProperties generated by Reflection. There is some looping 
going on but it stops after some rounds. There has to be some race 
condition or something alike that by chance works out fine. Or is there 
some other reason? I couldn't figure it out.

Any ideas? Maybe this is just a bug. Then it would be fine and 
commenting out the two lines of code above would fix it.

regards
roman

-------------------------
Custom Properties code:
-------------------------

package at.granul.mason

import scala.collection.mutable
import java.lang.reflect.Method
import sim.util.{Properties, Propertied}
import scala.Boolean
import java.lang.Class

import at.granul.mason.Property
import java.text.NumberFormat

/**
  * Created by Roman Seidl on 28.01.14.
  */

trait DeclaredPropertied extends Propertied {
   var ___properties = DeclaredProperties(this)

   override def properties(): Properties = ___properties

   def setProperties(p: PropertyElement*) : DeclaredProperties = 
___properties.setProperties(p :_*)

}

abstract class PropertyElement(nam: String){
   val name = nam
}

case class Property(override val name : String, var title : String = 
null, var domain : AnyRef = null, var isReadOnly : Boolean = false) 
extends PropertyElement(name) {
   if (title == null)
     title = name

   def dom(lower: Long, upper: Long) : Property = {
     domain = new sim.util.Interval(lower, upper)
     this
   }

   def dom(lower: Double, upper: Double) : Property = {
     domain = new sim.util.Interval(lower, upper)
     this
   }

   def dom(dom: Array[String]) : Property = {
     domain = dom
     this
   }


   def caption(tf : String) : Property = title(tf)
   def text(tf : String) : Property = title(tf)
   def title(tf : String) : Property = {
     title = tf
     this
   }

   def readOnly = ro
   def ro : Property = {
     isReadOnly = true
     this
   }

   //override def toString: String = super.toString + " Domain: " + " 
Domain: " + domain + " Field: " + targetField
}


case class DeclaredProperties(obj: Object, p : PropertyElement*) extends 
sim.util.Properties {

   val propertyElements = mutable.Buffer[PropertyElement]()
   val elements = mutable.Buffer[Property]()
   this.setProperties(p :_*)

   var getMethods = mutable.Buffer[Method]()
   var setMethods = mutable.Buffer[Method]()

   def setProperties(p : PropertyElement*) : DeclaredProperties = {
     for (pe <- p.iterator)
       this.+(pe)
     this
   }

   def +(prop : PropertyElement) : DeclaredProperties = {
     propertyElements += prop
     if( prop.isInstanceOf[Property]){
       elements += prop.asInstanceOf[Property]

       val getMethodStub = obj.getClass.getMethods.find(m => {m.getName 
== prop.name || m.getName == ("get" + prop.name.capitalize) || m.getName 
== ("is" + prop.name.capitalize)})
       val getMethod = if(getMethodStub != null) getMethodStub.get else null
       getMethods += getMethod

       val setMethodStub = obj.getClass.getMethods.find(m => {(m.getName 
== prop.name + "_$eq") || m.getName == ("set" + prop.name.capitalize)})
       val setMethod = if(setMethodStub != null) setMethodStub.get else null
       setMethods += setMethod
     }
     this
   }


   def numProperties(): Int = elements.size

   def isVolatile: Boolean = true


   def getValue(index: Int): Object = {
     val method = getMethods(index)
     if(method != null) method.invoke(obj) else null
   }

   def _setValue(index: Int, value: Object): Object = {
/*    if(isReadWrite(index: Int))
     {*/
       var method = setMethods(index)
       if(method != null) {
         method.invoke(obj, value.asInstanceOf[AnyRef])
         getValue(index)
       } else null
/*    }
     getValue(index)*/
   }

   override def getDomain(index: Int): AnyRef = elements(index).domain

   def isReadWrite(index: Int): Boolean = !elements(index).isReadOnly

   def getName(index: Int): String = elements(index).title

   def getType(index: Int): Class[_] = {
     val method = getMethods(index)
     if(method != null) method.getReturnType else null
   }

   override def toString: String = super.toString + " obj: " + obj + " 
elements:"+ propertyElements
}