001    package org.springframework.richclient.command.support;
002    
003    import java.awt.Component;
004    import java.util.ArrayList;
005    import java.util.List;
006    
007    import javax.swing.AbstractButton;
008    import javax.swing.JPanel;
009    
010    import org.springframework.richclient.command.CommandGroupFactoryBean;
011    
012    import com.jgoodies.forms.builder.ButtonStackBuilder;
013    import com.jgoodies.forms.layout.ColumnSpec;
014    import com.jgoodies.forms.layout.RowSpec;
015    import com.jgoodies.forms.layout.Size;
016    
017    /**
018     * Creates a buttonstack: a panel with buttons that are vertically positioned.
019     * 
020     * @see org.springframework.richclient.command.support.ButtonBarGroupContainerPopulator
021     * @see com.jgoodies.forms.builder.ButtonStackBuilder
022     * 
023     * @author jh
024     */
025    public class ButtonStackGroupContainerPopulator extends SimpleGroupContainerPopulator
026    {
027        private RowSpec rowSpec;
028    
029        private ButtonStackBuilder builder;
030    
031        private List buttons = new ArrayList();
032    
033        /**
034         * Constructor. 
035         */
036        public ButtonStackGroupContainerPopulator() {
037            super(new JPanel());
038            builder = new ButtonStackBuilder((JPanel)getContainer());
039        }
040    
041        /**
042         * Define the minimum buttonsize of the buttonStack. This will actually
043         * replace the rowSpec with a new one. 
044         * 
045         * @param minimumSize
046         * @see #setRowSpec(RowSpec)
047         */
048        public void setMinimumButtonSize(Size minimumSize) 
049        {
050            this.rowSpec = new RowSpec(minimumSize);
051        }
052    
053        /**
054         * This allows to completely customize the rowspec.
055         * 
056         * @param rowSpec
057         */
058        public void setRowSpec(RowSpec rowSpec)
059        {
060            this.rowSpec = rowSpec;
061        }
062    
063        /**
064         * Set a custom columnSpec for the buttonstack.
065         * 
066         * @param columnSpec
067         */
068        public void setColumnSpec(ColumnSpec columnSpec)
069        {
070            if (columnSpec != null)
071                builder.getLayout().setColumnSpec(1, columnSpec);
072        }    
073        
074        /**
075         * @return the created ButtonStack panel
076         */
077        public JPanel getButtonStack() {
078            return builder.getPanel();
079        }
080    
081        /**
082         * @see SimpleGroupContainerPopulator#add(Component)
083         */
084        public void add(Component c) {
085            buttons.add(c);
086        }
087    
088        /**
089         * @see SimpleGroupContainerPopulator#addSeparator()
090         */
091        public void addSeparator() {
092            buttons.add(CommandGroupFactoryBean.SEPARATOR_MEMBER_CODE);
093        }
094    
095        /**
096         * @see SimpleGroupContainerPopulator#onPopulated()
097         */
098        public void onPopulated() {
099            int length = buttons.size();
100            for (int i = 0; i < length; i++) {
101                Object o = buttons.get(i);
102                if (o instanceof String && o == CommandGroupFactoryBean.SEPARATOR_MEMBER_CODE) {
103                    builder.addUnrelatedGap();
104                }
105                else if (o instanceof AbstractButton) {
106                    AbstractButton button = (AbstractButton)o;
107                    if (this.rowSpec != null) {
108                        addCustomGridded(button);
109                    }
110                    else {
111                        builder.addGridded(button);
112                    }
113                    if (i < buttons.size() - 1) {
114                        builder.addRelatedGap();
115                    }
116                }
117            }
118            builder.addGlue();
119        }
120    
121        /**
122         * Handle the custom RowSpec.
123         * 
124         * @param button
125         */
126        private void addCustomGridded(AbstractButton button) {
127            builder.getLayout().appendRow(this.rowSpec);
128            builder.getLayout().addGroupedRow(builder.getRow());
129            button.putClientProperty("jgoodies.isNarrow", Boolean.TRUE);
130            builder.add(button);
131            builder.nextRow();
132        }
133    
134    }