001: /*
002: * ColumnExpressionPanel.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.filter;
013:
014: import java.awt.Color;
015: import java.awt.Dimension;
016: import java.awt.GridBagConstraints;
017: import java.awt.GridBagLayout;
018: import java.awt.Insets;
019: import java.awt.event.ActionEvent;
020: import java.awt.event.ActionListener;
021: import java.util.ArrayList;
022: import javax.swing.JCheckBox;
023: import javax.swing.JComboBox;
024: import javax.swing.JPanel;
025: import javax.swing.JTextField;
026: import workbench.db.ColumnIdentifier;
027: import workbench.gui.components.TextComponentMouseListener;
028: import workbench.gui.components.WbTraversalPolicy;
029: import workbench.log.LogMgr;
030: import workbench.resource.ResourceMgr;
031: import workbench.storage.ResultInfo;
032: import workbench.storage.filter.ColumnComparator;
033: import workbench.storage.filter.ColumnExpression;
034: import workbench.storage.filter.ComparatorFactory;
035: import workbench.storage.filter.DataRowExpression;
036: import workbench.storage.filter.ExpressionValue;
037: import workbench.util.ValueConverter;
038:
039: /**
040: * @author support@sql-workbench.net
041: */
042: public class ColumnExpressionPanel extends JPanel implements
043: ActionListener {
044: private final ComparatorFactory factory = new ComparatorFactory();
045: private JComboBox comparatorDropDown;
046: private JCheckBox ignoreCase;
047: protected JComboBox columnSelector;
048: private ArrayList comparatorItems;
049: private ListComboBoxModel activeItems;
050: private ResultInfo columnInfo;
051: protected JTextField valueField;
052: private ValueConverter converter = new ValueConverter();
053: private Class lastColumnClass;
054: private boolean ignoreComparatorChange = false;
055:
056: public ColumnExpressionPanel(ResultInfo info, ExpressionValue filter) {
057: columnInfo = info;
058: comparatorDropDown = new JComboBox();
059: activeItems = new ListComboBoxModel();
060:
061: ColumnComparator[] comps = factory.getAvailableComparators();
062: comparatorItems = new ArrayList(comps.length);
063: for (int i = 0; i < comps.length; i++) {
064: comparatorItems.add(new ComparatorListItem(comps[i]));
065: }
066:
067: // pre-fill dropdown to calculate space
068: buildColumnComparatorDropDown(String.class);
069: comparatorDropDown.setModel(activeItems);
070:
071: Dimension d = comparatorDropDown.getPreferredSize();
072: comparatorDropDown.setPreferredSize(d);
073: comparatorDropDown.setMinimumSize(d);
074:
075: columnSelector = new JComboBox();
076: int count = info.getColumnCount();
077: ArrayList l = new ArrayList(count);
078: l.add("*");
079: for (int i = 0; i < count; i++) {
080: l.add(info.getColumnName(i));
081: }
082:
083: ListComboBoxModel model = new ListComboBoxModel(l);
084: columnSelector.setModel(model);
085:
086: this .setLayout(new GridBagLayout());
087: ignoreCase = new JCheckBox(ResourceMgr
088: .getString("LblFilterIgnoreCase"));
089: ignoreCase.setSelected(false);
090: ignoreCase.setEnabled(false);
091: valueField = new JTextField(10);
092: TextComponentMouseListener ml = new TextComponentMouseListener();
093: valueField.addMouseListener(ml);
094:
095: valueField.setMinimumSize(new Dimension(15, 24));
096:
097: GridBagConstraints c = new GridBagConstraints();
098: c.gridx = 0;
099: c.gridy = 0;
100: c.anchor = GridBagConstraints.WEST;
101: c.weighty = 0;
102: c.weightx = 0;
103: c.insets = new Insets(1, 0, 0, 0);
104: this .add(columnSelector, c);
105:
106: c.gridx++;
107: this .add(comparatorDropDown, c);
108:
109: c.gridx++;
110: this .add(ignoreCase, c);
111:
112: c.gridx++;
113: c.weightx = 1.0;
114: c.anchor = GridBagConstraints.WEST;
115: c.fill = GridBagConstraints.HORIZONTAL;
116: this .add(valueField, c);
117:
118: columnSelector.addActionListener(this );
119: comparatorDropDown.addActionListener(this );
120:
121: if (filter == null) {
122: columnSelector.setSelectedIndex(0);
123: columnSelector.repaint();
124: } else {
125: setExpressionValue(filter);
126: }
127: WbTraversalPolicy pol = new WbTraversalPolicy();
128: pol.addComponent(columnSelector);
129: pol.addComponent(comparatorDropDown);
130: pol.addComponent(ignoreCase);
131: pol.addComponent(valueField);
132: pol.setDefaultComponent(valueField);
133: this .setFocusTraversalPolicy(pol);
134: }
135:
136: public void actionPerformed(ActionEvent evt) {
137: if (evt.getSource() == this .columnSelector) {
138: try {
139: ignoreComparatorChange = true;
140: int index = this .columnSelector.getSelectedIndex();
141: if (index == 0) {
142: buildColumnComparatorDropDown(String.class);
143: } else {
144: ColumnIdentifier col = this .columnInfo
145: .getColumn(index - 1);
146: buildColumnComparatorDropDown(col);
147: }
148: } finally {
149: ignoreComparatorChange = false;
150: }
151: checkComparator();
152: } else if (!ignoreComparatorChange
153: && evt.getSource() == this .comparatorDropDown) {
154: checkComparator();
155: }
156: }
157:
158: private void checkComparator() {
159: try {
160: ColumnComparator comp = this .getComparator();
161:
162: if (comp != null) {
163: ignoreCase.setSelected(comp.supportsIgnoreCase());
164: ignoreCase.setEnabled(comp.supportsIgnoreCase());
165: boolean needsValue = comp.needsValue();
166: valueField.setEnabled(needsValue);
167: if (needsValue) {
168: valueField.setBackground(Color.WHITE);
169: } else {
170: valueField.setBackground(this .getBackground());
171: }
172: } else {
173: ignoreCase.setSelected(false);
174: ignoreCase.setEnabled(false);
175: }
176: } catch (Exception e) {
177: LogMgr.logError("ColumnExpressionPanel.actionPerformed()",
178: "Error when updating comparator", e);
179: }
180: }
181:
182: private int findColumnInDropDown(String col) {
183: ListComboBoxModel model = (ListComboBoxModel) this .columnSelector
184: .getModel();
185: return model.findItemIgnoreCase(col);
186: }
187:
188: public void setExpressionValue(ExpressionValue expr) {
189: String col = expr.getColumnName();
190: int index = 0;
191: if (!"*".equals(col))
192: this .columnInfo.findColumn(col);
193: if (index > -1) {
194: int ddIndex = findColumnInDropDown(col);
195: if (ddIndex > -1)
196: this .columnSelector.setSelectedIndex(ddIndex);
197: ComparatorListItem item = new ComparatorListItem(expr
198: .getComparator());
199: this .comparatorDropDown.setSelectedItem(item);
200: this .ignoreCase.setSelected(expr.isIgnoreCase());
201: Object value = expr.getFilterValue();
202: if (value != null) {
203: this .valueField.setText(value.toString());
204: }
205: }
206: }
207:
208: public void setFocusToColumn() {
209: this .valueField.requestFocus();
210: //this.columnSelector.requestFocus();
211: }
212:
213: public String getColumnName() {
214: return (String) columnSelector.getSelectedItem();
215: }
216:
217: public boolean validateInput() {
218: ColumnComparator comp = getComparator();
219: if (comp == null)
220: return false;
221: Object value = getFilterValue();
222: return comp.validateInput(value);
223: }
224:
225: public String getInputValue() {
226: return valueField.getText();
227: }
228:
229: public ExpressionValue getExpressionValue() {
230: String col = this .getColumnName();
231: if (col == null)
232: return null;
233: ColumnComparator comp = getComparator();
234: if (comp == null)
235: return null;
236: Object value = this .getFilterValue();
237: if (value == null && comp.needsValue())
238: return null;
239:
240: ExpressionValue exp = null;
241: if ("*".equals(col)) {
242: exp = new DataRowExpression(comp, value);
243: } else {
244: exp = new ColumnExpression(col, comp, value);
245: }
246: if (this .ignoreCase.isEnabled()) {
247: exp.setIgnoreCase(ignoreCase.isSelected());
248: }
249: return exp;
250: }
251:
252: public ColumnComparator getComparator() {
253: ComparatorListItem item = (ComparatorListItem) this .comparatorDropDown
254: .getSelectedItem();
255: if (item != null) {
256: return item.getComparator();
257: }
258: return null;
259: }
260:
261: public Object getFilterValue() {
262: String value = valueField.getText();
263: String col = getColumnName();
264: int colIndex = this .columnInfo.findColumn(col);
265: // If the any column ("*") entry is selected
266: // colIndex will be -1, and we simply return the value entered
267: // because we tried everything as a String
268: if (colIndex > -1) {
269: int type = this .columnInfo.getColumnType(colIndex);
270: try {
271: Object dataValue = this .converter.convertValue(value,
272: type);
273: return dataValue;
274: } catch (Exception e) {
275: LogMgr.logWarning(
276: "ColumnExpressionPanel.getFilterValue()",
277: "Error converting input value", e);
278: }
279: }
280: return value;
281: }
282:
283: private void buildColumnComparatorDropDown(ColumnIdentifier col) {
284: Class columnClass = null;
285: try {
286: columnClass = col.getColumnClass();
287: buildColumnComparatorDropDown(columnClass);
288: } catch (Exception e) {
289: LogMgr
290: .logError(
291: "ColumnExpressionPanel.buildColumnComparatorDropwDown()",
292: "Error finding column class", e);
293: }
294: }
295:
296: private void buildColumnComparatorDropDown(Class columnClass) {
297: try {
298: if (lastColumnClass != null
299: && columnClass.equals(lastColumnClass)) {
300: if (comparatorDropDown.getSelectedItem() == null) {
301: comparatorDropDown.setSelectedIndex(0);
302: }
303: return;
304: }
305: int count = comparatorItems.size();
306: int added = 0;
307: final ArrayList<ComparatorListItem> l = new ArrayList<ComparatorListItem>(
308: count);
309: for (int i = 0; i < count; i++) {
310: ComparatorListItem item = (ComparatorListItem) comparatorItems
311: .get(i);
312: if (item.getComparator().supportsType(columnClass)) {
313: l.add(item);
314: added++;
315: }
316: }
317:
318: activeItems.setData(l);
319: comparatorDropDown.setSelectedItem(null);
320: comparatorDropDown.setModel(activeItems);
321: if (added > 0) {
322: comparatorDropDown.setSelectedIndex(0);
323: }
324: } catch (Exception e) {
325: LogMgr
326: .logError(
327: "ColumnExpressionPanel.buildColumnComparatorDropwDown()",
328: "Error building dropdown", e);
329: }
330: }
331: }
332:
333: /**
334: * A wrapper class to display the operator for a comparator
335: */
336: class ComparatorListItem {
337: private ColumnComparator comparator;
338:
339: public ComparatorListItem(ColumnComparator comp) {
340: comparator = comp;
341: }
342:
343: public String toString() {
344: return comparator.getOperator();
345: }
346:
347: public ColumnComparator getComparator() {
348: return comparator;
349: }
350:
351: public boolean equals(Object other) {
352: if (other instanceof ComparatorListItem) {
353: return comparator
354: .equals(((ComparatorListItem) other).comparator);
355: }
356: return false;
357: }
358: }
|