JavaStates is a Java library that allows defining the internal dynamics of a user interface declaratively using states. It handles cleanup when switching between states and supports concurrent subregions. The simplest example is a two-state "Hello World" application with buttons to switch between displaying "Hello" and "World". Regions and states can be nested. JavaStates ensures defects are avoided by checking state integrity.
2. CREATIVE COMMONS
• This
document is shared under the terms of the Attribution-
Share Alike 2.0 Generic Creative Commons license
• http://creativecommons.org/licenses/by-sa/2.0/
3. WHAT IS JAVASTATES?
• JavaStatesis a Java library that allows for defining the internal
dynamics of a man machine interface declaratively in terms of
states rather than in programmatic ways.
• JavaStatescan be used to implement Java Swing applications,
but also any program based upon objects obeying the Java
Bean conventions (“resource”->getResource/setResource/
isResource), or the Listener API
(addListener,removeListener,getListeners)
4. WHERE DO I GET JAVASTATES?
• JavaStates is shared under the terms of a BSD license.
• https://sourceforge.net/projects/javastates/
• http://laurent.henocque.free.fr/javastates.php
5. STATE INTEGRITY
• The main feature of JavaStates is that the library will take care
for all the cleanup needed when switching from state to state
• JavaStates
also cares for this integrity in the presence of
concurrent (independent) sub regions in states.
• The main advantage is that the interface designer/implementor
concentrates on the specification, under the warranty that the
resulting application will be defect free.
6. THE SIMPLEST TWO STATE
JAVA SWING APPLICATION
public class HelloWorld {
public static void main(String[] args) {
try { new HelloWorld(); } catch(Exception e) { System.out.println(e);}}
HelloWorld() throws Exception{
JFrame mainFrame= new JFrame("HelloWorld");
JButton hellobutton=new JButton("Hello ?");
mainFrame.add(hellobutton);
JavaStates.MAIN_("Main").
req(mainFrame, "Visible", true).
req(mainFrame, "Size", new Dimension(500,100)).
req(mainFrame, "Title", "Hello! World, powered with JavaStates").
lis(mainFrame, WindowListener.class, new WindowAdapter(){
public void windowClosing(WindowEvent e) {System.exit(0); }}).
set(hellobutton,"world").
STATE_("world").
req(hellobutton,"Label","World !").
set(hellobutton,"root").
_STATE("world").
_MAIN().start();
}}
8. INITIALIZING JAVASTATES
• Two initialize JavaStates, and at the same time create a main
region, use the static function JavaStates.MAIN_(String name)
JavaStates.MAIN_("Main")
• The name parameter is the name of the most global region.
• The root state in this region is called “root”.
9. STATE REQUIREMENTS AS
TRIPLES
•A state requirement is a triple: a mandatory setting of a given
resource, of a given object to a certain value. The function
req(Object, String resource, Object value)
• creates such a requirement. For example:
• req(hellobutton, “Label”, “World!”)
• JavaStates expects a Java Bean api to exist on target object:
10. CREATING STATES
• States are declared using the function
STATE_(String name)
• Statedeclarations must be closed at the end, like parentheses,
using the function
_STATE(String name)
• JavaStates
checks the identity of the names. This prevents from
copy/paste errors or forgotten/extraneous closures.
11. STATES AS PLACEHOLDERS
• Statesare placeholders for requirements and other
states.There are no limits to the embedding of states.
• Embedded states inherit, and may override the requirements
from enclosing states.
• Embedding states obeys the UML State Diagrams
conventions, borrowed from Harel Statecharts
• State requirements have no equivalent in UML
12. LISTENER REQUIREMENTS
• Interface dynamics are implemented in Java by using listeners.
A listener requirement is set using the function
lis(Object, Class<?>listener, Object value)
• creates such a requirement. For example:
lis(mainFrame, WindowListener.class, new
WindowAdapter(){...}).
• JavaStates supports listener requirements by fully relying upon
introspection. Any class having a resource that obeys the
Listener convention can be used: if there exist three functions
getListener, addListener, getListeners.
13. CHANGING STATE
•A function for creating Action Listeners that change state is
predefined:
• set(Object target, String name)
• ”set” expects target to implement the Java AbstractButton
interface. It does not use introspection.
• In
a state that specifies ‘set(hellobutton,"world")’, the
action listener of object ‘hello button’ has the effect of
changing to state “world”.
14. SETTING THE ROOT STATE
• Every region owns a “root” state, placeholder for all other
states
• When the state containing this region is set, the region state is
by default set to this root state.
• When explicit setting to this root state is needed, one can use
the function reset(Object target). This is almost
equivalent to set(Object target,”root”), with the
advantage of being independent from a change in the root
state name
15. CREATING REGIONS
• Regions are declared using the function
REGION_(String name)
• Regiondeclarations must be closed at the end, like
parentheses, using the function
_REGION(String name)
• JavaStates
checks the identity of the names. This prevents from
copy/paste errors or forgotten/extraneous closures.
16. THE TWO REGION DEMO
JavaStates.MAIN_("Main").
req(mainFrame, "Visible", true).
req(mainFrame, "Size", new Dimension(500,100)).
req(mainFrame, "Title", "Two Region demo, powered with JavaStates").
lis(mainFrame, WindowListener.class, new WindowAdapter() {...}).
set(button1,"world").
STATE_("world").
req(button1,"Label","World Region 1").
reset(button1).
_STATE("world").
REGION_("2").
set(button2,"world").
STATE_("world").
req(button2,"Label","World Region 2").
reset(button2).
_STATE("world").
_REGION("2").
_MAIN().start();
18. LAUNCHING JAVASTATES
• Launching JavaStates is performed using the function
start()
• This call sets the main region to its root state. Any subregion
in this state gets started as well, and so on recursively.
19. SETTING AN INITIAL STATE
• It often happens that the desired initial state in a region is not
its root state.
• To specify the root state in a region, use the function
initial (String name)
• The name parameter must match a valid state name in the
region at run time. “initial” may be called before the state is
declared (usually just after the region is created, and before
any requirement or state is declared.
20. TO CONTINUE
• You may check and then adapt the full featured Editor demo.
21. CONCLUSION, FURTHER
LINKS
• JavaStates offers state support in Java Interface development.
• Further details, and the programs are present at
• http://sourceforge.net/projects/javastates
• http://laurent.henocque.free.fr