package com.hackerdude.swing.picklist.search; import java.awt.Frame; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.DefaultComboBoxModel; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.table.TableModel; import com.hackerdude.swing.SwingUtils; /** * This is a generic Search Dialog. See the generic search panel for details. * @author David Martinez * @version 1.0 */ public class GenericSearchDialog extends JDialog { GenericSearchPanel searchPanel = new GenericSearchPanel(); SearchInterface searchInterface; SearchCriteria[] availableCriteria; public Action FIND_ACTION = new FindAction(); public Action OK_ACTION = new OKAction(); public Action CANCEL_ACTION = new CancelAction(); Action[] itemLevelActions = null; Action[] groupLevelActions = null; int modalResult; public static final int MODAL_RESULT_OK = 1; public static final int MODAL_RESULT_CANCEL = 0; public GenericSearchDialog() { super(); initSearchDialog(); } public GenericSearchDialog(Frame owner) { super(owner); initSearchDialog(); } public GenericSearchDialog(Frame owner, boolean modal) { super(owner, modal); initSearchDialog(); } public GenericSearchDialog(Frame owner, String title) { super(owner, title); initSearchDialog(); } public GenericSearchDialog(Frame owner, String title, boolean modal) { super(owner, title, modal); initSearchDialog(); } private void initSearchDialog() { getContentPane().add(searchPanel); searchPanel.criteriaPanel.fldSearchField.grabFocus(); getRootPane().setDefaultButton(searchPanel.criteriaPanel.btnFind); getRootPane().registerKeyboardAction(CANCEL_ACTION, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); pack(); Point newPoint = SwingUtils.getCenteredWindowPoint(this); setLocation(newPoint); searchPanel.criteriaPanel.btnFind.setAction(FIND_ACTION); searchPanel.btnCancel.setAction(CANCEL_ACTION); searchPanel.btnOk.setAction(OK_ACTION); setItemLevelActionsEnabled(false); getResultsTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } public int getSelectionMode() { return searchPanel.resultsPanel.resultsTable.getSelectionModel().getSelectionMode(); } public void setSelectionMode(int newSelectionMode) { searchPanel.resultsPanel.resultsTable.setSelectionMode(newSelectionMode); } public void setSearchInterface(SearchInterface searchInterface) { this.searchInterface = searchInterface; } public void setTableModel(TableModel model) { searchPanel.resultsPanel.setTableModel(model); searchPanel.resultsPanel.resultsTable.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { System.out.println(event.getPropertyName()); } }); } /** * This button sets the item-level actions to place as buttons on the * bottom of the form. * <P>Item level actions will only be active when there is a selected * result on the search field. * * @param itemLevelActions Extra actions you want to include. */ public void setItemLevelActions(Action[] itemLevelActions) { this.itemLevelActions = itemLevelActions; searchPanel.setItemLevelActions(itemLevelActions); setItemLevelActionsEnabled(false); } public void setGroupLevelActions(Action[] groupActions) { this.groupLevelActions = groupActions; searchPanel.setGroupLevelActions(groupActions); } public void setAvailableCriteria(SearchCriteria[] criteria) { availableCriteria = criteria; searchPanel.criteriaPanel.cbCriteria.setModel(new DefaultComboBoxModel(criteria)); } public void setCurrentAvailableCriteria(SearchCriteria currentCriteria) { searchPanel.criteriaPanel.cbCriteria.setSelectedItem(currentCriteria); } class OKAction extends AbstractAction { public OKAction() { super("OK"); } public void actionPerformed(ActionEvent ev) { GenericSearchDialog.this.modalResult = MODAL_RESULT_OK; GenericSearchDialog.this.hide(); } } class CancelAction extends AbstractAction { public CancelAction() { super("Cancel"); } public void actionPerformed(ActionEvent ev) { GenericSearchDialog.this.modalResult = MODAL_RESULT_CANCEL; GenericSearchDialog.this.hide(); } } /** * Shows the search dialog as a modal box. * @return The modal result (either MODAL_RESULT_OK or MODAL_RESULT_CANCEL); */ public int showModalSearch() { modalResult = MODAL_RESULT_CANCEL; setModal(true); searchPanel.criteriaPanel.fldSearchField.grabFocus(); show(); return modalResult; } class FindAction extends AbstractAction { public FindAction() { super("Find"); } public void actionPerformed(ActionEvent ev) { if ( searchInterface == null ) { JOptionPane.showMessageDialog(GenericSearchDialog.this, "Search Interface not specified", "Error", JOptionPane.ERROR_MESSAGE); return; } if ( ! searchInterface.okToBeginSearch() ) { JOptionPane.showMessageDialog(GenericSearchDialog.this, "Cannot begin a search.", "Cannot begin search",JOptionPane.ERROR_MESSAGE); return; } if ( searchPanel.criteriaPanel.cbCriteria.getSelectedIndex() > -1 && ( searchPanel.criteriaPanel.fldSearchField.getText() ==null || ! searchPanel.criteriaPanel.fldSearchField.getText().equals("") ) ) { searchPanel.lblResultsMessage.setText("Searching..."); SearchCriteria criteria = searchPanel.criteriaPanel.getSelectedCriteria(); searchPanel.criteriaPanel.affectCriteriaWithTextField(criteria); setSearchEnabled(false); try { final SearchCriteria criteriaClone = (SearchCriteria)criteria.clone(); Thread myThread = new Thread() { public void run() { try { searchInterface.beginSearch(criteriaClone); SwingUtilities.invokeLater(new Runnable() { public void run() { int rowCount = searchPanel.resultsPanel.resultsTable.getRowCount(); boolean enableItemLevelActions = rowCount > 0; setItemLevelActionsEnabled(enableItemLevelActions); if ( enableItemLevelActions ) searchPanel.resultsPanel.resultsTable.getSelectionModel().setSelectionInterval(0,0); setSearchEnabled(true); searchPanel.lblResultsMessage.setText("Search for "+criteriaClone.getWhatToSearchFor()+" finished."); /** @todo Do handling of jTable events for selection-time */ } }); } catch (Throwable ex) { } } }; myThread.setName("Generic Search Thread"); myThread.start(); } catch (CloneNotSupportedException ex) { } } else { JOptionPane.showMessageDialog(GenericSearchDialog.this, "You didn't enter a search criteria.", "Nothing to Do!", JOptionPane.ERROR_MESSAGE); } } } public JTable getResultsTable() { return searchPanel.resultsPanel.resultsTable; } public void setItemLevelActionsEnabled(boolean enabled) { // OK is also an item level action OK_ACTION.setEnabled(enabled); if ( itemLevelActions != null ) { for ( int i=0; i<itemLevelActions.length; i++ ) { itemLevelActions[i].setEnabled(enabled); } } } public void setSearchEnabled(boolean enabled) { FIND_ACTION.setEnabled(enabled); searchPanel.criteriaPanel.fldSearchField.setEnabled(enabled); searchPanel.criteriaPanel.cbCriteria.setEnabled(enabled); if ( groupLevelActions!= null ) { for ( int i=0; i<groupLevelActions.length; i++ ) { groupLevelActions[i].setEnabled(enabled); } } } }