package leaf.ui; import info.clearthought.layout.TableLayout; import info.clearthought.layout.TableLayoutConstraints; import java.awt.Dimension; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.ScrollPaneConstants; import leaf.data.OrderedMap; public class LeafOptionDialog extends JDialog { private Dimension OPTION_SIZE = new Dimension( 200, 20 ); private Dimension BUTTON_SIZE = new Dimension( 200, 20 ); private int MAX_VISIBLE_OPTIONS = 20; private static final long serialVersionUID = 1L; private String CANCEL_LABEL = "Cancelar"; private String okLabel = null; private final JLabel labelMessage = new JLabel(); private final JPanel optionsPanel = new JPanel(); private final JScrollPane optionsScrollPane = new JScrollPane(); private boolean cancelActive = true; private LeafInputField submitButton = new LeafInputField(); private Map map = null; private OrderedMap orderedMap = null; private List selected = new ArrayList(); private Map mapEnabledForKey = null; private Map mapChosenForKey = null; private String message = null; private boolean ordered = false; public LeafOptionDialog( LeafWindow owner, Map map, String message) { super( owner ); this.mapEnabledForKey = new HashMap(); this.mapChosenForKey = new HashMap(); this.message = message; cancelActive = false; for( KeyClass key : map.keySet() ) { mapEnabledForKey.put( key, true ); } startup( map, null ); } public LeafOptionDialog( LeafWindow owner, OrderedMap orderedMap, Map chosen, Map enabled, String message, String okButton) { super( owner ); ordered = true; this.message = message; okLabel = okButton; cancelActive = okButton != null; this.mapChosenForKey = chosen == null ? new HashMap() : chosen; this.mapEnabledForKey = enabled == null ? new HashMap() : chosen; if( chosen != null ) { for( KeyClass key : chosen.keySet() ) { Boolean isChosen = chosen.get( key ); if( isChosen != null && isChosen ) { selected.add( key ); } } } startup( null, orderedMap ); } private void startup( Map map, OrderedMap orderedMap ) { if( map == null ) { this.map = new HashMap(); } else { this.map = map; } if( orderedMap == null ) { this.orderedMap = new OrderedMap(); } else { this.orderedMap = orderedMap; } setupComponents( map == null ? orderedMap.iterator() : map.keySet().iterator(), map == null ? orderedMap.rows() : map.keySet().size(), map == null ? true : false ); setUndecorated( true ); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); getRootPane().setWindowDecorationStyle(JRootPane.NONE); setSize( getLayout().minimumLayoutSize( getRootPane() ) ); setLocationRelativeTo( getParent() ); setModal( true ); setVisible( true ); } private void setupComponents( Iterator iterator, Integer size, boolean ordered ) { double[] cols = new double[] { TableLayout.PREFERRED }; double[] rows = new double[(message == null ? 0 : 2) + 1 + (cancelActive ? 2 : 0)]; for( int i = 0; i < rows.length; ++i ) { rows[i] = TableLayout.PREFERRED; } TableLayout layout = new TableLayout( cols, rows ); layout.setVGap( 3 ); setContentPane( new LeafGradientPanel() ); getContentPane().setLayout( layout ); int shift = 0; if( message != null ) { labelMessage.setText( message ); getContentPane().add( labelMessage, new TableLayoutConstraints( 0, shift++ ) ); getContentPane().add( new JSeparator(), new TableLayoutConstraints( 0, shift++ ) ); } setupOptionsComponents( iterator, size ); getContentPane().add( optionsScrollPane, new TableLayoutConstraints( 0, shift++ ) ); if( cancelActive ) { getContentPane().add( new JSeparator(), new TableLayoutConstraints( 0, shift++ ) ); submitButton.setObject( ordered ? okLabel : CANCEL_LABEL ); submitButton.setClickable( true ); submitButton.setPreferredSize( BUTTON_SIZE ); getContentPane().add( submitButton, new TableLayoutConstraints( 0, shift++ ) ); addListenerToComponent( submitButton ); } ((JComponent) getContentPane()).setBorder( BorderFactory.createRaisedBevelBorder() ); } private void setupOptionsComponents( Iterator iterator, Integer size ) { int maxWidth = OPTION_SIZE.width; double[] cols = new double[] { TableLayout.PREFERRED }; double[] rows = new double[size]; for( int i = 0; i < rows.length; ++i ) { rows[i] = TableLayout.PREFERRED; } TableLayout layout = new TableLayout( cols, rows ); layout.setVGap( 3 ); optionsPanel.setLayout( layout ); KeyClass current = null; for( int i = 0; i < size && iterator.hasNext(); ++i ) { current = iterator.next(); LeafInputField component = new LeafInputField(); Object value; if( ordered ) { List values = orderedMap.getValues( current ); value = (values == null || values.size() == 0) ? null : values.get( 0 ); } else { value = map.get( current ); } component.setObject( value ); Boolean isChosen = mapChosenForKey.get( current ); component.setSelected( isChosen != null && isChosen ); Boolean isEnabled = mapEnabledForKey.get( current ); component.setClickable( isEnabled == null || isEnabled ); if(component.size != null && component.size.width > maxWidth ) { maxWidth = component.size.width; } optionsPanel.add( component, new TableLayoutConstraints( 0, i ) ); addListenerToComponent( component ); } optionsScrollPane.setViewportView( optionsPanel ); optionsScrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER ); JScrollBar verticalScrollBar = optionsScrollPane.getVerticalScrollBar(); verticalScrollBar.setUnitIncrement( (int) OPTION_SIZE.getHeight() + 3 ); optionsScrollPane.setVerticalScrollBar( verticalScrollBar ); optionsScrollPane.setVerticalScrollBarPolicy( size > MAX_VISIBLE_OPTIONS ? ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS : ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER ); optionsScrollPane.setPreferredSize( new Dimension( maxWidth + 30 , size > MAX_VISIBLE_OPTIONS ? (MAX_VISIBLE_OPTIONS * ((int) (OPTION_SIZE.getHeight() + 3 )) ) : (size * ((int) (OPTION_SIZE.getHeight() + 3 )) ) )); } private KeyClass getKeyForValue( Object value ) { if( value != null && map.containsValue( value ) ) { for( KeyClass key : map.keySet() ) { if( map.get( key ).equals( value ) ) { return key; } } } else if( ordered ) { return orderedMap.getKeyForValue( value ); } return null; } private void addListenerToComponent( JComponent component ) { component.addPropertyChangeListener( new PropertyChangeListener() { @Override public void propertyChange( PropertyChangeEvent e ) { if( e.getSource() instanceof LeafInputField ) { LeafInputField source = (LeafInputField) e.getSource(); if( LeafInputField.PROPERTY_CHANGED_CLICK.equals( e.getPropertyName() ) ) { if( !source.equals( submitButton ) ) { Object value = source.getObject(); if( value != null ) { KeyClass key = getKeyForValue( value ); if( selected.contains( key ) ) { selected.remove( key ); source.setSelected( false ); } else { selected.add( key ); source.setSelected( true ); } } } if( okLabel == null || source.equals( submitButton ) ) { close(); } } } } } ); } public KeyClass getOption() { return selected.isEmpty() ? null : selected.get( 0 ); } public List getSelected() { return selected; } public void close() { setVisible( false ); dispose(); } }