|
|
Example on Application DesignThe following is an example application that provide a user friendly interface and allow user to view high resolution images taken from Visible Human Project image data. The NPAC Visible Human ViewerSource code :
The NPAC Visible Human Viewer is an JAVA applet, that contain 9 files: VisibleHuman.java -- the Main Applet ImageFrame.java -- the Popup Image Frame Picture.java -- Object contains ImageCanvas and 2 Scroller ImageSelector.java -- Image Object with a Selection Line ImageCanvas.java -- Image Process and Display Object Scroller.java -- Motif Look Scroll Bar Button3D.java -- Motif Look 3D Button Panel3D.java -- Panel with 3D Outlook Delay.java -- Delay Interrupt Object Use the AWT component provided by JAVA is simple. But there are some problems arise when using AWT components:
I personally believe UI (user interface) is the most important element in commercial application design. If you are planning to write some serious application on JAVA, you will find the components provided in JAVA AWT is not enough. So I spend a lot of time on UI layout , process flow, and component redesign. It makes this program more complex than it should be, but people will like it more. The Class Hierarchy in NPAC Visible Human Viewer:Object --- Delay Applet --- VisibleHuman Frame --- ImageFrame Panel --- Panel3D -+- Button3D | +- ImageCanvas --- ImageSelector | +- Picture | +- Scroller In Panel3D class, I put in the concave/convex drawing utility methods. So the child classes will take advantage of these methods and make the concave/convex's color and style follow the same standard in different components. The Component Hierarchy:VisibleHuman -+- board ----+- view[3] --+- logo (ImageCanvas) | (Panel3D) | (Panel3D) | | | +- npac (Button3D) | | | +- view[0] --+- select[0] (ImageSelector) | | (Panel3D) | | | +- tagBtn[0] (Button3D) | | ("Axial") | +- view[1] --+- select[1] (ImageSelector) | | (Panel3D) | | | +- tagBtn[1] (Button3D) | | ("Sagittal") | +- view[2] --+- select[2] (ImageSelector) | (Panel3D) | | +- tagBtn[2] (Button3D) | ("Coronal") +- panel ----+- resolutions -+- tagBtn[3] (Button3D) (Panel3D) | (Panel3D) | ("Low") | +- tagBtn[4] (Button3D) | | ("Medium") | +- tagBtn[5] (Button3D) | ("High") +- controls -+- adjust ---+- left (Button3D) (Panel3D) | (Panel3D) | (triangle) | +- right (Button3D) | (triangle) +- slice (Panel3D) | (current slice number) +- load (Button3D) ImageFrame Component Hierarchy:ImageFrame -+- picture (Picture) | +- controls --+- Quit (Button3D) (Panel3D) | ("Quit") +- Download (Button3D) | ("Download") +- Apply (Button3D) | ("Apply") +- Org (Button3D) | ("1:1") +- lbScale (Panel3D) | (current scale) +- sbScale (Scrller) (HORIZONTAL) ImageCanvas Component Hierarchy:Picture -+- canvas (ImageCanvas) | (Center) +- hScroll (Scroller) | (South, HORIZONTAL) +- vScroll (Scroller) (East, VERTICAL) Scroller Component Hierarchy:Scroller ----+- up (Button3D) (HORIZONTAL) | (West, triangle) +- down (Button3D) (East, triangle) Scroller ----+- up (Button3D) (VERTICAL) | (North, triangle) +- down (Button3D) (South, triangle) Panel3D instance view[3]
The view[3] component contains logo(ImageCanvas) and npac(Button3D) by using BoardLayout. Source code: intr001.java You will see the following code in init() method: ... /* initialize logo and npac */ .... view[3].setLayout(new BorderLayout()); view[3].add("South", npac); view[3].add("Center", logo); ... Panel3D instance view[0]
The view[0] component contains select[0](ImageSelector) and tagBtn[0](Button3D) by using BoardLayout. Source code: intr002.java You will see the following code in init() method: ... /* initialize logo and npac */ .... view[0].setLayout(new BorderLayout()); view[0].add("South", tagBtn[0]); view[0].add("Center", select[0]); ... Panel3D instance view[1]
The view[1] component contains select[1](ImageSelector) and tagBtn[1](Button3D) by using BoardLayout. Source code: intr003.java You will see the following code in init() method: ... /* initialize logo and npac */ .... view[1].setLayout(new BorderLayout()); view[1].add("South", tagBtn[1]); view[1].add("Center", select[1]); ... Panel3D instance view[2]
The view[2] component contains select[2](ImageSelector) and tagBtn[2](Button3D) by using BoardLayout. Source code: intr004.java You will see the following code in init() method: ... /* initialize logo and npac */ .... view[2].setLayout(new BorderLayout()); view[2].add("South", tagBtn[2]); view[2].add("Center", select[2]); ... Panel3D instance board
Now we put view[0], view[1], view[2], and view[3] into board(Panel3D) by using FlowLayout. Source code: intr005.java If you click on the buttons, you will find we need some Event control in order to let the buttons and viewport react to Mouse Event caused by user. public boolean action(Event ev, Object arg) { if (arg == select[0]) { /* Select Cutting Line or View on Axial Image */ switch ( ev.id ) { case Event.MOUSE_DOWN : setCurrent(0); break; case Event.MOUSE_UP : case Event.MOUSE_DRAG : break; default: setCurrent(2); } return true; } else if (arg == select[1]) { /* Select Cutting Line or View on Sagittal Image */ switch ( ev.id ) { case Event.MOUSE_DOWN : setCurrent(1); break; case Event.MOUSE_UP : case Event.MOUSE_DRAG : break; default: setCurrent(0); } return true; } else if (arg == select[2]) { /* Select Cutting Line or View on Coronal Image */ switch ( ev.id ) { case Event.MOUSE_DOWN : setCurrent(2); break; case Event.MOUSE_UP : case Event.MOUSE_DRAG : break; default: setCurrent(1); } return true; } else if (arg == tagBtn[0]) { /* Select View on Axial Image */ setCurrent(2); return true; } else if (arg == tagBtn[1]) { /* Select View on Sagittal Image */ setCurrent(0); return true; } else if (arg == tagBtn[2]) { /* Select View on Coronal Image */ setCurrent(1); return true; } return false; } When responding to component's action in action method, we call setCurrent method to set the proper state of buttons and viewports. private void setCurrent(int _current) { /* Select the current Viewport */ if ( current == _current ) return; int i, k; current = _current; k = (current+1)%3; showStatus("Select "+tagName[k]+" View"); for (i=0; i<3; i++) { tagBtn[i].setActive(i!="k);" select[i].setMode((i="=k)" ? 1 : 1); select[i].setColor((i="=current)" ? Color.cyan : Color.red); } } Panel3D instance board with Event Handler
Source code: intr006.java Finally, we introduced all the components contained in board and react correctly to Mouse Selection. It would be impossible to cover every single method and component used in Visible Human project. In this example, we can get some idea about how an application is designed and implemented.
|