Jini Seminar by Bill Venners
Jini Service UIs
Lecture Handout
Agenda
- Brief History
- Technical Overview
- Whiz-Bang Demo
- API Details
- Implications
- Yet Another Demo
Service UI Participants
- Ken Arnold
- Michel Burger
- Jeffrey Carpenter
- Alvin Chin
- James Cotsios
- Bill Day
- Cees de Groot
- Haruo Fukuda
- Keith Goethert
- Brian Jeltima
- Bruce Jackson
- Dave Judd
- Alan Kaminsky
- James Kempf
|
- Peter Korn
- Adam Levin-Delson
- Gregory M. Lewis
- Sing Li
- Michael Los
- John McClain
- Bruno Melloni
- Mike Morris
- Uttam Narsu
- Jan Newmarch
- Wiven Nettles
- Olufisayo Omojokun
- Hugo Jose Pinto
- Sung Lu Ruo
|
- Harry Saddler
- Jason Sando
- Michael Sargent
- Bob Scheifler
- Jerome Scheuring
- Maurice Schoenmakers
- James Staten
- Keith B. Thompson
- Jimmy Torres
- Bill Venners
- Jim Waldo
- Willie Walker
- Greg Wonderly
- Phong Yau
|
Bundles of Functionality
Client UI
Service UI
The ServiceUI Project
-
To use a service UI, clients need prior knowledge
-
We needed a standard way to:
- Associate UIs with services
- Access those UIs at the client
User Adapters
UI Descriptors
- UI provider describes UIs
- Client decides
Class UIDescriptor
package net.jini.lookup.entry;
// imports...
public class UIDescriptor extends AbstractEntry {
public String role;
public String toolkit;
public Set attributes;
public MarshalledObject factory;
//...
}
UI Role
- Describe purpose of UI
- Examples: main, admin, about
- UIDescriptor.role = fully qualified name of role interface
package net.jini.lookup.ui;
public interface MainUI {
String ROLE = "net.jini.lookup.ui.MainUI";
}
The Role Interface
-
UI object implements the role interface
-
MainUI, AdminUI, and AboutUI are tag interfaces
-
Role interfaces can declare methods
package com.artima.calcserv;
import net.jini.lookup.ui.MainUI;
public class CalcJFrame extends JFrame
implements MainUI {
//...
}
UI Attributes
-
UIDescriptor.attributes = a set of objects that describe the UI
-
Four attribute classes defined:
- AccessibleUI
- Locales
- RequiredPackages
- UIFactoryTypes
AccessibleUI Attribute
-
Says two things about the UI:
- Implements javax.accessibility.Accessible
- Programmer did the necessary work
package net.jini.lookup.ui.attribute;
public class AccessibleUI
implements java.io.Serializable {
public boolean equals(Object o) {}
public int hashCode() {}
}
Locales Attribute
-
Describes supported locales
package net.jini.lookup.ui.attribute;
import java.util.*;
public class Locales
implements java.io.Serializable {
public boolean isLocaleSupported(Locale locale) {}
public Locale getFirstSupportedLocale(
List locales) {}
public Iterator iterator() {}
public Set getLocales() {}
//...
}
RequiredPackages Attribute
- Lists packages required by the UI:
- fully qualified package name
- package version number
package net.jini.lookup.ui.attribute;
import java.util.*;
public class RequiredPackages
implements java.io.Serializable {
public Iterator iterator() {}
public String getVersion(String packageName) {}
public Map getRequiredPackages() {}
}
UI Factories
-
Don't want to serialize UI objects
-
Instead, serialize a UI factory
-
To get the UI, Client invokes factory method
-
Factory methods declared in UI factory interfaces:
getJFrame()
declared in interface JFrameFactory
getDialog()
declared in DialogFactory
UIFactoryTypes Attribute
-
Lists UI factory interfaces implemented by the factory object
- (Factory is stored in
UIDescriptor.factory
)
package net.jini.lookup.ui.attribute;
import java.util.*;
public class UIFactoryTypes
implements java.io.Serializable {
public boolean isAssignableTo(Class classObj) {}
public Iterator iterator() {}
public Set getTypeNames() {}
}
UI Toolkit
-
UIDescriptor.toolkit
= package name of primary UI toolkit used by UI
-
Enables clients to narrow search for services based on UIs offered
UI Factory Interfaces
- Family of interfaces, each with targeted factory methods:
- AWT
DialogFactory
FrameFactory
PanelFactory
WindowFactory
- Swing
JDialogFactory
JFrameFactory
JComponentFactory
JWindowFactory
JFrameFactory
package net.jini.lookup.ui.factory;
import javax.swing.JFrame;
public interface JFrameFactory
extends java.io.Serializable {
String TOOLKIT = "javax.swing";
String TYPE_NAME =
"net.jini.lookup.ui.factory.JFrameFactory";
JFrame getJFrame(Object roleObject);
}
Separating Codebases
- Must not force clients to download JAR files for UI's they'll never use
public String role;
public String toolkit;
public Set attributes;
public MarshalledObject factory;
Marshalling the UI Factory
UIDescriptor descrip = new UIDescriptor();
Class c = RMIClassLoader.loadClass(
"http://minovia:8086/calcjframe.jar",
"com.artima.calculator.ui.CalcJFrameFactory");
Object factory = c.newInstance();
descrip.factory = new MarshalledObject(factory);
Unmarshalling the UI Factory
- Client can call getUIFactory() on UIDescriptor
public final Object getUIFactory(
final ClassLoader parentLoader)
throws IOException, ClassNotFoundException {}
- Must pass a class loader that can load the classes
of the role object
Object uiFactory = selectedDescriptor.getUIFactory(
serviceItem.service.getClass().getClassLoader());
Generating the UI
- Client invokes a factory method, passing in the role object
JFrameFactory swingJFrameFactory = (JFrameFactory) uiFactory;
JFrame jf = swingJFrameFactory.getJFrame(serviceItem);
jf.setLocation(100, 100);
jf.setVisible(true);
//...
UI Talks to the Service
public class CalcPanel extends Panel {
private CalculatorService calcService;
public CalcPanel(CalculatorService cs) {
this.calcService = cs;
//...
Conclusion
- Can add new roles, factories, and attributes
- Services can be used by both people and software
- Can create different UIs for different client devices
- More natural UIs than web pages