(For more resources on this topic, see here.)
qooxdoo uses the generic terminology of the graphical user interface. So, it is very easy to understand the concepts involved in it.. The basic building block in qooxdoo is termed a widget. Each widget (GUI component) is a subclass of the Widget class. A widget also acts as a container to hold more widgets. Wherever possible, grouping of the widgets to form a reusable component or custom widget is a good idea. This allows you to maintain consistency across your application and also helps you to build the application quicker than the normal time. It also increases maintainability, as you need to fix the defect at only one place. qooxdoo provides a set of containers too, to carry widgets, and provides public methods to manage.
Let’s start with the framework’s class hierarchy:
qooxdoo framework abstracts the common functionalities required by all the widgets into a few base classes, so that it can be reused by any class through object inheritance. Let’s start with these base classes.
Object is the base class for all other qooxdoo classes either directly or indirectly. The qx.core.Object class has the implementation for most of the functionalities, such as, object management, logging, event handling, object-oriented features, and so on.
A class can extend the qx.core.Object class to get all the functionalities defined in the this class. When you want to add any functionality to your class, just inherit the Object class and add the extra functionalities in the subclass.
The major functionalities of the Object class are explained in the sections that follow.
The Object class provides the following methods for object management, such as, creation, destruction, and so on:
The Object class provides the following methods for event creation, event firing, event listener, and so on:
The Object class provides the following methods to log the message at different levels:
Also, the Object class provides the methods for setters and getters for properties, and so on.
LayoutItem is the super most class in the hierarchy. You can place only the layout items in the layout manager. LayoutItem is an abstract class. The LayoutItem class mainly provides properties, such as, height, width, margins, shrinking, growing, and many more, for the item to be drawn on the screen. It also provides a set of public methods to alter these properties. Check the API documentation for a full set of class information.
Next in the class hierarchy is the Widget class, which is the base class for all the GUI components. Widget is the super class for all the individual GUI components, such as, button, text field, combobox, container, and so on, as shown in the class hierarchy diagram. There are different kinds of widgets, such as, containers, menus, toolbars, form items, and so on; each kind of widgets are defined in different namespaces. We will see all the different namespaces or packages, one-by-one, in this article.
A widget consists of at least three HTML elements. The container element, which is added to the parent widget, has two child elements—the decoration and the content element. The decoration element decorates the widget. It has a lower z-index and contains markup to render the widget’s background and border styles, using an implementation of the qx.ui.decoration.IDecorator interface. The content element is positioned inside the container element, with the padding, and contains the real widget element.
Common widget properties include:
The methods to modify this property are show(), hide(), and exclude(). The methods to check the status are isVisible(), isHidden(), and isExcluded().
The starting point for a qooxdoo application is to write a custom application class by inheriting one of the qooxdoo application classes in the qx.application namespace or package. Similar to the main method in Java, the qooxdoo application also starts from the main method in the custom application class.
qooxdoo supports three different kinds of applications:
Whenever a user creates an application with the Python script, a custom application class gets generated with a default main method. Let’s see the custom application class generated for our Team Twitter application. After generation, the main function code is edited to add functionality to communicate to the RPC server and say “hello” to the qooxdoo world. The following code is the content of the Application.js class file with an RPC call to communicate with the server:
/** * This is the main application class of your custom application "teamtwitter" */qx.Class.define("teamtwitter.Application", { extend : qx.application.Standalone, members : { /** * This method contains the initial application code and gets called during startup of the application * @lint ignoreDeprecated(alert) */main : function() { // Call super class this.base(arguments); // Enable logging in debug variant if (qx.core.Variant.isSet("qx.debug", "on")) { // support native logging capabilities, e.g. Firebug for Firefox qx.log.appender.Native; // support additional cross-browser console. Press F7 to toggle visibility qx.log.appender.Console; } /* Below is your actual application code... */// Create a button var button1 = new qx.ui.form.Button("First Button", "teamtwitter/test.png"); // Document is the application root var doc = this.getRoot(); // Add button to document at fixed coordinates doc.add(button1, {left: 100, top: 50}); // Add an event listener button1.addListener("execute", function(e) { var rpc = new qx.io.remote.Rpc(); rpc.setCrossDomain( false ); rpc.setTimeout(1000); var host = window.location.host; var proto = window.location.protocol; var webURL = proto + "//" + host + "/teamtwitter/.qxrpc"; rpc.setUrl(webURL); rpc.setServiceName("qooxdoo.test"); rpc.callAsync(function(result, ex, id){ if (ex == null) { alert(result); } else { alert("Async(" + id + ") exception: " + ex); } }, "echo", "Hello to qooxdoo World!"); }); } } });
We’ve had an overview of the class hierarchy of the qooxdoo framework and got to know the base classes for the widgets. Now, we have an idea of the core functionalities available for the widgets, the core properties of the widgets, and the methods to manage those properties. We’ve received more information on the application in the qooxdoo framework.
Now, it is time to learn about the containers.
A container is a kind of widget. It holds multiple widgets and exposes public methods to manage their child widgets. One can configure a layout manager for the container to position all the child widgets in the container. qooxdoo provides different containers for different purposes.
Let’s check different containers provided by the qooxdoo framework and understand the purpose of each container. Once you understand the purpose of each container, you can select the right container when you design your application.
Whenever the content widget size (width and height) is larger than the container size (width and height), the Scroll container provides vertical, or horizontal, or both scroll bars automatically. You have to set the Scroll container’s size carefully to make it work properly. The Scroll container is used most commonly if the application screen size is large.
The Scroll container has a fixed layout and it can hold a single child. So, there is no need to configure the layout for this container.
The following code snippet demonstrates how to use the Scroll container:
// create scroll container
var scroll = new qx.ui.container.Scroll().set({
width: 300,
height: 200
});
// adding a widget with larger widget and height of the scroll
scroll.add(new qx.ui.core.Widget().set({
width: 600,
minWidth: 600,
height: 400,
minHeight: 400
})); // add to the root widget.
this.getRoot().add(scroll);
The GUI look for the preceding code is as follows:
The Stack container puts a widget on top of an old widget. This container displays only the topmost widget. The Stack container is used if there are set of tasks to be carried out in a flow. An application user can work on each user interface one-by-one in order.
The following code snippet demonstrates how to use the Stack container:
// create stack container
var stack = new qx.ui.container.Stack();
// add some children
stack.add(new qx.ui.core.Widget().set({
backgroundColor: "red"
}));
stack.add(new qx.ui.core.Widget().set({
backgroundColor: "green"
}));
stack.add(new qx.ui.core.Widget().set({
backgroundColor: "blue"
}));
this.getRoot().add(stack);
The GUI look for the preceding code is as follows:
Resizer is a container that gives flexibility for resizing at runtime. This container should be used only if you want to allow the application user to dynamically resize the container.
The following code snippet demonstrates how to use the Resizer container:
var resizer = new qx.ui.container.Resizer().set({
marginTop : 50,
marginLeft : 50,
width: 200,
height: 100
});
resizer.setLayout(new qx.ui.layout.HBox());
var label = new qx.ui.basic.Label("Resize me <br>I'm resizable");
label.setRich(true);
resizer.add(label);
this.getRoot().add(resizer);
The GUI look for the preceding code is as follows:
This is a generic container. If you do not want any of the specific features, such as, resize on runtime, stack, scroll, and so on, but just want a container, you can use this container. This is one of the mostly used containers.
The following code snippet demonstrates the Composite container usage. A horizontal layout is configured to the Composite container. A label and a text field are added to the container. The horizontal layout manager places them horizontally:
// create the composite
var composite = new qx.ui.container.Composite()
// configure a layout.
composite.setLayout(new qx.ui.layout.HBox());
// add some child widgets
composite.add(new qx.ui.basic.Label("Enter Text: "));
composite.add(new qx.ui.form.TextField());
// add to the root widget.
this.getRoot().add(composite);
The GUI look for the preceding code is as follows:
Window is a container that has all features, such as, minimize, maximize, restore, and close. The icons for these operations will appear on the top-right corner. Different themes can be set to get the look and feel of a native window within a browser. This window is best used when an application requires Multiple Document Interface (MDI) or Single Document Interface (SDI). The following code snippet demonstrates a window creation and display:
var win = new qx.ui.window.Window("First Window");
win.setWidth(300);
win.setHeight(200);
// neglecting minimize button
win.setShowMinimize(false);
this.getRoot().add(win, {left:20, top:20});
win.open();
The GUI look for the preceding code is as follows:
The TabView container allows you to display multiple tabs, but only one tab is active at a time. The TabView container simplifies the GUI by avoiding the expansive content spreading to multiple pages, with a scroll. Instead, the TabView container provides the tab title buttons to navigate to other tabs. You can group the related fields into each tab and try to avoid the scroll by keeping the most-used tab as the first tab and making it active. Application users can move to other tabs, if required.
TabView is the best example for the stack container usage. It stacks all pages one over the other and displays one page at a time. Each page will have a button at the top, in a button bar, to allow switching the page. Tabview allows positioning the button bar on top, bottom, left, or right. TabView also allows adding pages dynamically; a scroll appears when the page buttons exceed the size.
The following code snippet demonstrates the usage of TabView:
var tabView = new qx.ui.tabview.TabView();
// create a page
var page1 = new qx.ui.tabview.Page("Layout",
"icon/16/apps/utilitiesterminal.png");
// add page to tabview
tabView.add(page1);
var page2 = new qx.ui.tabview.Page("Notes",
"icon/16/apps/utilitiesnotes.png");
page2.setLayout(new qx.ui.layout.VBox());
page2.add(new qx.ui.basic.Label("Notes..."));
tabView.add(page2);
var page3 = new qx.ui.tabview.Page("Calculator", "icon/16/apps/
utilities-calculator.png");
tabView.add(page3);
this.getRoot().add(tabView, {edge : 0});
The GUI look for the preceding code is as follows:
GroupBox groups a set of form widgets and shows an effective visualization with the use of a legend, which supports text and icons to describe the group. As with the container, you can configure any layout manager and allow adding a number of form widgets to the GroupBox.
Additionally, it is possible to use checkboxes or radio buttons within the legend. This allows you to provide group functionalities such as selecting or unselecting all the options in the group. This feature is most important for complex forms with multiple choices.
The following code snippet demonstrates the usage of GroupBox:
// group box
var grpBox = new qx.ui.groupbox.GroupBox("I am a box");
this.getRoot().add(grpBox, {left: 20, top: 70});
// radio group box
var rGrpBox = new qx.ui.groupbox.RadioGroupBox("I am a box");
rGrpBox.setLayout(new qx.ui.layout.VBox(4));
rGrpBox.add(new qx.ui.form.RadioButton("Option1"));
rGrpBox.add(new qx.ui.form.RadioButton("Option2"));
this.getRoot().add(rGrpBox, {left: 160, top: 70});
// check group box
var cGrpBox = new qx.ui.groupbox.CheckGroupBox("I am a box");
this.getRoot().add(cGrpBox, {left: 300, top: 70});
The GUI look for the preceding code is as follows:
We got to know the different containers available in the qooxdoo framework. Each container provides a particular functionality. Based on the information displayed on the GUI, you should choose the right container to have better usability of the application.
Containers are the outer-most widgets in the GUI. Once you decide on the containers for your user interface, the next thing to do is to configure the layout manager for the container. Layout manager places the child widgets in the container, on the basis of the configured layout manager’s policies. Now, it’s time to learn how to place and arrange widgets inside the container, that is, how to lay out the container.
I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…
Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…
Once we learn how to deploy an Ubuntu server, how to manage users, and how…
Key-takeaways: Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…
While developing a web application, or setting dynamic pages and meta tags we need to deal with…
Software architecture is one of the most discussed topics in the software industry today, and…