A few months before JavaOne everyone in our team is busy preparing for JavaOne related project milestones, a few weeks after JavaOne everyone is still on vacation or coming back from vacation. So we didn't have much of a QA team before/after JavaOne...
That is my personal excuse for not making our JavaOne deadline for the next LWUIT drop, I hope we can make the drop soon enough though.
We also have a video
Tuesday, June 16, 2009
Sunday, June 7, 2009
JavaOne is finally over but I'm still stuck in SF
Here in an interview I did on the J1 pavilion show floor. We had a session and a BoF and I hope to post more about both of these when I get the time.
Right now I'm somwhat upset since I missed my flight back home due to misreading my e-ticket (how stupid is that...). In the meantime everyone in our team is taking some time off so going ahead with the new release for JavaOne is a no go for now. I hope we can have a drop in the next couple of weeks, there are quite a few bugs in the new LWUIT designer but at least I have a new Lenovo instead of my highly problematic Mac so I can get some work done faster...
Just for a general information for those of you who couldn't attend, we demoed a chat client which we "pimped" to the extreme and we intend to release the full source code and quite a bit of explanation on how exactly we did it via this blog. Now I need to start preparing for Java Developer Days...
Right now I'm somwhat upset since I missed my flight back home due to misreading my e-ticket (how stupid is that...). In the meantime everyone in our team is taking some time off so going ahead with the new release for JavaOne is a no go for now. I hope we can have a drop in the next couple of weeks, there are quite a few bugs in the new LWUIT designer but at least I have a new Lenovo instead of my highly problematic Mac so I can get some work done faster...
Just for a general information for those of you who couldn't attend, we demoed a chat client which we "pimped" to the extreme and we intend to release the full source code and quite a bit of explanation on how exactly we did it via this blog. Now I need to start preparing for Java Developer Days...
Monday, June 1, 2009
Just Arrived At JavaOne
Make sure to sign up to Chen and my sessions TS-3895 if you attend JavaOne, this session is a more detailed "Pimp My LWUIT" sort of session and we guarantee some amusing special effects. We have a new demo made specifically for this talk which will hopefully redefine (again) what people do and attempt to do in LWUIT.You can also meet and talk with Chen and myself in BOF-4551 that very night which will be less formal and give you time to ask us any questions you might have on your mind.
You can also come and talk to us or other guys within the Java Utopia/java.net areas in the pavillion. Its a great opertunity to meet lots of other guys working on mobile, embedded and open source within Sun right now.
Monday, May 25, 2009
Some Recent Videos
This is my 100th post so forgive me if I slack a little with JavaOne coming and some other personal things I'm doing right now... There are several cool you tube videos which people posted in the last couple of months and also some nice news which I didn't really post about. First you should check out the featured app section of the lwuit site. It is hidden away within the site and most people sadly don't notice it, Meirav and Martin worked allot to give it makeover and it looks stunning.
On the right you can see the long awaited walkthrough video from majimob for the MajiPic application and its features. Bellow you can see a great video from Alex showing off a 3D style carousel in LWUIT:
See you guys at JavaOne Chen and Myself will be hosting a session and a BOF on Thurday, Terrence has some nice coverage for what to do at the conference. If you are there you can come meet both Chen and myself in:
TS-3895: Swing Filthy-Rich Clients on Mobile Devices with Lightweight User Interface Toolkit (LWUIT)
BOF-4551: Lightweight User Interface Toolkit (LWUIT): Meet the Developers
On the right you can see the long awaited walkthrough video from majimob for the MajiPic application and its features. Bellow you can see a great video from Alex showing off a 3D style carousel in LWUIT:
See you guys at JavaOne Chen and Myself will be hosting a session and a BOF on Thurday, Terrence has some nice coverage for what to do at the conference. If you are there you can come meet both Chen and myself in:
TS-3895: Swing Filthy-Rich Clients on Mobile Devices with Lightweight User Interface Toolkit (LWUIT)
BOF-4551: Lightweight User Interface Toolkit (LWUIT): Meet the Developers
Monday, April 27, 2009
Why Do You Need A Variable Sized List?
Last week the forum member juliofabio sent this gorgeous looking video to the forum showing a variable size list component. This looks really stunning and shows off how much you can do with LWUIT when you put your mind to it.
What I'm not exactly sure about is why did he choose to use a List?
Why not container and components like I used in my recent Tree demo?
Why List? Even if we think of our data as a list it might not always be appropriate for a list component.
Specifically in this case the set of elements within the "list" seem to be predefined and small hence there is no advantage to using a model. In fact I would assume that writing that code using a model and renderer paradigm would be very unintuitive. This set will never reach a very large size so the advantages of a huge million element list won't be realized either. It seems from the demo that even list animations were disabled, this is something that can be acheived using containers though.
Using Container.replace() can allow for most of the special effects within this list and can provide even more impressive effects (such as 3d). Building something like that can be trivial without getting into all of the complexities related to the list component, so why would someone want such a list?
What I'm not exactly sure about is why did he choose to use a List?
Why not container and components like I used in my recent Tree demo?
Why List? Even if we think of our data as a list it might not always be appropriate for a list component.
Specifically in this case the set of elements within the "list" seem to be predefined and small hence there is no advantage to using a model. In fact I would assume that writing that code using a model and renderer paradigm would be very unintuitive. This set will never reach a very large size so the advantages of a huge million element list won't be realized either. It seems from the demo that even list animations were disabled, this is something that can be acheived using containers though.
Using Container.replace() can allow for most of the special effects within this list and can provide even more impressive effects (such as 3d). Building something like that can be trivial without getting into all of the complexities related to the list component, so why would someone want such a list?
Thursday, April 23, 2009
JavaVerified: LWUIT's Killer Feature?
I'm generally very excited about Nokia's upcoming Ovi store, I think it has the potential to empower smaller developers to deliver content to end users.One of the decisions made by Nokia is to go with Java Verified for the QA and signing of application for Ovi. Java Verified has an issue with requiring a cost for every tested device & every failure. This cost can become remarkably high the more devices need certification/signing, here LWUIT really shines. Its approach of "One JAR for all devices" makes a world of difference in the Java Verified cost for signing, it can make the difference between turning a profit and losing money when publishing smaller applications.
I've always viewed LWUIT as a tool to assist the smaller shops and individual hackers to reach mass market device deployment and this is a concrete example of this perspective.
Tuesday, April 14, 2009
LWUIT Model Tree
Since the forum is down (as usual) my responses to some of the comments in the forum just never made it past the mailing list, one of the questions in the forum that comes up every now and again is "how to create a tree in LWUIT?"
We get this question every now and again and generally our response is that we don't but would like to get such a contribution. However, looking at our samples it seems that most of our component building explanations revolve around "small" components rather than composites which would fit a tree much better.
A composite component is really a Container which we would assemble into a specialized component by tailoring together smaller components. Naturally we could also perform custom painting for such a composite but that often defeats the purpose...
These components aren't suitable for everything but for things such as a tree we gain several huge advantages by using Container nesting to build a tree:
Lets go strait to the code, first we need the model:
Then we would like the implementation:
We get this question every now and again and generally our response is that we don't but would like to get such a contribution. However, looking at our samples it seems that most of our component building explanations revolve around "small" components rather than composites which would fit a tree much better.
A composite component is really a Container which we would assemble into a specialized component by tailoring together smaller components. Naturally we could also perform custom painting for such a composite but that often defeats the purpose...
These components aren't suitable for everything but for things such as a tree we gain several huge advantages by using Container nesting to build a tree:
- We represent the nodes using custom components allowing subclasses to manipulate the look of the tree to a great degree.
- We hardly need to write any code and styles, touch support, keyboard navigation etc. are all built in
- We can leverage transitions and component nesting for really stunning effects
Lets go strait to the code, first we need the model:
/**I think thats pretty self explanitory...
* Arranges tree node objects, a node can essentially be anything
*
* @author Shai Almog
*/
interface TreeModel {
/**
* Returns the child objects representing the given parent, null should return
* the root objects
*/
public Vector getChildren(Object parent);
/**
* Is the node a leaf or a folder
*/
public boolean isLeaf(Object node);
}
Then we would like the implementation:
class Node {Thats a bit long and tedious but its mostly unrelated to LWUIT, the main code is the tree component code which is really rather simple:
Object[] children;
String value;
public Node(String value, Object[] children) {
this.children = children;
this.value = value;
}
public String toString() {
return value;
}
}
TreeModel model = new TreeModel() {
Node[] sillyTree = {
new Node("Root 1", new Node[] {
new Node("Child 1", new Node[] {
new Node("Gand Child 1", new Node[] {
}),
new Node("Gand Child 2", new Node[] {
}),
new Node("Gand Child 3", new Node[] {
}),
new Node("Gand Child 4", new Node[] {
}),
}),
new Node("Child 2", new Node[] {
new Node("Something Else", new Node[] {
}),
new Node("More of the same", new Node[] {
}),
}),
new Node("Child 3", new Node[] {
}),
new Node("Child 4", new Node[] {
}),
}),
new Node("Root 2", new Node[] {
new Node("Something Else", new Node[] {
}),
new Node("More of the same", new Node[] {
}),
}),
new Node("Root 3", new Node[] {
new Node("Something Else", new Node[] {
}),
new Node("More of the same", new Node[] {
}),
}),
new Node("Root 4", new Node[] {
}),
};
/**Then all we need is to use it in order to produce the video on the right:
* LWUIT Tree component sample
*
* @author Shai Almog
*/
public class TreeComponent extends Container {
private static final String KEY_OBJECT = "TREE_OBJECT";
private static final String KEY_PARENT = "TREE_PARENT";
private static final String KEY_EXPANDED = "TREE_NODE_EXPANDED";
private static final String KEY_DEPTH = "TREE_DEPTH";
private ActionListener expansionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Component c = (Component)evt.getSource();
Object e = c.getClientProperty(KEY_EXPANDED);
if(e != null && e.equals("true")) {
collapseNode(c);
} else {
expandNode(c);
}
}
};
private TreeModel model;
private Image folder;
private Image nodeImage;
private int depthIndent = 15;
public TreeComponent(TreeModel model) {
try {
this.model = model;
folder = Image.createImage("/folder.png");
nodeImage = Image.createImage("/page_white.png");
setLayout(new BoxLayout(BoxLayout.Y_AXIS));
buildBranch(null, 0, this);
setScrollableY(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void expandNode(Component c) {
c.putClientProperty(KEY_EXPANDED, "true");
int depth = ((Integer)c.getClientProperty(KEY_DEPTH)).intValue();
Container parent = c.getParent();
Object o = c.getClientProperty(KEY_OBJECT);
Container dest = new Container(new BoxLayout(BoxLayout.Y_AXIS));
Label dummy = new Label();
parent.addComponent(BorderLayout.CENTER, dummy);
buildBranch(o, depth, dest);
parent.replace(dummy, dest, CommonTransitions.createSlide(CommonTransitions.SLIDE_VERTICAL, true, 300));
}
private void collapseNode(Component c) {
c.putClientProperty(KEY_EXPANDED, null);
Container p = c.getParent();
for(int iter = 0 ; iter < p.getComponentCount() ; iter++) {
if(p.getComponentAt(iter) != c) {
Label dummy = new Label();
p.replaceAndWait(p.getComponentAt(iter), dummy, CommonTransitions.createSlide(CommonTransitions.SLIDE_VERTICAL, false, 300));
p.removeComponent(dummy);
}
}
}
/**
* Adds the child components of a tree branch to the given container.nt
*/
protected void buildBranch(Object parent, int depth, Container destination) {
Vector children = model.getChildren(parent);
int size = children.size();
Integer depthVal = new Integer(depth + 1);
for(int iter = 0 ; iter < size ; iter++) {
Object current = children.elementAt(iter);
Button nodeComponent = createNodeComponent(current, depth);
if(model.isLeaf(current)) {
destination.addComponent(nodeComponent);
} else {
Container componentArea = new Container(new BorderLayout());
componentArea.addComponent(BorderLayout.NORTH, nodeComponent);
destination.addComponent(componentArea);
nodeComponent.addActionListener(expansionListener);
}
nodeComponent.putClientProperty(KEY_OBJECT, current);
nodeComponent.putClientProperty(KEY_PARENT, parent);
nodeComponent.putClientProperty(KEY_DEPTH, depthVal);
}
}
protected Button createNodeComponent(Object node, int depth) {
Button cmp = new Button(node.toString());
if(model.isLeaf(node)) {
cmp.setIcon(nodeImage);
} else {
cmp.setIcon(folder);
}
updateNodeComponentStyle(cmp.getSelectedStyle(), depth);
updateNodeComponentStyle(cmp.getUnselectedStyle(), depth);
return cmp;
}
protected void updateNodeComponentStyle(Style s, int depth) {
s.setBorder(null);
s.setPadding(LEFT, depth * depthIndent);
}
}
Form treeForm = new Form("Tree Test");
treeForm.setLayout(new BorderLayout());
TreeComponent tree = new TreeComponent(model);
treeForm.addComponent(BorderLayout.CENTER, tree);
treeForm.setScrollable(false);
treeForm.show();
Subscribe to:
Posts (Atom)