/** * @file UserInterface.java * @author Robert S Laramee * @version 1.0 * @see *

* start date Tue 15 Feb 2000 * finish date never *

* Description This is the user interface object. It constructs the GUI. * */ import rlaramee.*; import javax.swing.*; /* for JFileChooser class */ import java.awt.Component; import java.rmi.RemoteException; import java.awt.*; import java.awt.event.*; import visad.*; import visad.java3d.DisplayImplJ3D; import visad.util.ContourWidget; import java.io.*; /* for File class */ public class UserInterface implements ActionListener { private JFrame displayFrame; private JFrame widgetFrame; private JPanel displayPanel; private JPanel widgetPanel; private JMenuBar UIMenuBar; /** array of applic menus */ private JMenu UIMenus[]; private JMenuItem fileItems[]; private JMenuItem dataSetItems[]; private JMenuItem formatItems[]; private JMenuItem resolutionItems[]; private JMenuItem representationItems[]; private JMenuItem errorItems[]; private IsoRenderer isoRenderer; private DisplayImplJ3D display; private ContourWidget contourWidget; private double savedIsoValue = 0.0; private boolean debug = false; /** 29 Nov 00 */ private VisOptionsDialog vod; /** * constructor */ public UserInterface(IsoRenderer app) throws RemoteException, VisADException { isoRenderer = app; display = new DisplayImplJ3D("image display"); if (debug) System.out.println("UserInterface.new()"); /* rotate(display); /* not while testing */ } /** * get() method(s) */ public DisplayImplJ3D getDisplay() { return display; } /** * @return this UserInterface's projection control */ private ProjectionControl getProjectControl() { return getDisplay().getProjectionControl(); } /** * set up the Content Display Frame * create JFrame (i.e., a window) for display * create JPanel in JFrame * add display to JPanel * set size of JFrame and make it visible */ public DisplayImplJ3D initialize() throws RemoteException, VisADException { displayFrame = new JFrame("ARrenderer VisAD Application"); if (debug) System.out.println("UserInterface.initialize()"); double defaultValue = 0.185; /** * bob tries to center the window */ Toolkit toolkit = Toolkit.getDefaultToolkit(); Dimension dimension = toolkit.getScreenSize(); int screenHeight = dimension.height; int screenWidth = dimension.width; displayFrame.setLocation(screenWidth/8, screenHeight/8); displayFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); buildMenus(); /* this 1st */ displayFrame.setJMenuBar(UIMenuBar); /* this 2nd! */ displayPanel = new JPanel(); displayPanel.setLayout(new BoxLayout(displayPanel, BoxLayout.Y_AXIS)); displayPanel.setAlignmentY(JPanel.TOP_ALIGNMENT); displayPanel.setAlignmentX(JPanel.LEFT_ALIGNMENT); displayFrame.getContentPane().add(displayPanel); displayPanel.add(display.getComponent()); displayFrame.setSize(600, 600); displayFrame.setVisible(true); try { ContourWidget widget = initializeWidget(); widget.setSurfaceValue(defaultValue); } catch (RemoteException re) {} catch (VisADException ve) {} return display; } /** * Set up the Contour Widget */ public ContourWidget initializeWidget() throws RemoteException, VisADException{ if (debug) System.out.println("UserInterface.initializeWidget()"); ScalarMap mapContour=(ScalarMap)display.getMapVector().lastElement(); contourWidget = new ContourWidget(mapContour); widgetFrame = new JFrame("ContourWidget"); /** * bob tries to position the window */ Toolkit toolkit = Toolkit.getDefaultToolkit(); Dimension dimension = toolkit.getScreenSize(); int screenHeight = dimension.height; int screenWidth = dimension.width; widgetFrame.setLocation(screenWidth/2, screenHeight/2); widgetFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); widgetPanel = new JPanel(); widgetPanel.setLayout(new BorderLayout()); widgetPanel.add("Center", contourWidget); widgetFrame.setContentPane(widgetPanel); widgetFrame.pack(); widgetFrame.setVisible(true); return contourWidget; } /** * Used to rotate the view volume to a nice default */ private void rotate(LocalDisplay display) throws RemoteException, VisADException { boolean debug = false; if (display == null) System.err.println("*** Error, " + "UserInteface.rotate() display == null"); double xAngle = -90.0; double yAngle = -90.0; double[] matrix; double[] mult; /* display.getGraphicsModeControl().setTransparencyMode( * javax.media.j3d.TransparencyAttributes.SCREEN_DOOR); */ ProjectionControl control = display.getProjectionControl(); /** 1st, rotate about the x axis */ matrix = control.getMatrix(); mult = display.make_matrix(xAngle, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0); control.setMatrix(display.multiply_matrix(mult, matrix)); /** 2nd, rotate about the y axis */ matrix = control.getMatrix(); mult = display.make_matrix(0.0, yAngle, 0.0, 1.0, 0.0, 0.0, 0.0); control.setMatrix(display.multiply_matrix(mult, matrix)); } /** * Handle button click events here. It must be a public method: * "class Draw3d must override void * actionPerformed(java.awt.event.ActionEvent) with a public method in * order to implement interface java.awt.event.ActionListener." * * handle menu selections here */ public void actionPerformed(ActionEvent event) { if ( (readFile(event)) == 1) /* File Menu events */ return; if ( (readDataSet(event)) == 1) /* Data Set Menu events */ return; if ( (readFormat(event)) == 1) /* Data Format Menu events */ return; if ( (readResolution(event)) == 1) /* Resolution Menu events */ return; if ( (readRepresentation(event)) == 1) /* Representation Menu events */ return; if ( (readErrMode(event)) == 1) /*Error Visualization menu events */ return; System.err.println("*** Error, UserInterface.actionPerformed()"); } /** * This method is called from the ActionPerformed() method. It reads * the option chosen from the File menu. */ private int readFile(ActionEvent event) { if (event.getSource() == fileItems[0]) { System.out.println("UserInterface.readFile(): file mode = " + Constant.OPEN); startFileDialog(); return 1; } else if (event.getSource() == fileItems[1]) { System.out.println("UserInterface.readFile(): file mode = " + Constant.QUIT); System.exit(0); return 1; } else { return 0; } } /** * This method is called from the ActionPerformed() method. It reads * the option chosen from the Data Set menu. */ private int readDataSet(ActionEvent event) { if (event.getSource() == dataSetItems[0]) { Gridded3DMRSet.setDataSet(Constant.HEAD); System.out.println("UserInterface.readDataSet(): data set is " + Gridded3DMRSet.getDataSet()); return 1; } else if (event.getSource() == dataSetItems[1]) { Gridded3DMRSet.setDataSet(Constant.LOBSTER); System.out.println("UserInterface.readDataSet(): data set is " + Gridded3DMRSet.getDataSet()); return 1; } else if (event.getSource() == dataSetItems[2]) { Gridded3DMRSet.setDataSet(Constant.KNEE); System.out.println("UserInterface.readDataSet(): data set is " + Gridded3DMRSet.getDataSet()); return 1; } else if (event.getSource() == dataSetItems[3]) { Gridded3DMRSet.setDataSet(Constant.SPHERE); System.out.println("UserInterface.readDataSet(): data set is " + Gridded3DMRSet.getDataSet()); return 1; } else if (event.getSource() == dataSetItems[4]) { Gridded3DMRSet.setDataSet(Constant.ARTEST1); System.out.println("UserInterface.readDataSet(): data set is " + Gridded3DMRSet.getDataSet()); return 1; } else if (event.getSource() == dataSetItems[5]) { Gridded3DMRSet.setDataSet(Constant.ARTEST2); System.out.println("UserInterface.readDataSet(): data set is " + Gridded3DMRSet.getDataSet()); return 1; } else { return 0; } } /** * This method is called from the ActionPerformed() method. It reads * the option chosen from the Format menu. */ private int readFormat(ActionEvent event) { if (event.getSource() == formatItems[0]) { Gridded3DMRSet.setBinaryFormat(false); System.out.println("UserInterface.readFormat(): format is " + Gridded3DMRSet.getBinaryFormat()); return 1; } else if (event.getSource() == formatItems[1]) { Gridded3DMRSet.setBinaryFormat(true); System.out.println("UserInterface.readFormat(): format is " + Gridded3DMRSet.getBinaryFormat()); return 1; } else if (event.getSource() == formatItems[2]) { Gridded3DMRSet.setFloatFormat(true); System.out.println("UserInterface.readFormat(): format is " + Gridded3DMRSet.getFloatFormat()); return 1; } else if (event.getSource() == formatItems[3]) { Gridded3DMRSet.setFloatFormat(false); System.out.println("UserInterface.readFormat(): format is " + Gridded3DMRSet.getFloatFormat()); return 1; } else { return 0; } } /** * Note: source for an ExtensionFileFilter class can be found in the * SwingSet demo * The filter will show only files with the binary and ascii extensions */ private void startFileDialog() { String currentDirectory = "../data"; JFileChooser chooser = new JFileChooser(currentDirectory); int returnVal = chooser.showOpenDialog(displayFrame); if (returnVal == JFileChooser.APPROVE_OPTION) { System.out.println("You chose to open: " + chooser.getSelectedFile().getName()); } String inputFileName = chooser.getSelectedFile().getName(); FileName fileName = new FileName(inputFileName); fileName.examineSettings(); } /** * This method is called from the ActionPerformed() method. It reads * the resolution chosen from the Resolution menu. */ private int readResolution(ActionEvent event) { if (event.getSource() == resolutionItems[0]) { /* 128 cubed */ Gridded3DMRSet.setResolution(Constant.RES128); System.out.println("UserInterface.readResolution(): " + Gridded3DMRSet.getResolution()); setNewData(Gridded3DMRSet.getResolution() + 1); return 1; } else if (event.getSource() == resolutionItems[1]) { /* 64 cubed */ Gridded3DMRSet.setResolution(Constant.RES64); System.out.println("UserInterface.readResolution(): " + Gridded3DMRSet.getResolution()); setNewData(Gridded3DMRSet.getResolution() + 1); return 1; } else if (event.getSource() == resolutionItems[2]) { /* 32 cubed */ Gridded3DMRSet.setResolution(Constant.RES32); System.out.println("UserInterface.readResolution(): " + Gridded3DMRSet.getResolution()); setNewData(Gridded3DMRSet.getResolution() + 1); return 1; } else if (event.getSource() == resolutionItems[3]) { /* 16 cubed */ Gridded3DMRSet.setResolution(Constant.RES16); System.out.println("UserInterface.readResolution(): " + Gridded3DMRSet.getResolution()); setNewData(Gridded3DMRSet.getResolution() + 1); return 1; } else if (event.getSource() == resolutionItems[4]) { /* 8 cubed */ Gridded3DMRSet.setResolution(Constant.RES8); System.out.println("UserInterface.readResolution(): " + Gridded3DMRSet.getResolution()); setNewData(Gridded3DMRSet.getResolution() + 1); return 1; } else if (event.getSource() == resolutionItems[5]) { /* 4 cubed */ Gridded3DMRSet.setResolution(Constant.RES4); System.out.println("UserInterface.readResolution(): " + Gridded3DMRSet.getResolution()); setNewData(Gridded3DMRSet.getResolution() + 1); return 1; } else if (event.getSource() == resolutionItems[6]) { /* 2 cubed */ Gridded3DMRSet.setResolution(Constant.RES2); System.out.println("UserInterface.readResolution(): " + Gridded3DMRSet.getResolution()); setNewData(Gridded3DMRSet.getResolution() + 1); return 1; } else { return 0; } } /** * This method is called from the ActionPerformed() method. It reads * the representation chosen from the Representation menu. */ private int readRepresentation(ActionEvent event) { if (event.getSource() == representationItems[0]) { /* MR */ Gridded3DMRSet.setRepresentation(Constant.MR); System.out.println("UserInterface.readRepresentation(): " + Gridded3DMRSet.getRepresentation()); return 1; } else if (event.getSource() == representationItems[1]) { /* AR 010 */ Gridded3DMRSet.setRepresentation(Constant.AR01); System.out.println("UserInterface.readRepresentation(): " + Gridded3DMRSet.getRepresentation()); return 1; } else if (event.getSource() == representationItems[2]) { /* AR 020 */ Gridded3DMRSet.setRepresentation(Constant.AR02); System.out.println("UserInterface.readRepresentation(): " + Gridded3DMRSet.getRepresentation()); return 1; } else if (event.getSource() == representationItems[3]) { /* AR 050 */ Gridded3DMRSet.setRepresentation(Constant.AR05); System.out.println("UserInterface.readRepresentation(): " + Gridded3DMRSet.getRepresentation()); return 1; } else if (event.getSource() == representationItems[4]) { /* AR 100 */ Gridded3DMRSet.setRepresentation(Constant.AR10); System.out.println("UserInterface.readRepresentation(): " + Gridded3DMRSet.getRepresentation()); return 1; } else if (event.getSource() == representationItems[5]) { /* AR 150 */ Gridded3DMRSet.setRepresentation(Constant.AR15); System.out.println("UserInterface.readRepresentation(): " + Gridded3DMRSet.getRepresentation()); return 1; } else if (event.getSource() == representationItems[6]) { /* AR 200 */ Gridded3DMRSet.setRepresentation(Constant.AR20); System.out.println("UserInterface.readRepresentation(): " + Gridded3DMRSet.getRepresentation()); return 1; } else if (event.getSource() == representationItems[7]) { /* AR 250 */ Gridded3DMRSet.setRepresentation(Constant.AR25); System.out.println("UserInterface.readRepresentation(): " + Gridded3DMRSet.getRepresentation()); return 1; } else { return 0; } } /** * */ private int readErrMode(ActionEvent event) { Object source=event.getSource(); if(source == errorItems[0]){ System.err.println("Selected HUE"); Gridded3DMRSet.setErrorVisualizationMode(Constant.HUE); widgetPanel.repaint(); return 1; } else if(source == errorItems[1]){ System.err.println("Selected SATURATION"); Gridded3DMRSet.setErrorVisualizationMode(Constant.SATURATION); widgetPanel.repaint(); return 1; } else if(source == errorItems[2]){ System.err.println("Selected BRIGHTNESS"); Gridded3DMRSet.setErrorVisualizationMode(Constant.BRIGHTNESS); widgetPanel.repaint(); return 1; } else if(source == errorItems[3]){ System.err.println("Selected TRANSPARENCY"); Gridded3DMRSet.setErrorVisualizationMode(Constant.TRANSPARENCY); widgetPanel.repaint(); return 1; } else if(source == errorItems[4]){ System.err.println("Selected OFF"); Gridded3DMRSet.setErrorVisualizationMode(Constant.NOERR); widgetPanel.repaint(); return 1; } else if(source == errorItems[5]){ System.err.println("Visualization Options Dialog"); if (vod != null) /* if there is already a dialog */ vod.dispose(); /* dispose of it */ vod = new VisOptionsDialog( new JFrame("Visualization Options Dialog")); vod.show(); return 1; } return 0; } /** * This method reads and sets up new data for the current display. *

* @param size -size of the volume data along each dimension (x,y,z) * @param filename -the file with the data in it */ private void setNewData(int size) { if (debug) System.out.println("UserInterface.setNewData()"); if (contourWidget != null) savedIsoValue = contourWidget.getSurfaceValue(); try { /* remove the old widgets from the user interface */ /* remove the old data from the display */ widgetPanel.remove(0); display.removeReference(isoRenderer.getDataReferenceImpl()); display.clearMaps(); /* add the new data to the display */ try { resetDisplay(isoRenderer.getDataReferenceImpl(), size); } catch (VisADException exc) { System.out.println("UserInterface.setNewData(),VisADException"); } catch (RemoteException exc) { System.out.println("UserInterface.setNewData(),RemoteException"); } /* add the new widgets to the user interface and refresh it */ ScalarMap mapContour=(ScalarMap) display.getMapVector().lastElement(); contourWidget = new ContourWidget(mapContour); contourWidget.setSurfaceValue(savedIsoValue); widgetPanel.add("Center", contourWidget); widgetPanel.validate(); widgetPanel.repaint(); } catch (VisADException exc) { System.out.println("UserInterface.setNewData(), VisADException"); } catch (RemoteException exc) { System.out.println("UserInterface.setNewData(), RemoteException"); } } /** * sets up the given display to use the specified data reference and * data * @param dataReference -a dataReference to the display * @param filename -the file with the data in it * @param size -the size of the volume data along each dimension (x,y,z) */ private void resetDisplay(DataReferenceImpl dataReference, int size) throws VisADException, RemoteException { if (debug) System.out.println("UserInterface.resetDisplay()"); /* add the maps to the display */ isoRenderer.initializeMaps(); /* add the data reference to the display */ if ((isoRenderer.initializeField(size, size, size)) == 0) { dataReference.setData(isoRenderer.getField()); display.addReference(dataReference); } else { System.out.println("UserInterface.resetDisplay() failed"); } } /** * This method is nice from a design point of view -only UserInterface * collaborates with Gridded3DMRSet * @return resolution -the current resolution of resolution */ public int getResolution() { return Gridded3DMRSet.getResolution(); } /** * @param level -the level corresponding to a particular size of volume * data * @return size -the length of 1 dimension (x,y,z) at that level */ public int getGridDimension(int level) { switch(level) { case(0): return 129; /* 128^3 blocks = 129^3 sample points */ case(1): return 65; /* 64^3 blocks = 65^3 sample points */ case(2): return 33; /* 32^3 blocks = 33^3 sample points */ case(3): return 17; /* 16^3 blocks = 17^3 sample points */ case(4): return 9; /* 8^3 blocks = 9^3 sample points */ case(5): return 5; /* 4^3 blocks = 5^3 sample points */ case(6): return 3; /* 2^3 blocks = 3^3 sample points */ case(7): return 2; /* 1^3 block = 2^3 sample points */ default: System.out.println("***Error,UserInterface.getGridDimension()"); return 2; } } /** * buildMenus -File, Format, Resolution, Representation */ void buildMenus( ) { JPopupMenu.setDefaultLightWeightPopupEnabled(false); if (debug) System.out.println("UserInterface.buildMenus()"); final byte menuCount = 6; UIMenus = new JMenu[menuCount]; UIMenus[0] = buildFileMenu(); UIMenus[1] = buildDataSetMenu(); UIMenus[2] = buildFormatMenu(); UIMenus[3] = buildResolutionMenu(); UIMenus[4] = buildRepresentationMenu(); UIMenus[5] = buildErrorMenu(); UIMenuBar = new JMenuBar(); for (int i = 0; i < UIMenus.length; i++) UIMenuBar.add(UIMenus[i]); } /** * build the File menu */ private JMenu buildFileMenu( ) { String fileNames[] = { "Open ", "Quit "}; int fileModes[] = { Constant.OPEN, Constant.QUIT }; JMenu fileMenu = new JMenu ("File"); fileItems = new JMenuItem[fileNames.length]; for (byte i = 0; i < fileNames.length; i++) { fileItems[i] = new JMenuItem(fileNames[i]); fileMenu.add(fileItems[i]); fileItems[i].addActionListener(this); } return fileMenu; } /** * build the Data Set menu * @return the Data Set JMenu */ private JMenu buildDataSetMenu( ) { String dataSetNames[] = { "Classic Cadaver Head", "Edible Lobster", "Ugly Knee", "Sphere", "AR Test Data Set I (ASCII only)", "AR Test Data Set II (ASCII only)"}; JMenu dataSetMenu = new JMenu ("DataSet"); dataSetItems = new JMenuItem[dataSetNames.length]; for (byte i = 0; i < dataSetNames.length; i++) { dataSetItems[i] = new JMenuItem(dataSetNames[i]); dataSetMenu.add(dataSetItems[i]); dataSetItems[i].addActionListener(this); } return dataSetMenu; } /** * build the Format menu * @return the Format JMenu */ private JMenu buildFormatMenu( ) { String formatNames[] = { "Text Format (for debugging)", "Binary Format (for performance)", "Floats (for MR data sets)", "Cubes (for AR data sets)"}; JMenu formatMenu = new JMenu ("DataFormat"); formatItems = new JMenuItem[formatNames.length]; for (byte i = 0; i < formatNames.length; i++) { formatItems[i] = new JMenuItem(formatNames[i]); formatMenu.add(formatItems[i]); formatItems[i].addActionListener(this); } return formatMenu; } /** * build the Resolution menu * @return the Resolution JMenu */ private JMenu buildResolutionMenu() { String resolutions[] = { "128 x 128 x 128", "64 x 64 x 64", "32 x 32 x 32", "16 x 16 x 16", "8 x 8 x 8", "4 x 4 x 4", "2 x 2 x 2"}; JMenu resolutionMenu = new JMenu("Resolution"); resolutionItems = new JMenuItem[resolutions.length]; for (byte i = 0; i < resolutions.length; i++) { resolutionItems[i] = new JMenuItem(resolutions[i]); resolutionMenu.add(resolutionItems[i]); resolutionItems[i].addActionListener(this); } return resolutionMenu; } /** * build the Representation Menu */ private JMenu buildRepresentationMenu() { String levels[] = { "MultiResolution (MR)", "Adaptive Resolution 01% threshold", "Adaptive Resolution 02% threshold", "Adaptive Resolution 05% threshold", "Adaptive Resolution 10% threshold", "Adaptive Resolution 15% threshold", "Adaptive Resolution 20% threshold", "Adaptive Resolution 25% threshold"}; JMenu representationMenu = new JMenu("Representation"); representationItems = new JMenuItem[levels.length]; for (byte i = 0; i < levels.length; i++) { representationItems[i] = new JMenuItem(levels[i]); representationMenu.add(representationItems[i]); representationItems[i].addActionListener(this); } return representationMenu; } /** * This method builds the error menu */ private JMenu buildErrorMenu( ) { String errorNames[] = {"Hue", "Saturation", "Brightness", "Transparency", "Off", "Vis Options Dialog" }; int ErrorModes[] = { Constant.HUE, Constant.SATURATION, Constant.BRIGHTNESS, Constant.TRANSPARENCY, Constant.NOERR }; JMenu errorMenu = new JMenu ("Error Visualization"); errorItems = new JMenuItem[errorNames.length]; for (byte i = 0; i < errorNames.length; i++) { errorItems[i] = new JMenuItem(errorNames[i]); errorMenu.add(errorItems[i]); errorItems[i].addActionListener(this); } return errorMenu; } }