Making the Statusbar more "visible"
One of the things users always complain about is, that errors which occur or messages which are shown are not recognized. For some reason, the statusbar visible by default at the bottom of a forms-application seems to be invisible or at least somehow encrypted to the enduser. So, inspired by a recently question on the forms-forum at OTN, i tried to find a way to make showing messages to be more "recognizable".
Best way to get someones attention in an application is to use some visual effect, like coloring. So my approach was to
- get hand on the statusbar object
- at some specific event triggered from forms, colorize the statusbar
- somehow remove the coloreffect again, so that the next time someone should pay attention i can activate the color-effect again.
So, i started writing a little javabean. There is already a javabean by Francois Degrelle (Personalize.java) which can identify the Statusbar-object. So, all i had to do was
- define an event to be sent from forms to my bean, which initializes the coloring of the formerly identified statusbar
- write a little Thread-class which colors the statusbar and then slowly fades out the color back to its original value.
Heres the code
package forms; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.lang.reflect.Method; import oracle.ewt.statusBar.StatusBar; import oracle.forms.engine.Main; import oracle.forms.handler.IHandler; import oracle.forms.ui.VBean; import oracle.forms.ui.VTextField; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import oracle.forms.properties.ID; /** * Sample-Code for a java-Bean that colors the Statusbar green, yellow or red and then slowly fades out the color * back to the original color */ public class StatusBarFlasher extends VBean { /** Different Type */ public static final ID ERROR =ID.registerProperty("ERROR"); public static final ID WARNING =ID.registerProperty("WARNING"); public static final ID MESSAGE =ID.registerProperty("MESSAGE"); /** The statusbar-object */ private static StatusBar m_statusBar=null; /** Handler-Object */ private IHandler m_handler=null; /** Curent fader-alpha */ int fadervalue=0; /** * Store the handler locally * @param handler */ public void init(IHandler handler) { super.init(handler); m_handler=handler; } /** * Recursive search for the statusbar-object, inspired by Francois Degrelles Personalize.java * @param ct */ private void findStatusBar(Container ct) { Component cp[] = ct.getComponents() ; int i=0; while (m_statusBar==null && i<cp.length) { if(m_statusBar==null && (cp[i] instanceof StatusBar)) { m_statusBar = (oracle.ewt.statusBar.StatusBar)cp[i] ; } try { findStatusBar((Container)cp[i]); } catch (Exception e) { } i++; } } /** * Initialize and find the Statusbar, if not already done */ public void init() { if (m_statusBar==null) { try { Method method = m_handler.getClass().getMethod("getApplet", new Class[0]); Object applet = method.invoke(m_handler, new Object[0]); if (applet instanceof Main) { findStatusBar(((Main)applet).getFrame()); } } catch(Exception ex) { } } } /** * Overwritten method acceptingproeprties from forms * @return * @param id Properties ID * @param p0 value */ public boolean setProperty(ID id, Object value) { if (id==ERROR) { init(); if (m_statusBar!=null) { if (fadervalue==0) { StatusBarFlasher.Fader fader=new StatusBarFlasher.Fader(255,0,0); fader.start(); } else { fadervalue=255; } } return true; } else if (id==WARNING) { init(); if (m_statusBar!=null) { if (fadervalue==0) { StatusBarFlasher.Fader fader=new StatusBarFlasher.Fader(255, 255, 0); fader.start(); } else { fadervalue=255; } } return true; } else if (id==MESSAGE) { init(); if (m_statusBar!=null) { if (fadervalue==0) { StatusBarFlasher.Fader fader=new StatusBarFlasher.Fader(0, 255, 0); fader.start(); } else { fadervalue=255; } } return true; } else { /** Delegate */ return super.setProperty(id, value); } } /** * Local class to color the Statusbar where messages are shwon and slowly fading * out the color by reducing the alpha-value */ class Fader extends Thread { /** The base-Color */ private int m_r; private int m_g; private int m_b; /** * Constructor taken the base-color as rgb-color-values * @param b * @param g * @param r */ public Fader(int r, int g, int b) { m_r=r; m_g=g; m_b=b; } /** * The Run-methode */ public void run() { Color cc=m_statusBar.getBackground(); fadervalue=255; while (fadervalue>0) { Color c=new Color(m_r, m_g, m_b, fadervalue); m_statusBar.setBackground(c); fadervalue=fadervalue-5; try { Thread.sleep(50); } catch (Exception e) { } } m_statusBar.setBackground(cc); } } }
Using the javabean is as with any java-bean.
- Compile it, create a jar of it and put that jar in your archive or archice_jni-tag in the formsweb.cfg of your application
- Create a Bean-object in your form, setting the implementation class to forms.StatusBarFlasher
Finally, you need to invoke the flashing effect. As the bean is used to signal errors, you can put something like the following in your own ON-ERROR-trigger, or add the SET_CUTOM_PROPERTY-part to an existing errorhandler
message(ERROR_TYPE || '-' || ERROR_CODE || ': ' || ERROR_TEXT); SET_CUSTOM_ITEM_PROPERTY('B.BEAN', 'ERROR', '');
Use the property
- ERROR for red color,
- WARNING for yellow color,
- MESSAGE for green color.
Well, thats it.
P.S.
Francois Degrelle build a readmade jar-file that can be used directly, get it from here