Sunday, March 30, 2008

Java: A JDialog and JProgressBar Example

If you have an application that runs for a long time, providing feedback that something is still happening is a really useful thing. Java provides a very wide range of GUI components.

One that fits the need is the JProgressBar. As you might expect, the JProgressBar allows you to draw a progress meter, either horizontally or vertically, and update it while your program is running.

Here is an example of using JProgressBar within a JDialog. JDialog allows you to set the dialog as modal, which will stop the application until the dialog is dismissed (as a JOptionPane does). There are many ways to create a dialog in java, this example includes both and is merely one (very minimalistic) way to do it.

First the JProgressBar object is created and attributes set, including min and max values of 0 and 100, respectively, and size of the progress bar:

JProgressBar pb = new JProgressBar(0,100);
pb.setPreferredSize(new Dimension(175,20));
pb.setString("Working");
pb.setStringPainted(true);
pb.setValue(0);


A JLabel object is created to display some text in the dialog:

JLabel label = new JLabel("Progress: ");


Then the label and progress bar are added to the panel:

JPanel center_panel = new JPanel();
center_panel.add(label);
center_panel.add(pb);



Once the panel is populated, the JDialog object is created, the panel is added,
and it is made visible:

dialog = new JDialog((JFrame)null, "Working ...");
dialog.getContentPane().add(center_panel, BorderLayout.CENTER);
dialog.pack();
dialog.setVisible(true);



Some useful actions to perform on the dialog, though not all at the same time:

dialog.setLocationRelativeTo(null); // center on screen
dialog.setLocation(550,25); // position by coordinates
dialog.toFront(); // raise above other java windows



While your program is running, you can update the progress bar by feeding it an integer value between the min and max values:

pb.setValue(25);


You have a couple of options when your program is done. The simplest thing to do is to close the dialog, and then display a JOptionPane, for example, informing the user:

dialog.dispose();


To get more creative, one can add a button to the dialog, which will can close the dialog when pressed. The action is defined by adding an action listener to the button. Here we dynamically add the button, but it could be done at the beginning.

JButton button = new JButton("Done");
button.setActionCommand("done");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt){
if ( evt.getActionCommand().equals("done") ) {
dialog.dispose();
}
}
});


The button is added to a new JPanel object:

JPanel page_end_panel = new JPanel();
page_end_panel.add(button);


Then the new panel is added to the dialog, which will make it appear immediately:

dialog.getContentPane().add(page_end_panel, BorderLayout.PAGE_END);


It's not required, but if you wish to force the user to hit the button, the dialog can be made "modal", which will cause it to act like a JOptionPane. It seems that the visibility of the dialog must be toggled for the change in modality to take effect:

dialog.setModal(true);
dialog.pack();
dialog.setVisible(false);
dialog.setVisible(true);



This will cause the program to wait until the button is pressed, which will dismiss the dialog.

Just in case the dialog is dismissed by closing the window, without hitting the button, you might want to add a call to dispose() anyway. Perhaps that is unnecessary.
dialog.dispose();

Intralink Scripting: Triggering on Java Events

It is possible to trigger on events occuring with the JVM using the AWTEventListener class. There won't be fine grain control nor information about what event occurred, but that can be derived from the expected events.

This is an example of how to use the AWTEventListener to monitor for window events such as opening windows and closing windows, as well as windows gaining and losing focus.

The first step is to define an AWT event listener. This listener makes the newly created frame invisible. It's almost immediate, but the frame will appear briefly before disappearing.

AWTEventListener listener = new AWTEventListener() {
public void eventDispatched(java.awt.AWTEvent event) {
if (event.getID() == WindowEvent.WINDOW_OPENED) {
Frame[] frames = Frame.getFrames();
int frm_idx = frames.length-1;
System.out.println( " making frame " + frm_idx
+ " (" + frames[frm_idx].getTitle()
+ ") invisible" );
frames[frm_idx].setVisible(false);
}
}
};

Once the listener object has been created, it needs to be registered to become active using addAWTEventListener():

Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.WINDOW_EVENT_MASK);


To disable the listener, use removeAWTEventListener():

Toolkit.getDefaultToolkit().removeAWTEventListener(listener);


Monday, March 24, 2008

Intralink: Who's Logged In?

A PTC/User post of mine from May 2002:

Use this sql query as a privileged user to list intralink users who have logged into the dataserver:

  col un format A15 heading 'User Name'
col mn format A15 heading 'Host Name'
col lt format A10 heading 'Login Date'
col lc format 999999999 heading 'Last Cmd (Sec)'
select
OSUSER un,MACHINE mn,STATUS,TERMINAL,LOGON_TIME lt,LAST_CALL_ET lc
from v$session where SCHEMANAME='PDM';
The 'Status' column will show 'ACTIVE' or 'INACTIVE', with 'ACTIVE' indicating that there is ongoing sql activity (i.e. Search, Checkout, Checkin, etc.). The 'Last Cmd...' column shows the number of seconds since the last sql command issued by the client. It's only updated every three seconds.

An entry will appear immediately when the user logs in, and will disappear immediately when the user logs out. The entry will remain even if the client license on your FlexLM license server has timed out.