Demophone
From JGlade
Under construction
Contents |
Introduction
Demophone is a fictional application, with relativelly simple complexity, to aid the evaluation of GUI builders and toolkits. This simmulates an Internet phone, but don't expect to place a call yet :-)
These are the screenshots of Demophone running on different platforms and toolkits (GTK, Windows and Motif). The application is the same and obtained from a single Glade UI design.
|
|
|
|
State diagram
Building the GUI
This screenshot shows the GUI building process (almost finished) in
Glade.You can see
- the Glade main window, with the demophone project opened
- the Glade palette
- the Properties window, showing the main window's properties
- the Tree view, showing the hierarchy of GTK widgets conforming
the demophone interface
- the demophone main window
Creating the layout
This is the list of widgets that you have to create in order to obtain the desired interface
- main window
- vertical box (size 5)
- textview
- label
- hbox (size 2)
- button Yes
- button No
- table (size 3x4)
- button 1
- button 2
- ...
- button #
- image
- vertical box (size 5)
Step by step
Launch Glade UI designer by clicking on the menu entry or from the shell with
$ glade-2
Glade project
Create a new project using Net GTK+ Project. Go to Project->Options... and set project name and folder.
Main window
Select Window in the GTK+ Basic palette, to create the main window. Then, set Name and Title to demophone in properties.
Vertical box
Layouts in Glade are managed through horizontal and vertical boxes and tables. Select Vertical Box in the palette and set the number of rows to 4.
Text view
Select Textview from the palette and place it in the first row of the previously created Vertical Box. In properties set Name to textviewLCD, Editable to No and Cursor visible to No. By default, the textview is placed inside a scrolledwindow, you can see it in the Widget Tree, accessible through View->Show Widget Tree. Since we don't want scroll bars in our widget, we have to disable them in the scrolledwindow properties. Set H Scroll and V Scroll to Never.
Label
Select Label from the palette and place it in the second row of the Vertical Box. Set Name to labelStatus.
Horizontal Box
We now need an Horizontal Box to put the two action buttons. Select Horizontal Box and place it in the third row of the Vertical Box. Set the Number of columns to 2.
Button Yes
Select Button and place it in the left column of the Horizontal Box. Set Name to buttonYes, and Label to Yes. And set Expand and Fill to Yes in the packing tab.
Button No
Select Button and place it in the right column of the Horizontal Box. Set Name to buttonNo, and Label to No. And set Expand and Fill to Yes in the packing tab.
Table
Select Table and place it in the fourth row of the Vertical Box. Set Number of rows to 4 and Number of columns to 3.
Buttons
Select Button and fill every table cell with a button. Set Name and Label for every button indicating the button number. For example, name the first button button1 with label 1.
For the special case of * and # buttons, name them buttonStar and buttonNumeral respectively.
Image
Let's make some room to add an image at the bottom. Select vbox1 in Widget Tree, and increase the Size from 4 to 5.
Select Image from the palette and add it in the new row. In properties, set Icon to demophone.png.
Finishing touch
You can add borders and spacing to some widgets to improve visibility.
Defining the signals
Signals are the way to connect some event in the widget with functionality inside your code.
This signals have to be defined for the corresponding widgets
- destroy for the main window (in order to exit the application when it is closed)
- clicked on every number, '*' or '#' button, to provide the corresponding actions using handler on_button_clicked.
- clicked on 'Yes' button, using handler on_action_button_clicked.
- clicked on 'No' button using on_action_button_clicked.
To do this, select the corresponding widget (i.e: buttonYes) from Widget Tree, go to the Signals tab in properties and then select the desired signal or event (clicked in this case) in Signal, modify the proposed Handler name into one of the handlers defined in the previous list and press the Add button.
The signal is now connected with the method handler you defined.
Glade definition file
Saving the project you will obtain the Glade XML definition file Demophone.glade. This file is defined in http://glade.gnome.org/glade-2.0.dtd.
Pygtk example
One of the most common approaches is to use Pygtk and its libglade bindings. This can be used as a test.
JGlade example
This example demonstrates the use of JGlade to build the application.
Download software components
Downlod latest JGlade distribution jar, JGlade.jar, from http://sourceforge.net/project/showfiles.php?group_id=153625.
Download latest Demophone distribbution jar, Demophone.jar, from http://sourceforge.net/project/showfiles.php?group_id=153625.
You may also need to download the latest SWT version for you platform from http://eclipse.org/swt.
Extract resources
In the Demophone directory
jar -xvf Demophone.jar resources
Extract runner
In the Demophone directory and depending on your platform
jar -xvf Demophone.jar demophone.sh
or
jar -xvf Demophone.jar demophone.bat
Review settings
Some values can be configured to suit your environment. Check the runner script and edit it if necessary. These are the default settings for Linux and Unix.
#---------------------------------------------------------------------- # Configurable # JAVA_HOME=/opt/java/jdk1.5.0_05 SWTLIBDIR=/opt/java/swt-3.1.1-\$TK-linux-x86/ SWTJAR=$SWTLIBDIR/swt.jar DEMOPHONELIBDIR=. DEMOPHONEJAR=$DEMOPHONELIBDIR/Demophone.jar JGLADELIBDIR=../JGlade JGLADEJAR=$JGLADELIBDIR/JGlade.jar #----------------------------------------------------------------------
Run demophone
Run the corresponding runner for your platform, for example in Linux and Unix
demophone.sh
and you will see something like this.
You can also specify a toolkit option, for exaample to use Motif
demophone.sh --motif
and Demophone will use SWT Motif.
Analyzing Demophone
package demophone;
import jglade.JGlade;
import jglade.JGladeConstructionExeption;
import jglade.toolkit.swt.SwtToolkit;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class Demophone extends JGlade {
/**
* Demophone texview display
*/
private Text textviewLCD;
/**
* Demophone status label
*/
private Label labelStatus;
/**
* Demophone constructor, uses the XML file produced by Glade UI builder to build
* the interface.
*
* @author diego
* @version 0.1
*
* @throws JGladeConstructionExeption
*/
public Demophone() throws JGladeConstructionExeption {
super("resources/demophone.xml");
final Color lcd = new Color(SwtToolkit.getDisplay(), 0xd5, 0xdb, 0xc5);
textviewLCD = (Text)getWidget("textviewLCD");
if ( textviewLCD != null ) {
//textviewLCD.append("\n\n\n");
textviewLCD.setBackground(lcd);
}
labelStatus = (Label)getWidget("labelStatus");
if ( labelStatus != null ) {
labelStatus.setBackground(lcd);
}
// initialize
updateLCD("");
updateStatus("");
// event loop
eventLoop();
}
/**
* Appends the digit n to the information displayed.
*
* @param n the digit to display
*/
private void number(String n) {
updateStatus("");
textviewLCD.append(n);
}
/**
* Peroforms the requested action.
*
* @param a the action to perform
*/
private void action(String a) {
String text = "";
if ( a.equals("Yes") ) {
if ( textviewLCD.getText().equals("") ) {
text = "No number";
}
else {
text = "Calling...";
}
}
else if ( a.equals("No") ) {
updateLCD("");
}
updateStatus(text);
}
private void updateLCD(String text) {
textviewLCD.setText(text);
}
private void updateStatus(String text) {
labelStatus.setText(text);
}
/**
* This is a JGlade signal handler
* @param event the event beign handled
*/
public void on_button_clicked(Event event) {
Button b = (Button)event.widget;
number(b.getText());
}
/**
* This is a JGlade signal handler
* @param event the event beign handled
*/
public void on_action_button_clicked(Event event) {
Button b = (Button)event.widget;
action(b.getText());
}
/**
* @param args
*/
public static void main(String[] args) {
try {
new Demophone();
} catch (JGladeConstructionExeption e) {
System.err.println("Unable to create Demophone interface.");
e.printStackTrace();
}
}
}
- package definition and imports
- class definition, extending JGlade
- widget definition
- constructor
- methods
- signal handlers
- main






