Statusbars

A statusbar is a widget that usually is displayed along the bottom of the main application window and is used to display helpful text messages to the user. The GTK implementation of a statusbar works like a FIFO queue. Messages are "pushed" on the statusbar and are "popped" off the statusbar. Let's extend the example and add a statusbar.

Example 4-2. Third.java - second take


import gtk.*;
import gnome.*;

public class Third {
    private GnomeApp app = null;
    private GtkToolbar toolbar = null;
    private GtkStatusbar statusbar = null;
    private int contextID = 0;
    public static final String appVersion = "0.1";

    public Third() {
	createMainWindow();
	createMenus();
	createToolbar();
	createStatusbar();
    }

    private void createMainWindow() {
	app = new GnomeApp("Third", "Third App");
	app.setPolicy(false, true, false);
	app.setWmclass("Third", "ThirdApp");
	app.setUsize(200, 200);
	app.signal_connect("delete_event", this);
	app.signal_connect("destroy", this);
	app.show();
    }

    private void createMenus() {
	GtkMenuBar menubar = new GtkMenuBar();
	GtkMenuItem file = new GtkMenuItem("File");
	GtkMenuItem help = new GtkMenuItem("Help");
	menubar.append(file);
	menubar.append(help);
	
	// finish the file menu
	GtkMenu fileMenu = new GtkMenu();
	GtkMenuItem fileNew = new GtkMenuItem("New");
	GtkMenuItem fileOpen = new GtkMenuItem("Open");
	GtkMenuItem fileSave = new GtkMenuItem("Save");
	GtkMenuItem fileSaveAs = new GtkMenuItem("Save As");
	GtkMenuItem fileExit = new GtkMenuItem("Exit");
	fileNew.signal_connect("activate", "fileNew", this);
	fileOpen.signal_connect("activate", "fileOpen", this);
	fileSave.signal_connect("activate", "fileSave", this);
	fileSaveAs.signal_connect("activate", "fileSaveAs", this);
	fileExit.signal_connect("activate", "fileExit", this);
	file.setSubmenu(fileMenu);
	fileMenu.append(fileNew);
	fileMenu.append(fileOpen);
	fileMenu.append(fileSave);
	fileMenu.append(fileSaveAs);
	fileMenu.append(fileExit);
	// now display it
	fileNew.show();
	fileOpen.show();
	fileSave.show();
	fileSaveAs.show();
	fileExit.show();
	file.show();
	
	// finish the help menu
	GtkMenu helpMenu = new GtkMenu();
	GtkMenuItem helpAbout = new GtkMenuItem("About");
	helpAbout.signal_connect("activate", "helpAbout", this);
	help.setSubmenu(helpMenu);
	helpMenu.append(helpAbout);
	// display
	helpAbout.show();
	help.show();
	
	menubar.show();
	
	app.setMenus(menubar);
    }

    private void createToolbar() {
	toolbar = new GtkToolbar(GtkOrientation.GTK_ORIENTATION_VERTICAL,
				 GtkToolbarStyle.GTK_TOOLBAR_TEXT);
	GtkButton button = new GtkButton("New");
	button.signal_connect("clicked", "fileNew", this);
	toolbar.appendWidget(button, "New File", "Private");
	button.show();
	button = new GtkButton("Open");
	button.signal_connect("clicked", "fileOpen", this);
	toolbar.appendWidget(button, "Open File", "Private");
	button.show();
	toolbar.appendSpace();
	button = new GtkButton("Save");
	button.signal_connect("clicked", "fileSave", this);
	toolbar.appendWidget(button, "Save File", "Private");
	button.show();
	button = new GtkButton("Save As");
	button.signal_connect("clicked", "fileSaveAs", this);
	toolbar.appendWidget(button, "Save File As", "Private");
	button.show();

	app.setToolbar(toolbar);
    }

    private void createStatusbar() {
	statusbar = new GtkStatusbar();
	contextID = statusbar.getContextId("Third App");
	statusbar.show();
	statusbar.push(contextID, "Ready");

	app.setStatusbar(statusbar);
    }

    public boolean delete_event(int value) {
	return true;
    }
    
    public void destroy() {
	Gtk.mainQuit();
    }
    
    public void fileNew() {
        statusbar.pop(contextID);
	statusbar.push(contextID, "File New Selected");
    }

    public void fileOpen() {
        statusbar.pop(contextID);
	statusbar.push(contextID, "file Open Selected");
    }

    public void fileSave() {
        statusbar.pop(contextID);
	statusbar.push(contextID, "File Save Selected");
    }

    public void fileSaveAs() {
        statusbar.pop(contextID);
	statusbar.push(contextID, "File Save As Selected");
    }

    public void fileExit() {
	Gtk.mainQuit();
    }
    
    public void helpAbout() {
	String title = "Third App";
	String version = "Version " + appVersion;
	String license = "GPL";
	String[] authors = {"The Java-GNOME team"};
	String comments = "This example is a part of the Java-GNOME tutorial";
	String pixmap = "gftp.png";
	GnomeAbout about = new GnomeAbout(title, version, license,
					  authors, comments, pixmap);
	about.show();
    }
    
    public static void main(String[] args) {
	Gnome.init("Third", Third.appVersion, 0, 0);
	Third second = new Third();
	Gtk.main();
    }    
}

The pattern you see here should be quite familiar to you by now. We have added a member of type GtkStatusbar and a method called createStatusbar() which is called from the constructor.

The interesting code here is the actual "pushing" and "popping" of the messages on the statusbar. In the method createStatusbar we made a call to statusbar.push(contextID, "Ready"). This pushes a message onto the statusbar message queue. In the callback methods that handle the menu and toolbar signals we have replaced the print statement with two calls. The first call is statusbar.pop(contextID). This call removes the previous message from the statusbar message queue. The second call is statusbar.push(contextID, "Some Message") and places a new message onto the statusbar message queue. I just decided to remove each previous message before adding the next but you can implement it differently as you wish.

Once you have completed this chapter you should have an application that looks similar to the following:

Figure 4-1. Third Application

All menu items and toolbar buttons have associated callback and the statusbar displays the last action performed. In the next few chapters we will add some meat to our example.