View Javadoc

1   package org.springframework.richclient.command;
2   
3   import org.springframework.richclient.application.Application;
4   import org.springframework.richclient.command.config.CommandButtonConfigurer;
5   import org.springframework.richclient.command.config.CommandConfigurer;
6   import org.springframework.richclient.factory.ButtonFactory;
7   
8   import javax.swing.*;
9   import java.beans.PropertyChangeListener;
10  import java.beans.PropertyChangeEvent;
11  import java.awt.event.ComponentAdapter;
12  import java.awt.event.ComponentEvent;
13  import java.awt.*;
14  
15  public class SplitPaneExpansionToggleCommand extends ActionCommand
16  {
17  
18      private DefaultButtonModel model;
19  
20      public SplitPaneExpansionToggleCommand(String commandId, JSplitPane splitPane, boolean switchedAway)
21      {
22          super(commandId);
23          this.model = new SplitPaneExpansionButtonModel(splitPane, switchedAway);
24          ((CommandConfigurer) Application.services().getService(CommandConfigurer.class)).configure(this);
25      }
26  
27  
28      protected void doExecuteCommand()
29      {
30          //toggle
31          this.model.setSelected(!this.model.isSelected());
32  
33      }
34  
35      public void doHide()
36      {
37          this.model.setSelected(false);
38      }
39  
40      public void doShow()
41      {
42          this.model.setSelected(true);
43      }
44  
45      public AbstractButton createButton(String faceDescriptorId, ButtonFactory buttonFactory,
46                                         CommandButtonConfigurer configurer)
47      {
48          AbstractButton button = buttonFactory.createToggleButton();
49          attach(button, faceDescriptorId, configurer);
50          return button;
51      }
52  
53      public void attach(AbstractButton button, String faceDescriptorId,
54                         CommandButtonConfigurer configurer)
55      {
56          super.attach(button, faceDescriptorId, configurer);
57          button.setModel(this.model);
58      }
59  
60      public static class SplitPaneExpansionButtonModel extends DefaultButtonModel
61      {
62  
63          private final JSplitPane splitPane;
64  
65          private enum SWITCH_STATE
66          {
67              NO_ACTION, SWITCHED_AWAY, SWITCHED_AWAY_AND_MOVED
68          }
69  
70          ;
71  
72          private SWITCH_STATE state = SWITCH_STATE.NO_ACTION;
73  
74          private transient PropertyChangeListener listener = new PropertyChangeListener()
75          {
76              public void propertyChange(PropertyChangeEvent evt)
77              {
78                  fireStateChanged();
79  
80                  if (state == SWITCH_STATE.SWITCHED_AWAY)
81                      state = SWITCH_STATE.SWITCHED_AWAY_AND_MOVED;
82                  else if (state == SWITCH_STATE.SWITCHED_AWAY_AND_MOVED)
83                      state = SWITCH_STATE.NO_ACTION;
84              }
85          };
86  
87          public SplitPaneExpansionButtonModel(JSplitPane mySplitPane, boolean switchedAway)
88          {
89              super();
90              this.splitPane = mySplitPane;
91  
92              this.splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY,
93                      listener);
94  
95              this.splitPane.addComponentListener(new ComponentAdapter()
96              {
97                  @Override
98                  public void componentResized(ComponentEvent e)
99                  {
100                     if (state == SWITCH_STATE.SWITCHED_AWAY || state == SWITCH_STATE.SWITCHED_AWAY_AND_MOVED)
101                         hidePanel();
102                 }
103 
104             });
105 
106             if (switchedAway)
107                 this.state = SWITCH_STATE.SWITCHED_AWAY;
108         }
109 
110         public boolean isSelected()
111         {
112             return isShown();
113         }
114 
115         public void setSelected(boolean makeVisible)
116         {
117             super.setSelected(makeVisible);
118             if (makeVisible)
119             {
120                 splitPane.resetToPreferredSizes();
121                 state = SWITCH_STATE.NO_ACTION;
122             }
123             else
124             {
125                 hidePanel();
126             }
127         }
128 
129         private void hidePanel()
130         {
131             splitPane.setDividerLocation(getHideRightComponentDividerLocation());
132             state = SWITCH_STATE.SWITCHED_AWAY;
133         }
134 
135         private boolean isShown()
136         {
137             return splitPane.getDividerLocation() < (getHideRightComponentDividerLocation());
138         }
139 
140         private int getHideRightComponentDividerLocation()
141         {
142             Dimension size = splitPane.getSize();
143             int max = getRelevantDimensionpart(size);
144             Insets insets = splitPane.getInsets();
145             int relevantInset = getRelevantInsetpart(insets); // we need to correct with the border size
146             int dividerSize = splitPane.getDividerSize();// we need to correct with the size of the divider!
147             return max - (relevantInset + dividerSize);
148         }
149 
150         private int getRelevantInsetpart(Insets insets)
151         {
152             int orientation = splitPane.getOrientation();
153             int result = (orientation == JSplitPane.VERTICAL_SPLIT) ? // for vertical
154                     (insets.bottom) : //take the height
155                     (insets.right); //  else the width
156             return result;
157         }
158 
159         private int getRelevantDimensionpart(Dimension size)
160         {
161             int orientation = splitPane.getOrientation();
162             int result = (orientation == JSplitPane.VERTICAL_SPLIT) ? // for vertical
163                     (int) Math.ceil(size.getHeight()) : //take the height
164                     (int) Math.ceil(size.getWidth()); //  else the width
165             return result;
166         }
167     }
168 
169 }
170