KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > nightlabs > rcp > composite > HorizontalMultiColumnCompositeList


1 /*
2  * Created on Jan 7, 2005
3  * by alex
4  *
5  */

6 package com.nightlabs.rcp.composite;
7
8 import java.util.ArrayList JavaDoc;
9 import java.util.HashSet JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.List JavaDoc;
12 import java.util.Set JavaDoc;
13
14 import org.eclipse.jface.viewers.ISelection;
15 import org.eclipse.jface.viewers.ISelectionChangedListener;
16 import org.eclipse.jface.viewers.ISelectionProvider;
17 import org.eclipse.jface.viewers.StructuredSelection;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.ControlEvent;
20 import org.eclipse.swt.events.ControlListener;
21 import org.eclipse.swt.events.KeyEvent;
22 import org.eclipse.swt.events.KeyListener;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.events.SelectionListener;
25 import org.eclipse.swt.layout.GridData;
26 import org.eclipse.swt.layout.GridLayout;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Slider;
29
30 /**
31  * Takes SelectableComposite s and display them in a
32  * vertically fixed but horizontal expandable list.
33  * A column number can be defined for the viewport.
34  * All composites will be set to the width needed
35  * to fill the whole column but keep their height.
36  *
37  * @author Alexander Bieber <alex[AT]nightlabs[DOT]de>
38  *
39  */

40 public class HorizontalMultiColumnCompositeList extends Composite implements ISelectionProvider {
41
42     private List JavaDoc children = new ArrayList JavaDoc();
43     private Set JavaDoc selectedChildren = new HashSet JavaDoc();
44     /**
45      * SelectionListener to add and remove to selectedChildren
46      */

47     private SelectableCompositeListener selectionChangeListener = new SelectableCompositeListener() {
48         public void selectionStateChanged(CompositeSelectionEvent evt) {
49             if (preserveRecursion)
50                 return;
51             if (!multiSelect) {
52                 exclusiveSelect(evt.getSource(),evt.isSelected());
53             }
54             else {
55                 boolean ctrlPressed = (evt.getStateMask() & SWT.CTRL) > 0;
56                 if (!ctrlPressed)
57                     exclusiveSelect(evt.getSource(),evt.isSelected());
58                 else {
59                     if (evt.isSelected()) {
60                         if (!selectedChildren.contains(evt.getSource()))
61                             selectedChildren.add(evt.getSource());
62                         else
63                             selectedChildren.remove(evt.getSource());
64                     }
65                     else
66                         selectedChildren.remove(evt.getSource());
67                 }
68             }
69         }
70         public void compositeDoubleClicked(SelectableComposite composite) {
71         }
72     };
73     
74     /**
75      * SelectionListener to the slider.
76      */

77     private SelectionListener scrollListener = new SelectionListener() {
78         public void widgetSelected(SelectionEvent evt) {
79             scrollTo(slider.getSelection());
80         }
81         public void widgetDefaultSelected(SelectionEvent arg0) {
82             // not called
83
}
84     };
85     
86     
87     private ControlListener coltrolListener = new ControlListener(){
88         public void controlMoved(ControlEvent arg0) {
89             // don't care
90
}
91         public void controlResized(ControlEvent arg0) {
92             HorizontalMultiColumnCompositeList.this.layout();
93             refreshList();
94         }
95     };
96     
97     private Set JavaDoc keySet = new HashSet JavaDoc();
98     private KeyListener keyListener = new KeyListener() {
99         public void keyPressed(KeyEvent evt) {
100             keySet.add(new Integer JavaDoc(evt.keyCode));
101             System.out.println("Key pressed for CompList : Key Code is: "+evt.keyCode);
102         }
103         public void keyReleased(KeyEvent evt) {
104             keySet.remove(new Integer JavaDoc(evt.keyCode));
105         }
106     };
107     
108     private int numColumns = 1;
109     private int verticalSpacing = 5;
110     private int verticalMargin = 5;
111     private int horizontalSpacing = 5;
112     private boolean multiSelect = false;
113     private Composite carrier;
114
115     private TightWrapperComposite wrapper;
116     private Composite carrierWrapper;
117     private Slider slider;
118     
119     
120     /**
121      * @param parent
122      * @param style
123      */

124     public HorizontalMultiColumnCompositeList(Composite parent, int style) {
125         super(parent, style);
126         this.setLayout(new GridLayout());
127         wrapper = new TightWrapperComposite(this,SWT.NONE,true);
128         
129         carrierWrapper = new Composite(wrapper,SWT.NONE);
130         carrierWrapper.setLayout(null);
131         GridData gd = new GridData();
132         gd.grabExcessHorizontalSpace = true;
133         gd.grabExcessVerticalSpace = true;
134         gd.horizontalAlignment = GridData.FILL;
135         gd.verticalAlignment = GridData.FILL;
136         carrierWrapper.setLayoutData(gd);
137         
138         carrier = new Composite(carrierWrapper,SWT.NONE);
139         carrier.setLayout(null);
140         
141         slider = new Slider(wrapper,SWT.HORIZONTAL);
142         GridData sliderGD = new GridData();
143         sliderGD.grabExcessHorizontalSpace = true;
144         sliderGD.horizontalAlignment = GridData.FILL;
145         slider.setLayoutData(sliderGD);
146         slider.setVisible(true);
147         slider.addSelectionListener(scrollListener);
148         this.addControlListener(coltrolListener);
149         this.addKeyListener(keyListener);
150     }
151     
152     /**
153      * Create and add a SelectableComposite
154      * @param style
155      * @return
156      */

157     public SelectableComposite createChild(int style) {
158         SelectableComposite child = new SelectableComposite(getCarrier(),style);
159         addChild(child);
160         return child;
161     }
162     
163     /**
164      * Add a child.
165      * @param child
166      */

167     public void addChild(SelectableComposite child) {
168         child.compositeListIdx = children.size();
169         child.addSelectionChangeListener(selectionChangeListener);
170         children.add(child);
171     }
172     
173     /**
174      * Add a child at the specified position.
175      *
176      * @param child
177      * @param idx
178      */

179     public void addChild(SelectableComposite child, int idx) {
180         child.compositeListIdx = idx;
181         child.addSelectionChangeListener(selectionChangeListener);
182         children.add(idx,child);
183         for (int i=idx+1; i<children.size(); i++){
184             SelectableComposite comp = (SelectableComposite)children.get(i);
185             comp.compositeListIdx = i;
186         }
187     }
188     
189     /**
190      * Remove the child at the specified index.
191      * If dispose id true the Composite will be disposed as well.
192      *
193      * @param idx
194      * @param dispose
195      */

196     public void removeChild(int idx, boolean dispose) {
197         selectedChildren.remove(children.get(idx));
198         if (dispose) {
199             ((SelectableComposite)children.get(idx)).dispose();
200         }
201         ((SelectableComposite)children.get(idx)).removeSelectionChangeListener(selectionChangeListener);
202         children.remove(idx);
203         for (int i=idx; i<children.size(); i++) {
204             SelectableComposite comp = (SelectableComposite)children.get(i);
205             comp.compositeListIdx = i;
206         }
207     }
208     
209     /**
210      * Will remove and dispose the child.
211      *
212      * @param idx
213      */

214     public void removeChild(int idx) {
215         removeChild(idx,true);
216     }
217     
218     /**
219      * Remove the given child and dispose it if dispose it true.
220      *
221      * @param child
222      * @param dispose
223      */

224     public void removeChild(SelectableComposite child, boolean dispose) {
225         removeChild(child.getCompositeListIdx(), dispose);
226     }
227     
228     /**
229      * Remove the first child with the given selectionObject and dispose it if dispose it true.
230      *
231      * @param selectionObject
232      * @param dispose
233      */

234     public void removeChildBySelectionObject(Object JavaDoc selectionObject, boolean dispose) {
235         SelectableComposite childToRemove = null;
236         if (selectionObject == null)
237             return;
238         for (Iterator JavaDoc iter = children.iterator(); iter.hasNext();) {
239             SelectableComposite child = (SelectableComposite) iter.next();
240             if (selectionObject.equals(child.getSelectionObject())) {
241                 childToRemove = child;
242                 break;
243             }
244         }
245         if (childToRemove != null)
246             removeChild(childToRemove, dispose);
247     }
248
249     /**
250      * Remove all children. If dispose is true
251      * they will be disposed as well.
252      *
253      * @param dispose
254      */

255     public void removeAll(boolean dispose) {
256         for (int i=children.size()-1; i>=0; i--){
257             removeChild(i,dispose);
258         }
259     }
260     
261     /**
262      * Remove and dispose all children.
263      */

264     public void removeAll() {
265         removeAll(true);
266     }
267     
268     /**
269      * Replace the child at replacedIdx with the Composite
270      * passed. If disposeReplaced is true the replaced Composite
271      * will be disposed.
272      *
273      * @param replacedIdx
274      * @param replacing
275      * @param disposeReplaced
276      */

277     public void replaceChild(int replacedIdx, SelectableComposite replacing, boolean disposeReplaced) {
278         selectedChildren.remove(children.get(replacedIdx));
279         if (disposeReplaced)
280             ((SelectableComposite)children.get(replacedIdx)).dispose();
281         ((SelectableComposite)children.get(replacedIdx)).removeSelectionChangeListener(selectionChangeListener);
282         replacing.compositeListIdx = replacedIdx;
283         replacing.addSelectionChangeListener(selectionChangeListener);
284         children.set(replacedIdx,replacing);
285     }
286     
287     /**
288      * Replace the child replaced with the Composite replacing.
289      * If disposeReplaced is true replaced will be disposed.
290      *
291      * @param replaced
292      * @param replacing
293      * @param disposeReplaced
294      */

295     public void replaceChild(SelectableComposite replaced, SelectableComposite replacing, boolean disposeReplaced) {
296         replaceChild(replaced.getCompositeListIdx(),replacing,disposeReplaced);
297     }
298     
299     /**
300      * Get the current set number of columns.
301      * @return
302      */

303     public int getNumColumns() {
304         return numColumns;
305     }
306     /**
307      * Set the number of columns. Default is 1.
308      * @param numColumns
309      */

310     public void setNumColumns(int numColumns) {
311         this.numColumns = numColumns;
312     }
313     
314     /**
315      * Check if items in this list are
316      * multiselectable.
317      *
318      * @return
319      */

320     public boolean isMultiSelect() {
321         return multiSelect;
322     }
323     
324     /**
325      * Set if items in this list are multiselectable.
326      *
327      * @param multiSelect
328      */

329     public void setMultiSelect(boolean multiSelect) {
330         this.multiSelect = multiSelect;
331     }
332     
333     /**
334      * Returns the carrier for all children.
335      * A child should be created with this
336      * as a parent or use {@link #createChild(int)}.
337      *
338      * @return
339      */

340     public Composite getCarrier() {
341         return carrier;
342     }
343     
344     private int columnScrollInc;
345     private int currentScrollColumn;
346     private int totalNumColumns;
347     
348     /**
349      * Rearranges the children of this list
350      * and redraws the composite.
351      *
352      */

353     protected void arrangeChildren() {
354         int carrierHeight = carrierWrapper.getSize().y;
355         int width = carrierWrapper.getSize().x;
356         int columnWidth = (width - (2*horizontalSpacing)) / numColumns;
357         int compositeWidth = columnWidth - (horizontalSpacing / 2);
358         columnScrollInc = columnWidth + (horizontalSpacing / 2);
359         int yRun = verticalMargin;
360         int xRun = horizontalSpacing;
361         totalNumColumns = 1;
362         carrier.setSize(0,carrierHeight);
363         
364         for (Iterator JavaDoc iter = children.iterator(); iter.hasNext();) {
365             SelectableComposite comp = (SelectableComposite) iter.next();
366             int compHeight = comp.getSize().y;
367             int compWidth = columnWidth - 2 * horizontalSpacing;
368             
369             if ((yRun+compHeight > carrierHeight-(2*verticalMargin)) && (yRun != verticalMargin)) {
370                 // if composite doesn't fit into column and
371
// is not the first comp in this column then
372
xRun += columnScrollInc;
373                 yRun = verticalMargin;
374                 totalNumColumns ++;
375             }
376             comp.setBounds(xRun,yRun,compWidth,compHeight);
377             yRun += compHeight + verticalSpacing;
378         }
379         slider.setVisible(totalNumColumns>numColumns);
380         slider.setMinimum(0);
381         slider.setMaximum(totalNumColumns-(numColumns-1));
382         slider.setSelection(currentScrollColumn);
383         slider.setIncrement(1);
384         slider.setThumb(1);
385         slider.setPageIncrement(1);
386         carrier.setSize((totalNumColumns + 1)*columnScrollInc, carrierHeight);
387         scrollTo(currentScrollColumn);
388         this.redraw();
389     }
390     
391     /**
392      * Scrolls the List to the given columnIndex but
393      * only until (totalColumnCount - numColumns) is reached.
394      *
395      * @param columnScrollIdx
396      */

397     protected void scrollTo(int columnScrollIdx) {
398         if (columnScrollIdx > totalNumColumns - numColumns) {
399             currentScrollColumn = totalNumColumns - numColumns;
400             slider.setSelection(currentScrollColumn);
401         }
402         else
403             currentScrollColumn = columnScrollIdx;
404     
405         if (currentScrollColumn < 0)
406             currentScrollColumn = 0;
407         carrier.setLocation(0-(currentScrollColumn*columnScrollInc),0);
408         
409         if ((slider.getSelection()) != currentScrollColumn) {
410             slider.setSelection(currentScrollColumn);
411         }
412         this.redraw();
413     }
414     
415     /**
416      * Rearranges the children and the scrollbar.
417      *
418      */

419     public void refreshList() {
420         arrangeChildren();
421     }
422     
423     private boolean preserveRecursion = false;
424     /**
425      * Clears the Map of selected Composites
426      * after setting the selection state of all
427      * entries to false.
428      */

429     private void clearSelectionMap(SelectableComposite causingComposite) {
430         preserveRecursion = true;
431         try {
432             for (Iterator JavaDoc iter = selectedChildren.iterator(); iter.hasNext();) {
433                 SelectableComposite comp = (SelectableComposite) iter.next();
434                 if (comp != causingComposite)
435                     comp.setSelected(false);
436             }
437             selectedChildren.clear();
438         } finally {
439             preserveRecursion = false;
440         }
441     }
442     
443     private void exclusiveSelect(SelectableComposite selection, boolean selected) {
444         clearSelectionMap(selection);
445         if (selected)
446             selectedChildren.add(selection);
447     }
448
449     /**
450      * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
451      */

452     public void addSelectionChangedListener(ISelectionChangedListener listener) {
453         throw new UnsupportedOperationException JavaDoc("Not implemented yet. Contact alex[at]nightlabs[dot]de.");
454     }
455
456     /**
457      * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
458      */

459     public void removeSelectionChangedListener(ISelectionChangedListener listener) {
460         throw new UnsupportedOperationException JavaDoc("Not implemented yet. Contact alex[at]nightlabs[dot]de.");
461     }
462
463     /**
464      * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
465      */

466     public void setSelection(ISelection selection) {
467         throw new UnsupportedOperationException JavaDoc("Not implemented yet. Contact alex[at]nightlabs[dot]de.");
468     }
469
470     /**
471      * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
472      */

473     public ISelection getSelection() {
474         Object JavaDoc[] sel = new Object JavaDoc[selectedChildren.size()];
475         Object JavaDoc[] comps = selectedChildren.toArray();
476         for (int i=0; i<comps.length; i++) {
477             Object JavaDoc selObj = (Object JavaDoc) ((SelectableComposite)comps[i]).getSelectionObject();
478             sel[i] = selObj;
479         }
480         ISelection result = new StructuredSelection(sel);
481         return result;
482     }
483 }
484
Popular Tags