/*****************************************************************************
* J3D.org Copyright (c) 2000
* Java Source
*
* This source is licensed under the GNU LGPL v2.1
* Please read http://www.gnu.org/copyleft/lgpl.html for more information
*
* This software comes with the standard NO WARRANTY disclaimer for any
* purpose. Use it at your own risk. If there's a problem you get to fix it.
*
****************************************************************************/
package org.j3d.ui.navigation;
// Standard imports
import javax.swing.*;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
// Application specific imports
import org.j3d.util.ImageLoader;
/**
* A toolbar for all navigation commands.
*
*
* The toolbar offers three buttons representing the navigation states. As this
* panel also implements the state listener, these will change in response to
* the mouse changing. Clicking these buttons will send the appropriate event
* back to it's registered listener. By default, the navigation toolbar does
* not have any state pre-set.
*
*
* Using the default images, the toolbar looks like this:
*
*
*
*
* @author Halden VR Centre, Institute for Energy Technology
* Updated for j3d.org by Justin Couch
* @version $Revision: 1.8 $
*/
public class NavigationToolbar extends JPanel
implements ActionListener, NavigationStateListener
{
// Constants for images
/** The name of the file for the pan cursor image */
private static final String PAN_BUTTON = "images/navigation/ButtonPan.gif";
/** The name of the file for the tilt cursor image */
private static final String TILT_BUTTON = "images/navigation/ButtonTilt.gif";
/** The name of the file for the fly cursor image */
private static final String FLY_BUTTON = "images/navigation/ButtonFly.gif";
/** The name of the file for the fly cursor image */
private static final String WALK_BUTTON = "images/navigation/ButtonWalk.gif";
/** The name of the file for the fly cursor image */
private static final String EXAMINE_BUTTON = "images/navigation/ButtonExamine.gif";
// Local variables
/** The current navigation state either set from us or externally */
private int navigationState = FLY_STATE;
/** An observer for navigation state change information */
private NavigationStateListener navigationListener;
/** Button group holding the navigation state buttons */
private ButtonGroup navStateGroup;
/** Button representing the fly navigation state */
private JToggleButton flyButton;
/** Button representing the tilt navigation state */
private JToggleButton tiltButton;
/** Button representing the pan navigation state */
private JToggleButton panButton;
/** Button representing the walk navigation state */
private JToggleButton walkButton;
/** Button representing the examine navigation state */
private JToggleButton examineButton;
/** The last selected button */
private JToggleButton lastButton;
/** Flag to indicate if user state selection is allowed */
private boolean allowUserSelect;
/**
* Create a new horizontal navigation toolbar with an empty list of
* viewpoints and disabled user selection of state.
*/
public NavigationToolbar()
{
this(true);
}
/**
* Create a new navigation toolbar with an empty list of viewpoints but
* controllable direction for the buttons. The user selection is disabled.
*
* @param horizontal True to lay out the buttons horizontally
*/
public NavigationToolbar(boolean horizontal)
{
if(horizontal)
setLayout(new GridLayout(1, 3));
else
setLayout(new GridLayout(3, 1));
navStateGroup = new ButtonGroup();
Icon icon = ImageLoader.loadIcon(FLY_BUTTON);
flyButton = new JToggleButton(icon, false);
flyButton.setMargin(new Insets(0,0,0,0));
flyButton.setToolTipText("Fly");
flyButton.addActionListener(this);
navStateGroup.add(flyButton);
add(flyButton);
icon = ImageLoader.loadIcon(TILT_BUTTON);
tiltButton = new JToggleButton(icon, false);
tiltButton.setMargin(new Insets(0,0,0,0));
tiltButton.setToolTipText("Tilt");
tiltButton.addActionListener(this);
navStateGroup.add(tiltButton);
add(tiltButton);
icon = ImageLoader.loadIcon(PAN_BUTTON);
panButton = new JToggleButton(icon, false);
panButton.setMargin(new Insets(0,0,0,0));
panButton.setToolTipText("Pan");
panButton.addActionListener(this);
navStateGroup.add(panButton);
add(panButton);
icon = ImageLoader.loadIcon(WALK_BUTTON);
walkButton = new JToggleButton(icon, false);
walkButton.setMargin(new Insets(0,0,0,0));
walkButton.setToolTipText("Walk");
walkButton.addActionListener(this);
navStateGroup.add(walkButton);
add(walkButton);
icon = ImageLoader.loadIcon(EXAMINE_BUTTON);
examineButton = new JToggleButton(icon, false);
examineButton.setMargin(new Insets(0,0,0,0));
examineButton.setToolTipText("Examine");
examineButton.addActionListener(this);
navStateGroup.add(examineButton);
add(examineButton);
allowUserSelect = false;
setEnabled(false);
}
//----------------------------------------------------------
// Local public methods
//----------------------------------------------------------
/**
* Set the listener for navigation state change notifications. By setting
* a value of null it will clear the currently set instance
*
* @param l The listener to use for change updates
*/
public void setNavigationStateListener(NavigationStateListener l)
{
navigationListener = l;
}
/**
* Toggle whether the UI will allow the user to change the state selected
* for navigation.
*
* @param allow True if the user can change the navigation state
*/
public void setAllowUserStateChange(boolean allow)
{
allowUserSelect = allow;
setEnabled(allowUserSelect);
}
//----------------------------------------------------------
// Methods required by the ActionListener
//----------------------------------------------------------
/**
* Process an action event on one of the buttons.
*
* @param evt The event that caused this method to be called
*/
public void actionPerformed(ActionEvent evt)
{
if(!allowUserSelect)
return;
Object src = evt.getSource();
if(src == flyButton)
{
navigationState = FLY_STATE;
if(navigationListener != null)
navigationListener.setNavigationState(navigationState);
}
else if(src == tiltButton)
{
navigationState = TILT_STATE;
if(navigationListener != null)
navigationListener.setNavigationState(navigationState);
}
else if(src == panButton)
{
navigationState = PAN_STATE;
if(navigationListener != null)
navigationListener.setNavigationState(navigationState);
}
else if(src == walkButton)
{
navigationState = WALK_STATE;
if(navigationListener != null)
navigationListener.setNavigationState(navigationState);
}
else if(src == examineButton)
{
navigationState = EXAMINE_STATE;
if(navigationListener != null)
navigationListener.setNavigationState(navigationState);
}
}
//----------------------------------------------------------
// Methods required by the NavigationStateListener
//----------------------------------------------------------
/**
* Notification that the panning state has changed to the new state.
*
* @param state One of the state values declared here
*/
public void setNavigationState(int state)
{
navigationState = state;
switch(navigationState)
{
case NavigationStateListener.FLY_STATE:
flyButton.setSelected(true);
lastButton = flyButton;
break;
case NavigationStateListener.PAN_STATE:
panButton.setSelected(true);
lastButton = panButton;
break;
case NavigationStateListener.TILT_STATE:
tiltButton.setSelected(true);
lastButton = tiltButton;
break;
case NavigationStateListener.WALK_STATE:
walkButton.setSelected(true);
lastButton = walkButton;
break;
case NavigationStateListener.EXAMINE_STATE:
examineButton.setSelected(true);
lastButton = examineButton;
break;
case NavigationStateListener.NO_STATE:
if(lastButton != null)
lastButton.setSelected(false);
break;
}
}
/**
* Callback to ask the listener what navigation state it thinks it is
* in.
*
* @return The state that the listener thinks it is in
*/
public int getNavigationState()
{
return navigationState;
}
//----------------------------------------------------------
// Methods Overriding Component
//----------------------------------------------------------
/**
* Set the panel enabled or disabled. Overridden to make sure the base
* components are properly handled.
*
* @param enabled true if this component is enabled
*/
public void setEnabled(boolean enabled)
{
super.setEnabled(enabled);
examineButton.setEnabled(enabled);
flyButton.setEnabled(enabled);
walkButton.setEnabled(enabled);
panButton.setEnabled(enabled);
tiltButton.setEnabled(enabled);
}
}