//(c) Copyright 2013, Scott Vorthmann.
package org.vorthmann.zome.ui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import org.vorthmann.ui.Controller;
public class PolytopesDialog extends EscapeDialog
{
private final JCheckBox[] renderCheckboxes = new JCheckBox[4];
private final NumberPanel[] numberPanels = new NumberPanel[4];
public PolytopesDialog( Frame frame, final Controller controller )
{
super( frame, "Generate a 4D Polytope", true );
setSize( new Dimension( 350, 350 ) );
setLocationRelativeTo( frame );
Container content = getContentPane();
content .setLayout( new BorderLayout() );
{
JPanel topHalf = new JPanel();
// topHalf .setBorder( BorderFactory .createBevelBorder( BevelBorder .LOWERED ) );
topHalf .setLayout( new BorderLayout() );
{
JPanel labelAndGroup = new JPanel();
labelAndGroup .setToolTipText( "4-dimensional Coxeter (reflection) groups." );
{
JLabel label = new JLabel( "symmetry group" );
labelAndGroup .add( label );
}
{
String[] groupNames = controller .getCommandList( "groups" );
String defaultGroup = controller .getProperty( "group" );
JComboBox<String> groups = new JComboBox<String>( groupNames );
groups .setSelectedItem( defaultGroup );
groups .setMaximumRowCount( 6 );
groups .addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
JComboBox<?> combo = (JComboBox<?>) e.getSource();
String command = "setGroup." + combo .getSelectedItem().toString();
controller .actionPerformed( new ActionEvent( e .getSource(), e.getID(), command ) );
}
} );
labelAndGroup .add( groups );
}
topHalf .add( labelAndGroup, BorderLayout.NORTH );
}
{
JPanel checkboxList = new JPanel();
checkboxList .setLayout( new BoxLayout( checkboxList, BoxLayout.PAGE_AXIS ) );
checkboxList .add( Box.createRigidArea( new Dimension( 0, 15 ) ) );
checkboxList .setToolTipText( "The group is based on four mirror planes intersecting the 3-sphere." );
{
JPanel checkboxesAndLabel = new JPanel();
checkboxesAndLabel .setLayout( new BorderLayout() );
checkboxesAndLabel .setToolTipText( "Which mirrors should create pairs of balls." );
{
JLabel label = new JLabel( "use mirror" );
label .setMinimumSize( new Dimension( 1, 100 ) );
label .setHorizontalAlignment( SwingConstants.RIGHT );
checkboxesAndLabel .add( label, BorderLayout.CENTER );
}
{
JPanel checkboxes = new JPanel();
checkboxes .setLayout( new BoxLayout( checkboxes, BoxLayout.LINE_AXIS ) );
checkboxes .add( Box.createRigidArea( new Dimension( 20, 0 ) ) );
for ( int i = 3; i >= 0; i-- ) {
final int edge = i;
JCheckBox checkbox = new JCheckBox();
boolean enabled = "true" .equals( controller .getProperty( "edge." + i ) );
checkbox .setSelected( enabled );
checkbox .setActionCommand( "edge." + i );
checkbox .addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
controller .actionPerformed( e );
boolean enabled = "true" .equals( controller .getProperty( "edge." + edge ) );
renderCheckboxes[ edge ] .setEnabled( enabled );
if ( enabled )
{
boolean render = "true" .equals( controller .getProperty( "render." + edge ) );
renderCheckboxes[ edge ] .setSelected( render );
}
else
{
renderCheckboxes[ edge ] .setSelected( false );
}
}
} );
checkboxes .add( checkbox );
}
checkboxes .add( Box.createRigidArea( new Dimension( 30, 0 ) ) );
checkboxesAndLabel .add( checkboxes, BorderLayout.EAST );
}
checkboxList .add( checkboxesAndLabel );
}
{
JPanel checkboxesAndLabel = new JPanel();
checkboxesAndLabel .setLayout( new BorderLayout() );
checkboxesAndLabel .setToolTipText( "Which mirrors should create struts." );
{
JLabel label = new JLabel( "create struts" );
label .setMinimumSize( new Dimension( 1, 100 ) );
label .setHorizontalAlignment( SwingConstants.RIGHT );
checkboxesAndLabel .add( label, BorderLayout.CENTER );
}
{
JPanel checkboxes = new JPanel();
checkboxes .setLayout( new BoxLayout( checkboxes, BoxLayout.LINE_AXIS ) );
checkboxes .setMinimumSize( new Dimension( 1, 80 ) );
checkboxes .add( Box.createRigidArea( new Dimension( 20, 0 ) ) );
for ( int i = 3; i >= 0; i-- ) {
renderCheckboxes[ i ] = new JCheckBox();
boolean enabled = "true" .equals( controller .getProperty( "edge." + i ) );
boolean render = "true" .equals( controller .getProperty( "render." + i ) );
renderCheckboxes[ i ] .setEnabled( enabled );
renderCheckboxes[ i ] .setSelected( enabled && render );
renderCheckboxes[ i ] .setActionCommand( "render." + i );
renderCheckboxes[ i ] .addActionListener( controller );
checkboxes .add( renderCheckboxes[ i ] );
}
checkboxes .add( Box.createRigidArea( new Dimension( 30, 0 ) ) );
checkboxesAndLabel .add( checkboxes, BorderLayout.EAST );
}
checkboxList .add( checkboxesAndLabel );
}
checkboxList .add( Box.createRigidArea( new Dimension( 0, 15 ) ) );
topHalf .add( checkboxList, BorderLayout.CENTER );
}
content .add( topHalf, BorderLayout.NORTH );
}
{
JPanel quaternionPanel = new JPanel();
quaternionPanel .setBorder( BorderFactory .createTitledBorder( "rotation quaternion" ) );
quaternionPanel .setLayout( new BoxLayout( quaternionPanel, BoxLayout.PAGE_AXIS ) );
quaternionPanel .setToolTipText( "To pre-set the i, j, and k values, " +
"select a single strut before opening this dialog." );
// coordinates .add( Box.createRigidArea( new Dimension( 0, 10 ) ) );
Controller quaternionController = controller .getSubController( "rotation" );
String[] coords = new String[]{ "w", "x", "y", "z" };
String[] labels = new String[]{ " ", "+ i * ", "+ j * ", "+ k * " };
for ( int j = 0; j < labels.length; j++ ) {
String labelStr = labels[ j ];
JPanel coordinate = new JPanel();
coordinate .setLayout( new BoxLayout( coordinate, BoxLayout.LINE_AXIS ) );
{
JLabel label = new JLabel( labelStr );
Font biggestFont = label .getFont() .deriveFont( 20f );
label .setFont( biggestFont );
label .setHorizontalAlignment( SwingConstants.LEFT );
coordinate .add( label, BorderLayout.WEST );
}
{
numberPanels[ j ] = new NumberPanel( quaternionController .getSubController( coords[ j ]) );
coordinate .add( numberPanels[ j ], BorderLayout.CENTER );
}
quaternionPanel .add( coordinate );
}
content .add( quaternionPanel, BorderLayout.CENTER );
}
JPanel buttons = new JPanel();
content .add( buttons, BorderLayout .SOUTH );
JButton cancel = new JButton( "Cancel" );
cancel .addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
PolytopesDialog.this .setVisible( false );
}
} );
buttons .add( cancel );
JButton build = new JButton( "Generate" );
build .setActionCommand( "generate" );
build .addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
for ( NumberPanel numberPanel : numberPanels ) {
numberPanel .syncToModel();
}
PolytopesDialog.this .setVisible( false );
controller .actionPerformed( e );
}
} );
buttons .add( build );
}
@Override
public void setVisible( boolean b )
{
if ( b ) {
for ( NumberPanel numberPanel : numberPanels ) {
numberPanel .syncFromModel();
}
}
super.setVisible(b);
}
}