KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > modeler > editor > SelectQueryOrderingTab


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.modeler.editor;
57
58 import java.awt.BorderLayout JavaDoc;
59 import java.awt.Dimension JavaDoc;
60 import java.awt.event.ActionEvent JavaDoc;
61 import java.awt.event.ActionListener JavaDoc;
62 import java.util.Iterator JavaDoc;
63
64 import javax.swing.JButton JavaDoc;
65 import javax.swing.JPanel JavaDoc;
66 import javax.swing.JScrollPane JavaDoc;
67 import javax.swing.JTable JavaDoc;
68 import javax.swing.ListSelectionModel JavaDoc;
69 import javax.swing.event.ListSelectionEvent JavaDoc;
70 import javax.swing.event.ListSelectionListener JavaDoc;
71 import javax.swing.table.AbstractTableModel JavaDoc;
72 import javax.swing.table.TableModel JavaDoc;
73 import javax.swing.tree.TreeModel JavaDoc;
74
75 import org.objectstyle.cayenne.map.Entity;
76 import org.objectstyle.cayenne.map.event.QueryEvent;
77 import org.objectstyle.cayenne.modeler.ProjectController;
78 import org.objectstyle.cayenne.modeler.util.EntityTreeModel;
79 import org.objectstyle.cayenne.modeler.util.MultiColumnBrowser;
80 import org.objectstyle.cayenne.modeler.util.UIUtil;
81 import org.objectstyle.cayenne.query.Ordering;
82 import org.objectstyle.cayenne.query.Query;
83 import org.objectstyle.cayenne.query.SelectQuery;
84 import org.objectstyle.cayenne.util.CayenneMapEntry;
85
86 import com.jgoodies.forms.builder.PanelBuilder;
87 import com.jgoodies.forms.layout.CellConstraints;
88 import com.jgoodies.forms.layout.FormLayout;
89
90 /**
91  * A panel for picking SelectQuery orderings.
92  *
93  * @author Andrei Adamchik
94  */

95 public class SelectQueryOrderingTab extends JPanel JavaDoc {
96
97     static final Dimension JavaDoc BROWSER_CELL_DIM = new Dimension JavaDoc(150, 100);
98     static final Dimension JavaDoc TABLE_DIM = new Dimension JavaDoc(460, 60);
99
100     static final String JavaDoc PATH_HEADER = "Path";
101     static final String JavaDoc ASCENDING_HEADER = "Ascending";
102     static final String JavaDoc IGNORE_CASE_HEADER = "Ignore Case";
103
104     protected ProjectController mediator;
105     protected SelectQuery selectQuery;
106
107     protected MultiColumnBrowser browser;
108     protected JTable JavaDoc table;
109
110     public SelectQueryOrderingTab(ProjectController mediator) {
111         this.mediator = mediator;
112
113         initView();
114         initController();
115     }
116
117     protected void initView() {
118         // create widgets
119
JButton JavaDoc addButton = createAddPathButton();
120         JButton JavaDoc removeButton = createRemovePathButton();
121
122         browser = new MultiColumnBrowser();
123         browser.setPreferredColumnSize(BROWSER_CELL_DIM);
124         browser.setDefaultRenderer();
125
126         table = new JTable JavaDoc();
127         table.setRowHeight(25);
128         table.setRowMargin(3);
129         table.setPreferredScrollableViewportSize(TABLE_DIM);
130         table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
131
132         // assemble
133
setLayout(new BorderLayout JavaDoc());
134
135         CellConstraints cc = new CellConstraints();
136         // "fill:350dlu" is used instead of preferred size, so
137
// that bottom browser does not resize all the way when the window is enlarged
138
PanelBuilder builder = new PanelBuilder(new FormLayout(
139                 "fill:350dlu, 3dlu, fill:80dlu",
140                 "3dlu, top:p:grow, 3dlu, fill:100dlu"));
141
142         // orderings table must grow as the panel is resized
143
builder.add(new JScrollPane JavaDoc(table), cc.xywh(1, 1, 1, 2, "d, fill"));
144         builder.add(removeButton, cc.xy(3, 2, "d, top"));
145         builder.add(new JScrollPane JavaDoc(
146                 browser,
147                 JScrollPane.VERTICAL_SCROLLBAR_NEVER,
148                 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), cc.xywh(1, 4, 1, 1));
149
150         // while browser must fill the whole area, button must stay on top
151
builder.add(addButton, cc.xy(3, 4, "d, top"));
152         add(builder.getPanel(), BorderLayout.CENTER);
153     }
154
155     protected void initController() {
156
157         // scroll to selected row whenever a selection even occurs
158
table.getSelectionModel().addListSelectionListener(new ListSelectionListener JavaDoc() {
159
160             public void valueChanged(ListSelectionEvent JavaDoc e) {
161                 if (!e.getValueIsAdjusting()) {
162                     UIUtil.scrollToSelectedRow(table);
163                 }
164             }
165         });
166     }
167
168     protected void initFromModel() {
169         Query query = mediator.getCurrentQuery();
170
171         if (!(query instanceof SelectQuery)) {
172             setVisible(false);
173             return;
174         }
175
176         if (!(query.getRoot() instanceof Entity)) {
177             setVisible(false);
178             return;
179         }
180
181         this.selectQuery = (SelectQuery) query;
182
183         browser.setModel(createBrowserModel((Entity) selectQuery.getRoot()));
184         table.setModel(createTableModel());
185
186         // init column sizes
187
table.getColumnModel().getColumn(0).setPreferredWidth(250);
188
189         setVisible(true);
190     }
191
192     protected JButton JavaDoc createAddPathButton() {
193         JButton JavaDoc button = new JButton JavaDoc("Add Ordering");
194         button.addActionListener(new ActionListener JavaDoc() {
195
196             public void actionPerformed(ActionEvent JavaDoc event) {
197                 addOrdering();
198             }
199         });
200
201         return button;
202     }
203
204     protected JButton JavaDoc createRemovePathButton() {
205         JButton JavaDoc button = new JButton JavaDoc("Remove Ordering");
206         button.addActionListener(new ActionListener JavaDoc() {
207
208             public void actionPerformed(ActionEvent JavaDoc event) {
209                 removeOrdering();
210             }
211         });
212
213         return button;
214     }
215
216     protected TreeModel JavaDoc createBrowserModel(Entity entity) {
217         return new EntityTreeModel(entity);
218     }
219
220     protected TableModel JavaDoc createTableModel() {
221         return new OrderingModel();
222     }
223
224     protected String JavaDoc getSelectedPath() {
225         Object JavaDoc[] path = browser.getSelectionPath().getPath();
226
227         // first item in the path is Entity, so we must have
228
// at least two elements to constitute a valid ordering path
229
if (path != null && path.length < 2) {
230             return null;
231         }
232
233         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
234
235         // attribute or relationships
236
CayenneMapEntry first = (CayenneMapEntry) path[1];
237         buffer.append(first.getName());
238
239         for (int i = 2; i < path.length; i++) {
240             CayenneMapEntry pathEntry = (CayenneMapEntry) path[i];
241             buffer.append(".").append(pathEntry.getName());
242         }
243
244         return buffer.toString();
245     }
246
247     void addOrdering() {
248         String JavaDoc orderingPath = getSelectedPath();
249         if (orderingPath == null) {
250             return;
251         }
252
253         // check if such ordering already exists
254
Iterator JavaDoc it = selectQuery.getOrderings().iterator();
255         while (it.hasNext()) {
256             Ordering ord = (Ordering) it.next();
257             if (orderingPath.equals(ord.getSortSpecString())) {
258                 return;
259             }
260         }
261
262         selectQuery.addOrdering(new Ordering(orderingPath, Ordering.ASC));
263         int index = selectQuery.getOrderings().size() - 1;
264
265         OrderingModel model = (OrderingModel) table.getModel();
266         model.fireTableRowsInserted(index, index);
267         mediator.fireQueryEvent(new QueryEvent(SelectQueryOrderingTab.this, selectQuery));
268     }
269
270     void removeOrdering() {
271         int selection = table.getSelectedRow();
272         if (selection < 0) {
273             return;
274         }
275
276         OrderingModel model = (OrderingModel) table.getModel();
277         Ordering ordering = model.getOrdering(selection);
278         selectQuery.removeOrdering(ordering);
279
280         model.fireTableRowsDeleted(selection, selection);
281         mediator.fireQueryEvent(new QueryEvent(SelectQueryOrderingTab.this, selectQuery));
282     }
283
284     /**
285      * A table model for the Ordering editing table.
286      */

287     final class OrderingModel extends AbstractTableModel JavaDoc {
288
289         Ordering getOrdering(int row) {
290             return (Ordering) selectQuery.getOrderings().get(row);
291         }
292
293         public int getColumnCount() {
294             return 3;
295         }
296
297         public int getRowCount() {
298             return (selectQuery != null) ? selectQuery.getOrderings().size() : 0;
299         }
300
301         public Object JavaDoc getValueAt(int row, int column) {
302             Ordering ordering = getOrdering(row);
303
304             switch (column) {
305                 case 0:
306                     return ordering.getSortSpecString();
307                 case 1:
308                     return ordering.isAscending() ? Boolean.TRUE : Boolean.FALSE;
309                 case 2:
310                     return ordering.isCaseInsensitive() ? Boolean.TRUE : Boolean.FALSE;
311                 default:
312                     throw new IndexOutOfBoundsException JavaDoc("Invalid column: " + column);
313             }
314         }
315
316         public Class JavaDoc getColumnClass(int column) {
317             switch (column) {
318                 case 0:
319                     return String JavaDoc.class;
320                 case 1:
321                 case 2:
322                     return Boolean JavaDoc.class;
323                 default:
324                     throw new IndexOutOfBoundsException JavaDoc("Invalid column: " + column);
325             }
326         }
327
328         public String JavaDoc getColumnName(int column) {
329             switch (column) {
330                 case 0:
331                     return PATH_HEADER;
332                 case 1:
333                     return ASCENDING_HEADER;
334                 case 2:
335                     return IGNORE_CASE_HEADER;
336                 default:
337                     throw new IndexOutOfBoundsException JavaDoc("Invalid column: " + column);
338             }
339         }
340
341         public boolean isCellEditable(int row, int column) {
342             return column == 1 || column == 2;
343         }
344
345         public void setValueAt(Object JavaDoc value, int row, int column) {
346             Ordering ordering = getOrdering(row);
347
348             switch (column) {
349                 case 1:
350                     ordering.setAscending(((Boolean JavaDoc) value).booleanValue());
351                     mediator.fireQueryEvent(new QueryEvent(
352                             SelectQueryOrderingTab.this,
353                             selectQuery));
354                     break;
355                 case 2:
356                     ordering.setCaseInsensitive(((Boolean JavaDoc) value).booleanValue());
357                     mediator.fireQueryEvent(new QueryEvent(
358                             SelectQueryOrderingTab.this,
359                             selectQuery));
360                     break;
361                 default:
362                     throw new IndexOutOfBoundsException JavaDoc("Invalid editable column: "
363                             + column);
364             }
365
366         }
367     }
368 }
Popular Tags