package org.vorthmann.zome.ui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import org.vorthmann.ui.CardPanel;
import org.vorthmann.ui.Controller;
public class OrbitPanel extends JPanel implements PropertyChangeListener
{
@Override
public void setToolTipText( String text )
{
orbitTriangle .setToolTipText( text );
orbitCheckboxes .setToolTipText( text );
}
private Controller enabledOrbits, drawnOrbits;
private final ContextualMenu directionPopupMenu;
private final JPanel orbitTriangle, orbitCheckboxes;
private final CardPanel cardPanel;
private MouseListener orbitPopup;
public OrbitPanel( final Controller selectedOrbits, final Controller drawnOrbits, ControlActions enabler )
{
this .enabledOrbits = selectedOrbits;
this .drawnOrbits = drawnOrbits;
orbitTriangle = new JPanel()
{
@Override
public void paintComponent( Graphics graphics )
{
enabledOrbits .repaintGraphics( "orbits", graphics, getSize() );
}
};
orbitCheckboxes = new JPanel();
final ActionListener indirection = new ActionListener()
{
@Override
public void actionPerformed( ActionEvent evt )
{
enabledOrbits .actionPerformed( evt );
}
};
// here's the containment hierarchy
this .setLayout( new BorderLayout() );
{
JPanel controlStrip = new JPanel();
controlStrip .setLayout( new BorderLayout() );
{
JPanel row1 = new JPanel();
row1 .setLayout( new GridLayout( 0, 3 ) );
row1 .add( createButton( "None", "setNoDirections", indirection ) );
final JCheckBox checkbox = createCheckbox( "single", "oneAtATime", indirection );
if ( "true" .equals( enabledOrbits .getProperty( "oneAtATime" ) ) )
checkbox .setSelected( true );
row1 .add( createButton( "All", "setAllDirections", new ActionListener()
{
@Override
public void actionPerformed( ActionEvent evt )
{
indirection .actionPerformed( evt );
checkbox .setSelected( false );
}
} ) );
row1 .add( checkbox, BorderLayout.WEST );
controlStrip .add( row1, BorderLayout.NORTH );
}
this .add( controlStrip, BorderLayout.NORTH );
}
{
cardPanel = new CardPanel();
cardPanel .add( "graphical", orbitTriangle );
{
orbitCheckboxes .setLayout( new BoxLayout( orbitCheckboxes, 1 ) );
JScrollPane scrollPanel = new JScrollPane( orbitCheckboxes );
cardPanel .add( "textual", scrollPanel );
}
this .add( cardPanel, BorderLayout.CENTER );
}
if ( enabler != null )
{
directionPopupMenu = new ContextualMenu();
directionPopupMenu.setLightWeightPopupEnabled( false );
directionPopupMenu.add( enabler .setMenuAction( "rZomeOrbits", new JMenuItem( "real Zome" ) ) );
directionPopupMenu.add( enabler .setMenuAction( "predefinedOrbits", new JMenuItem( "predefined" ) ) );
directionPopupMenu.add( enabler .setMenuAction( "usedOrbits", new JMenuItem( "used in model" ) ) );
directionPopupMenu.add( enabler .setMenuAction( "setAllDirections", new JMenuItem( "all" ) ) );
directionPopupMenu.add( enabler .setMenuAction( "configureDirections", new JMenuItem( "configure..." ) ) );
}
else
directionPopupMenu = null;
modeChanged( enabledOrbits .propertyIsTrue( "useGraphicalViews" ) );
systemChanged( selectedOrbits, drawnOrbits );
}
void modeChanged( boolean graphical )
{
if ( graphical )
cardPanel .showCard( "graphical" );
else
cardPanel .showCard( "textual" );
}
public void systemChanged( Controller buildOrbits, Controller shownOrbits )
{
if ( orbitPopup != null )
orbitTriangle .removeMouseListener( orbitPopup );
this .enabledOrbits .getMouseTool() .detach( orbitTriangle );
this .drawnOrbits .removePropertyListener( this );
this .enabledOrbits .removePropertyListener( this );
this .drawnOrbits = shownOrbits;
this .enabledOrbits = buildOrbits;
enabledOrbits .addPropertyListener( this );
drawnOrbits .addPropertyListener( this );
enabledOrbits .getMouseTool() .attach( orbitTriangle );
if ( directionPopupMenu != null )
{
orbitPopup = new ContextualMenuMouseListener( enabledOrbits, directionPopupMenu );
orbitTriangle .addMouseListener( orbitPopup );
orbitCheckboxes .addMouseListener( orbitPopup );
}
orbitsChanged();
}
public void orbitsChanged()
{
enabledOrbits .actionPerformed( new ActionEvent( orbitTriangle, 0, "refreshDots" ) );
orbitCheckboxes .removeAll();
String[] dirNames = enabledOrbits .getCommandList( "allOrbits" );
for ( int j = 0; j < dirNames.length; j++ )
{
final String orbitName = dirNames[ j ];
JPanel panel = new JPanel();
panel .setMaximumSize( new Dimension( 600, 20 ) );
panel .setLayout( new BorderLayout() );
final JPanel colorSwatch = new JPanel()
{
@Override
public void paintComponent( Graphics graphics )
{
enabledOrbits .repaintGraphics( "oneOrbit." + orbitName, graphics, getSize() );
}
};
colorSwatch .setMaximumSize( new Dimension( 60, 20 ) );
colorSwatch .setPreferredSize( new Dimension( 60, 20 ) );
colorSwatch .setMinimumSize( new Dimension( 60, 20 ) );
panel .add( colorSwatch, BorderLayout.WEST );
{
JCheckBox checkbox = new JCheckBox();
checkbox .setText( orbitName );
checkbox .setVisible( true );
checkbox .setSelected( false );
checkbox .setActionCommand( "toggleDirection." + orbitName );
checkbox .addActionListener( enabledOrbits );
panel .add( checkbox, BorderLayout.CENTER );
}
orbitCheckboxes .add( panel );
}
enabledChanged();
}
private void enabledChanged()
{
String[] dirNames = enabledOrbits .getCommandList( "orbits" );
for ( int i = 0; i < orbitCheckboxes .getComponentCount(); i++ ) {
JPanel row = (JPanel) orbitCheckboxes .getComponent( i );
JCheckBox checkbox = (JCheckBox) row .getComponent( 1 );
checkbox .setSelected( false );
}
for ( int j = 0; j < dirNames.length; j++ )
{
for ( int i = 0; i < orbitCheckboxes .getComponentCount(); i++ ) {
JPanel row = (JPanel) orbitCheckboxes .getComponent( i );
JCheckBox checkbox = (JCheckBox) row .getComponent( 1 );
if ( dirNames[ j ] .equals( checkbox .getText() ) ) {
checkbox .setSelected( true );
break;
}
}
}
orbitTriangle .repaint();
orbitCheckboxes .repaint();
// The repaint leaves some instances blank! don't know why.
// This seems to address the problem.
orbitCheckboxes .setVisible( false );
orbitCheckboxes .setVisible( true );
}
@Override
public void propertyChange( PropertyChangeEvent event )
{
switch ( event .getPropertyName() ) {
case "orbits":
orbitsChanged();
break;
case "useGraphicalViews":
if ( Boolean.TRUE .equals( event .getNewValue() ) )
cardPanel .showCard( "graphical" );
else
cardPanel .showCard( "textual" );
break;
default:
break;
}
}
protected static JButton createButton( String buttonText, String actionCommand, ActionListener listener )
{
JButton button = new JButton( buttonText );
button .addActionListener( listener );
button .setActionCommand( actionCommand );
return button;
}
protected static JCheckBox createCheckbox( String buttonText, String actionCommand, ActionListener listener )
{
JCheckBox button = new JCheckBox( buttonText, false );
button .addActionListener( listener );
button .setActionCommand( actionCommand );
return button;
}
}