/* File: InfoPanel.java University of Applied Science Berne,HTA-Biel/Bienne, Computer Science Department. Diploma thesis J3D Solar System Simulator Originally written by Marcel Portner & Bernhard Hari (c) 2000 CVS - Information : $Header: /var/cvsreps/projects/c450/2000/sss3d/source_diploma/sss3d/gui/infobox/InfoPanel.java,v 1.7 2000/12/13 13:39:35 portm Exp $ $Author: portm $ $Date: 2000/12/13 13:39:35 $ $State: Exp $ */ package sss3d.gui.infobox; import sss3d.contentbranch.CelestialObjectInfo; import sss3d.gui.*; import sss3d.utils.SSS3dConstants; import sss3d.utils.xmlparser.*; // gui import java.awt.*; import javax.swing.*; import javax.swing.tree.*; // tree view import org.w3c.dom.Document; import org.w3c.dom.DOMException; import org.w3c.dom.Element; import org.w3c.dom.Node; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import java.awt.event.ActionListener; import java.util.*; import javax.swing.event.*; /** * If a user selects the View/Planet Informations/Planet from the * menubar from the InfoBox, then a new tab gets added to the Box. * * @author Marcel Portner & Bernhard Hari * @version $Revision: 1.7 $ * @see InfoBox */ public class InfoPanel extends JPanel implements ActionListener, GlobalPanel{ // GUI components tree view private JScrollPane treeView; private JSplitPane jSplitPane; private JTree jTreeDocument; // GUI components edit view private JPanel editView = new JPanel(); private JTextField editField; private JButton updateButton; private JButton closeButton; private JLabel infoField; private JLabel parameter; private Component rigidArea; private InfoBox infobox; private CelestialObjectInfo cObjInfo; // references the current selected node inside the tree view private AdapterNode currentNode; // size of InfoPanel private int width; private int height; private XMLConstants xmlconstants; // hashtable for quicker access to the update method Hashtable treeElements = new Hashtable(); // xml tree view - compressed mode private boolean compress = true; private String type = SSS3dConstants.TYPES[SSS3dConstants.CELESTIALOBJECT_TYPE]; /** * Creates an information panel of a given celestial object. * * @param cObjInfo a reference to the CelestialObjectInfo */ public InfoPanel(CelestialObjectInfo cObjInfo, InfoBox infobox) { this.infobox = infobox; this.cObjInfo = cObjInfo; parameter = new JLabel(this.cObjInfo.getName()); xmlconstants = new XMLConstants(); // initialize hashtable for (int i = 0; i < XMLConstants.treeElementNames.length; i++) { treeElements.put(XMLConstants.treeElementNames[i], new Integer(i)); } try { // build GUI init(); } catch(Exception e) { e.printStackTrace(); } } /** * builds the basic GUI, called by constructor * */ private void init() throws Exception { setLayout(new BorderLayout()); createTreeView(); jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,treeView, editView); jSplitPane.setVisible(true); jSplitPane.setContinuousLayout( true ); jSplitPane.setDividerLocation( 350 ); this.add(jSplitPane,BorderLayout.CENTER); this.setVisible(true); } /** * Returns the type of this Panel. * * @return String panel type */ public String getType() { return type; } /** * This method isn't used at the moment. Returns null. * Reason : defined inside GlobalPanel.java */ public org.w3c.dom.Document getDocument() { return null; // not used } /** * Builds the complete GUI, called by init function * * @param name the name */ private void createTreeView() { jTreeDocument = new JTree(new DomToTreeModelAdapter(cObjInfo.getDocument())); jTreeDocument.putClientProperty("JTree.lineStyle", "Angled"); jTreeDocument.setEditable(true); jTreeDocument.getSelectionModel().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION); jTreeDocument.setShowsRootHandles(true); MyRenderer renderer = new MyRenderer(this); jTreeDocument.setCellRenderer(renderer); // build tree view treeView = new JScrollPane(jTreeDocument); treeView.setVisible(true); // build edit view editView.setLayout(new BoxLayout(editView, BoxLayout.Y_AXIS)); editView.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); JPanel header = new JPanel(); header.setLayout(new BoxLayout(header, BoxLayout.X_AXIS)); header.setAlignmentX(LEFT_ALIGNMENT); JLabel value = new JLabel("Value :",SwingConstants.LEFT); value.setAlignmentX(LEFT_ALIGNMENT); header.add(value); header.add(Box.createRigidArea(new Dimension(5,0))); parameter.setAlignmentX(LEFT_ALIGNMENT); header.add(parameter); header.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); editView.add(header); infoField = new JLabel("",SwingConstants.LEFT); infoField.setAlignmentX(LEFT_ALIGNMENT); editView.add(infoField); editField = new JTextField("",40); editField.setMinimumSize(new Dimension(50, 25)); editField.setPreferredSize(new Dimension(50, 25)); editField.setMaximumSize(new Dimension(150,25)); //editField.setSize( new Dimension(150,20) ); editField.setHorizontalAlignment(JTextField.LEFT); editField.setAlignmentX(LEFT_ALIGNMENT); editField.setEditable(false); editView.add(editField); //Lay out the buttons from left to right. JPanel buttonPane = new JPanel(); buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS)); buttonPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); buttonPane.setAlignmentX(LEFT_ALIGNMENT); updateButton = new JButton( "update" ); updateButton.setActionCommand("update"); updateButton.addActionListener(this); updateButton.setAlignmentX(LEFT_ALIGNMENT); updateButton.setVisible(false); buttonPane.add(updateButton); rigidArea = Box.createRigidArea(new Dimension(10, 0)); rigidArea.setVisible(false); buttonPane.add(rigidArea); closeButton = new JButton("close"); closeButton.setActionCommand("close"); closeButton.addActionListener(this); closeButton.setAlignmentX(LEFT_ALIGNMENT); buttonPane.add(closeButton); editView.add(buttonPane); // Wire the two views together. Use a selection listener // created with an anonymous inner-class adapter. jTreeDocument.addTreeSelectionListener( new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { TreePath p = e.getNewLeadSelectionPath(); if (p != null) { currentNode = (AdapterNode) p.getLastPathComponent(); editField.setText(currentNode.content()); String nodeName = currentNode.domNode.getNodeName(); parameter.setText(nodeName); infoField.setText(""); infoField.setIcon(null); // check if this value is modifiable or not int index = xmlconstants.getElementIndex(nodeName); if ( index >= 0 ) { if ( XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[index] ) { editField.setEditable(true); updateButton.setVisible(true); rigidArea.setVisible(true); }else { editField.setEditable(false); updateButton.setVisible(false); rigidArea.setVisible(false); } } } } } ); } /** * Updates the CelestialObjectInfo object. * * @param node node that needs to be updated */ private void updateCelestialObjectInfo(Node node) { String nodeName = currentNode.domNode.getNodeName(); infoField.setVisible(false); // get this value and set it correctly inside // CelestialObjectInfo..... Integer n = (Integer)treeElements.get( nodeName ); String value = editField.getText(); try { if (n != null) { switch ( n.intValue() ){ // the first five values aren't modifiable case 0 : // celestialobject case 1 : // general case 2 : // parameter case 3 : // type case 4 : break; // name case 5 : // scalingfactor cObjInfo.setScalingFactor( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 6 : // diameter cObjInfo.setDiameter( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 7 : // mindistancefromsun cObjInfo.setMinDistanceFromSun( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 8 : // maxdistancefromsun cObjInfo.setMaxDistanceFromSun( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 9 : // nbrofplanetpositions cObjInfo.setNbrOfPositions( (new Integer( value )).intValue() ); node.setNodeValue( value ); break; case 10 : // rotationperiod cObjInfo.setRotationPeriod( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 11 : // orbitperiod cObjInfo.setOrbitPeriod( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 12 : // meanorbitvelocity cObjInfo.setMeanOrbitVelocity( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 13 : // orbiteccentricity cObjInfo.setOrbitEccentricity( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 14 : // orbitinclinationtoecliptic cObjInfo.setOrbitInclinationToEcliptic( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 15 : // inclinationofequatortoorbit cObjInfo.setInclinationOfEquatorToOrbit( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 16 : // volume cObjInfo.setVolume( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 17 : // distance cObjInfo.setDistance( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 18 : // mass cObjInfo.setMass( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 19 : // density cObjInfo.setDensity( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 20 : // surfacegravity cObjInfo.setSurfaceGravity( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 21 : // escapevelocity cObjInfo.setEscapeVelocity( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 22 : // meantempatsolidsurface cObjInfo.setTempAtSolidSurface( (new Double( value )).doubleValue() ); node.setNodeValue( value ); break; case 23 : // majoratmosphericconstitutents cObjInfo.setAtmosphericConstitutents( value ); node.setNodeValue( value ); break; default : break; } } } catch( NumberFormatException e) { ImageIcon icon = new ImageIcon("images/warning.gif"); infoField.setIcon(icon); if ( n.intValue() == 9 ) { // integer infoField.setText("Please enter an integer value !"); }else { infoField.setText("Please enter a floating point value !"); } infoField.setVerticalTextPosition(SwingConstants.CENTER); infoField.setVisible(true); } // update document view jTreeDocument.expandPath(jTreeDocument.getSelectionPath()); jTreeDocument.repaint(); } /** * Returns the CelestialObjectInfo related to this InfoPanel * * @return CelestialObjectInfo CelestialObjectInfo related to this InfoPanel */ public CelestialObjectInfo getCelestialObjectInfo() { return cObjInfo; } /** * Sets the text of the parameter field (JLabel) * */ public void setParameterText() { if ( currentNode != null ) { TreePath tp = jTreeDocument.getSelectionPath(); currentNode = (AdapterNode)tp.getLastPathComponent(); if ( currentNode.domNode.getNodeName().equals("#document") ) { parameter.setText(cObjInfo.getName()); editField.setEditable(false); } else { parameter.setText(currentNode.domNode.getNodeName()); } } } /** * Implementation of action listener for update and close button inside edit view * * @param e java.awt.event.ActionEvent */ public void actionPerformed(java.awt.event.ActionEvent e) { if (e.getActionCommand().equals("update")) { // handle new input.... String str = editField.getText(); if ( currentNode != null ) { org.w3c.dom.NodeList nl = currentNode.domNode.getChildNodes(); String nodeName = currentNode.domNode.getNodeName(); if ( !nodeName.equals(XMLConstants.treeElementNames[0]) && // celestialobject !nodeName.equals(XMLConstants.treeElementNames[1]) && // general !nodeName.equals(XMLConstants.treeElementNames[2]) && // parameter !nodeName.equals(XMLConstants.treeElementNames[3]) && // type !nodeName.equals(XMLConstants.treeElementNames[4]) // name ) { for(int i = 0; i < nl.getLength(); i++) { org.w3c.dom.Node n = nl.item(i); if ( n.getNodeName().equals("#text") ) { updateCelestialObjectInfo(n); } } } } } else if(e.getActionCommand().equals("close")){ // close this tab JMenu menu = infobox.mObjectsInfo; int max = menu.getItemCount(); for(int i = 0; i < max; i++) { JMenuItem temp = menu.getItem(i); if( temp.getText().toLowerCase().equals( cObjInfo.getName() ) ) { temp.setSelected(false); } } infobox.removeInfoTab( cObjInfo ); } } }