/* * Visible Human Project Java Program * by: Yuh-Jye Chang * * This Project contains 12 files: * * VisibleHuman.java -- the Main Applet * ImageFrame.java -- the Popup Image Frame * ImageSelector.java -- Image Object with a Selection Line * ImageCanvas.java -- Image Process and Display Object * Scroller.java -- Motif Look Scrollbar * Button3D.java -- Motif Look 3D Button * Panel3D.java -- Panel with 3D Outlook * Label3D.java -- Label with 3D Outlook * Canvas3D.java -- Canvas with 3D Outlook * Thumb.java -- Thumb in Scrollbar * Setting.java -- Global Setting Interface * Delay.java -- Delay Interrupt Object * * The Class Hierarchy: * * Object --- Delay * Applet --- VisibleHuman * Frame --- ImageFrame * Panel --- Panel3D --- Scroller * Canvas --- Canvas3D -+- Label3D --- Button3D * | * +- ImageCanvas --- ImageSelector * | * +- Thumb * * The Component Hierarchy: * * VisibleHuman -+- board ----+- view[3] --+- logo (ImageCanvas) * | (Panel3D) | (Panel) | * | | +- npac (Button3D) * | | * | +- view[0] --+- select[0] (ImageSelector) * | | (Panel) | * | | +- tagBtn[0] (Button3D) * | | ("Axial") * | +- view[1] --+- select[1] (ImageSelector) * | | (Panel) | * | | +- tagBtn[1] (Button3D) * | | ("Sagittal") * | +- view[2] --+- select[2] (ImageSelector) * | (Panel) | * | +- tagBtn[2] (Button3D) * | ("Coronal") * +- panel ----+- resolutions -+- tagBtn[3] (Button3D) * (Panel) | (Panel3D) | ("Low") * | +- tagBtn[4] (Button3D) * | | ("Medium") * | +- tagBtn[5] (Button3D) * | ("High") * +- controls -+- adjust ---+- left (Button3D) * (Panel3D) | (Panel3D) | (triangle) * | +- right (Button3D) * | (triangle) * +- slice (Label3D) * | (current slice number) * +- load (Button3D) * * ImageFrame -+- picture ---+- canvas (ImageCanvas) * | (Panel) | (Center) * | +- hScroll (Scroller) * | | (South, HORIZONTAL) * | +- vScroll (Scroller) * | (East, VERTICAL) * +- controls --+- Quit (Button3D) * (Panel3D) | ("Quit") * +- Download (Button3D) * | ("Download") * +- Apply (Button3D) * | ("Apply") * +- Org (Button3D) * | ("1:1") * +- lbScale (Panel3D) * | (current scale) * +- sbScale (Scrller) * (HORIZONTAL) * * Scroller ----+- up (Button3D) * (HORIZONTAL) | (West, triangle) * +- down (Button3D) * | (East, triangle) * +- thumb (Thumb) * (Center) * * Scroller ----+- up (Button3D) * (VERTICAL) | (North, triangle) * +- down (Button3D) * | (South, triangle) * +- thumb (Thumb) * (Center) */ import java.applet.*; import java.awt.*; import java.net.*; public class VisibleHuman extends Applet implements Runnable, Setting { static ImageFrame frameList = null; static URL codeBase, Fatch; static double scale = 1.0; static int maxp = 2; static int step = 50; static int wFrame = 580; static int hFrame = 420; static int offset = 24; static int no = 0; static int wrap; static int sliceOfs = 1001; static String LOAD = "Load"; static String imgdir = "."; static String tagName[] = { "Axial", "Sagittal", "Coronal", "Low", "Medium", "High"}; int current = 0; int resolution = 0; boolean canStop = false; Panel panel, view[]; Panel3D board, resolutions, controls, adjust; Label3D slice; Button3D tagBtn[], npac, load, left, right; ImageCanvas logo; ImageSelector select[]; int sliceNo[] = { 860, 350, 600}; public void init() { int i; int defaultRes = 1; int defaultView = 2; String arg; /* Get Current Screen Resolution */ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); view = new Panel[4]; tagBtn = new Button3D[6]; select = new ImageSelector[3]; /* Initialize Arguments pass from HTML */ arg = getParameter("wframe"); if (arg != null) wFrame = Integer.valueOf(arg).intValue(); arg = getParameter("hframe"); if (arg != null) hFrame = Integer.valueOf(arg).intValue(); arg = getParameter("slicex"); if (arg != null) sliceNo[0] = Integer.valueOf(arg).intValue(); arg = getParameter("slicey"); if (arg != null) sliceNo[1] = Integer.valueOf(arg).intValue(); arg = getParameter("slicez"); if (arg != null) sliceNo[2] = Integer.valueOf(arg).intValue(); arg = getParameter("scale"); if (arg != null) scale = Double.valueOf(arg).doubleValue(); arg = getParameter("maxp"); if (arg != null) maxp = Integer.valueOf(arg).intValue(); arg = getParameter("step"); if (arg != null) step = Integer.valueOf(arg).intValue(); arg = getParameter("defaultRes"); if (arg != null) defaultRes = Integer.valueOf(arg).intValue(); arg = getParameter("defaultView"); if (arg != null) defaultView = Integer.valueOf(arg).intValue(); arg = getParameter("imgdir"); if (arg != null) imgdir = arg; codeBase = getCodeBase(); /* Set Main Applet to Border Layout */ setLayout(new BorderLayout()); /* Setup Components */ logo = new ImageCanvas(); logo.setPreferredSize(59, 59); logo.mode = 1; select[0] = new ImageSelector(Scrollbar.HORIZONTAL, sliceNo[0], 0, 1728); select[0].setValue(sliceNo[0], false); select[0].setPreferredSize(100, 59); select[0].mode = 1; select[1] = new ImageSelector(Scrollbar.HORIZONTAL, sliceNo[1], 0, 1000); select[1].setValue(sliceNo[1], false); select[1].setPreferredSize(59, 317); select[1].mode = 1; select[2] = new ImageSelector(Scrollbar.VERTICAL, sliceNo[2], 0, 1878); select[2].setValue(sliceNo[2], false); select[2].setPreferredSize(100, 317); select[2].mode = 1; npac = new Button3D("NPAC"); view[3] = new Panel(); view[3].setLayout(new BorderLayout()); view[3].add("South", npac); view[3].add("Center", logo); board = new Panel3D(); board.add(view[3]); for (i=0; i<3; i++) { view[i] = new Panel(); view[i].setLayout(new BorderLayout()); view[i].add("South", tagBtn[i] = new Button3D(Button3D.CHECKBTN, tagName[i])); view[i].add("Center", select[i]); tagBtn[i].setRatio(2); board.add(view[i]); } resolutions = new Panel3D(); resolutions.add(tagBtn[3] = new Button3D(Button3D.CHECKBTN, tagName[3])); resolutions.add(tagBtn[4] = new Button3D(Button3D.CHECKBTN, tagName[4])); resolutions.add(tagBtn[5] = new Button3D(Button3D.CHECKBTN, tagName[5])); tagBtn[4].setRatio(3); adjust = new Panel3D(); adjust.setLayout(new FlowLayout(FlowLayout.CENTER, d2, depth)); adjust.add(left = new Button3D(Button3D.LEFT)); adjust.add(right = new Button3D(Button3D.RIGHT)); left.setBase(tagBtn[0].getBase()-8); right.setBase(tagBtn[0].getBase()-8); controls = new Panel3D(); controls.add(adjust); controls.add(slice = new Label3D(String.valueOf(sliceNo[2]))); controls.add(load = new Button3D(LOAD)); load.setRatio(3); slice.setActive(false); panel = new Panel(); panel.setLayout(new GridLayout(2, 1)); panel.add(controls); panel.add(resolutions); add("Center", board); add("South", panel); setCurrent(defaultView); setResolution(defaultRes+3); sliceNo[0] = sliceNo[1] = sliceNo[2] = -1; /* Caculate offsets for Pupup ImageFrame */ int wrapx = (screenSize.width-offset*4-wFrame)/offset; wrap = (screenSize.height-offset*4-hFrame)/offset; if ( wrap > wrapx ) wrap = wrapx; if ( wrap < 1 ) wrap = 1; /* Caculate the Width and Height of Applet int wApp=59+100+4*3+depth*2; int hApp=59+317+4*3+controls.preferredSize().height*2+depth*2+44; System.out.println("W"+wApp+" H"+hApp); */ } public void start() { /* Setup Image into Image Object */ logo.updateImage(getImage(codeBase, "logo.gif")); updatePreview(); } private void updatePreview() { /* Update Image only when slice number is changed */ if ( sliceNo[0] != select[0].getValue()/18 ) { sliceNo[0] = select[0].getValue()/18; select[1].updateImage(getImage(codeBase, imgdir+ "JPEGX-18/a_vmX"+(sliceNo[0]+sliceOfs)+"-18.jpg")); } if ( sliceNo[1] != select[1].getValue()/18 ) { sliceNo[1] = select[1].getValue()/18; select[2].updateImage(getImage(codeBase, imgdir+ "JPEGY-18/a_vmY"+(sliceNo[1]+sliceOfs)+"-18.jpg")); } if ( sliceNo[2] != select[2].getValue()/6 ) { sliceNo[2] = select[2].getValue()/6; select[0].updateImage(getImage(codeBase, imgdir+ "JPEG-18/a_vm"+(sliceNo[2]+sliceOfs)+"-18.jpg")); } } public void stop() { /* Destroy all the Popup ImageFrame Windows */ while ( frameList != null ) frameList.dispose(); } private void setCurrent(int _current) { /* Select the current Viewport */ if ( current == _current ) return; int i, j, 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); } left.setType((current == 2)? Button3D.UP : Button3D.LEFT); right.setType((current == 2)? Button3D.DOWN : Button3D.RIGHT); slice.setText(String.valueOf(select[current].getValue())); } private void setResolution(int _resolution) { /* Select the current Resolution */ if ( resolution == _resolution ) return; resolution = _resolution; showStatus("Set resolution to "+tagName[resolution]); for (int i=3; i<6; i++) tagBtn[i].setActive(i!=resolution); } public void run() { /* Fatch the URL and Show Document */ showStatus(Fatch.toString()); getAppletContext().showDocument(Fatch); } private void showHTML(String addr) { /* Show URL addr's HTML document */ try { Fatch = new URL(codeBase, addr); new Delay(100, -1, this); } catch (MalformedURLException e); } public boolean keyDown(Event ev, int key) { if ( key < 0 ) (new Thread(this)).start(); return true; } public boolean action(Event ev, Object arg) { if ( arg == load ) { /* Load a Image from Data Set */ if ( canStop ) { canStop = false; load.setText(LOAD); if ( frameList != null ) frameList.dispose(); return true; } int x = offset*((no%wrap)+2); int slice = select[current].getValue(); int yScale = 1; URL dataBase = codeBase; double kScale = 1.0; String path = imgdir+"JPEG"; updatePreview(); switch ( resolution ) { case 3 : path += "-L"; break; case 4 : path += "-M"; break; } switch ( current ) { case 0 : // Sagittal Image path += "X/a_vmX"+(slice+sliceOfs); if ( resolution == 5 ) { yScale = 3; kScale = scale; } break; case 1 : // Coronal Image path += "Y/a_vmY"+(slice+sliceOfs); if ( resolution == 5 ) { yScale = 3; kScale = scale; } break; default : // Axial Image path += "/a_vm"+(slice+sliceOfs); break; } switch ( resolution ) { case 3 : path += "-L"; break; case 4 : path += "-M"; break; } path += ".jpg"; canStop = true; new ImageFrame(this, "2D Viewer No."+(++no)+" "+ tagBtn[(current+1)%3].getText()+" "+ tagBtn[resolution].getText()+" "+ "Slice#"+slice, path, getImage(dataBase, path), x, x, wFrame, hFrame, kScale, 1, yScale, maxp, step); if ( canStop ) load.setText("Stop"); else canStop = false; return true; } else if (arg == left) { /* Decrease current slice number by 1 */ if ( ev.id != Event.MOUSE_UP ) { int v = select[current].getValue()-1; if ( select[current].setValue(v, true) ) slice.setText(String.valueOf(v)); } else updatePreview(); return true; } else if (arg == right) { /* Increase current slice number by 1 */ if ( ev.id != Event.MOUSE_UP ) { int v = select[current].getValue()+1; if ( select[current].setValue(v, true) ) slice.setText(String.valueOf(v)); } else updatePreview(); return true; } else 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 : updatePreview(); break; case Event.MOUSE_DRAG : break; default: setCurrent(2); } slice.setText(String.valueOf(select[current].getValue())); 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 : updatePreview(); break; case Event.MOUSE_DRAG : break; default: setCurrent(0); } slice.setText(String.valueOf(select[current].getValue())); 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 : updatePreview(); break; case Event.MOUSE_DRAG : break; default: setCurrent(1); } slice.setText(String.valueOf(select[current].getValue())); 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; } else if (arg == tagBtn[3]) { /* Select Low Resolution */ setResolution(3); return true; } else if (arg == tagBtn[4]) { /* Select Medium Resolution */ setResolution(4); return true; } else if (arg == tagBtn[5]) { /* Select High Resolution */ setResolution(5); return true; } else if ((arg == logo) || (arg == npac)) { /* Select NPAC logo or Button */ if ( (ev.id == Event.MOUSE_DOWN) || (arg == npac) ) showHTML("http://www.npac.syr.edu"); return true; } else if (arg instanceof String) { /* Download the Image into Browser */ showHTML((String)arg); return true; } else if ((frameList != null) && (arg == frameList)) { /* Popup ImageFrame is Ready Notify */ if ( canStop ) { canStop = false; if ( load.getText() != LOAD ) load.setText(LOAD); } return true; } return false; } }