Coverage report

  %line %branch
ca.spaz.cron.ui.SearchPanel$SearchAction
0% 
0% 

 1  
 /*
 2  
  * Created on 20-Mar-2005
 3  
  */
 4  
 package ca.spaz.cron.ui;
 5  
 
 6  
 import java.awt.*;
 7  
 import java.awt.event.*;
 8  
 import java.util.*;
 9  
 import java.util.List;
 10  
 
 11  
 import javax.swing.*;
 12  
 import javax.swing.event.*;
 13  
 import javax.swing.table.AbstractTableModel;
 14  
 
 15  
 import org.apache.log4j.Logger;
 16  
 
 17  
 import se.datadosen.component.RiverLayout;
 18  
 import ca.spaz.cron.CRONOMETER;
 19  
 import ca.spaz.cron.database.*;
 20  
 import ca.spaz.cron.datasource.*;
 21  
 import ca.spaz.gui.PrettyTable;
 22  
 
 23  
 /**
 24  
  * The search panel allows fast and easy searching of the food database, and
 25  
  * potentially multiple database sources.
 26  
  * 
 27  
  * @todo: Add multiple data sources (ex: web searches, CNF2001b)
 28  
  * 
 29  
  * @author davidson
 30  
  */
 31  
 public class SearchPanel extends JPanel implements ItemListener {
 32  
    /**
 33  
     * This Action invokes the search capability.
 34  
     * 
 35  
     * @author Chris Rose
 36  
     */
 37  
    private class SearchAction extends AbstractAction {
 38  
 
 39  0
       public SearchAction() {
 40  0
          super("Search");
 41  0
       }
 42  
 
 43  
       /*
 44  
        * (non-Javadoc)
 45  
        * 
 46  
        * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
 47  
        */
 48  
       public void actionPerformed(ActionEvent e) {
 49  0
          doDBSearch();
 50  0
       }
 51  
 
 52  
    }
 53  
 
 54  
    //   private static final String USER_DB = "My Foods";
 55  
    //   private static final String FOOD_DB = "USDA sr17";
 56  
 
 57  
    /**
 58  
     * Logger for this class
 59  
     */
 60  
    private static final Logger logger = Logger.getLogger(SearchPanel.class);
 61  
 
 62  
    private CRONOMETER cwapp;
 63  
    
 64  
    private ServingEditor info;
 65  
 
 66  
    private JComboBox sourceBox;
 67  
 
 68  
    private JTextField queryField;
 69  
    
 70  
    private FoodDBToolBar toolBar;
 71  
    
 72  
    private JTable resultTable = new PrettyTable();
 73  
 
 74  
    private ArrayList result = new ArrayList();
 75  
 
 76  
    private ResultsTableModel model = new ResultsTableModel();
 77  
 
 78  
    private Action searchAction;
 79  
 
 80  
    private Food selectedFood;
 81  
    
 82  
    public SearchPanel(CRONOMETER cwapp) {
 83  
       this.cwapp = cwapp;
 84  
 
 85  
       setLayout(new BorderLayout(4, 4));
 86  
       setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
 87  
       add(makeQueryPanel(), BorderLayout.NORTH);
 88  
       add(makeResultPanel(), BorderLayout.CENTER);
 89  
       add(makeSouthPanel(), BorderLayout.SOUTH);
 90  
       doDBSearch();
 91  
    }
 92  
    
 93  
    private JPanel makeSouthPanel() {
 94  
       JPanel jp = new JPanel(class="keyword">new BorderLayout(4,4));
 95  
       jp.add(getToolBar(), BorderLayout.NORTH);
 96  
       jp.add(getServingEditor(), BorderLayout.CENTER);      
 97  
       return jp;
 98  
    }
 99  
 
 100  
    private JPanel makeQueryPanel() {
 101  
       JPanel jp = new JPanel(class="keyword">new RiverLayout(1,1));
 102  
       jp.add(RiverLayout.CENTER, new JLabel("Search: "));
 103  
       jp.add(RiverLayout.CENTER, getSourceBox());
 104  
       jp.add(RiverLayout.HFILL, getQueryField());
 105  
       return jp;
 106  
    }
 107  
    
 108  
    private FoodDBToolBar getToolBar() {
 109  
       if (toolBar == null) {
 110  
          toolBar = new FoodDBToolBar();
 111  
       }
 112  
       return toolBar;
 113  
    }
 114  
    
 115  
    private JTextField getQueryField() {
 116  
       if (null == queryField) {
 117  
          queryField = new JTextField();
 118  
          queryField.setAction(getSearchAction());
 119  
 
 120  
       }
 121  
       return queryField;
 122  
    }
 123  
 
 124  
    private Action getSearchAction() {
 125  
       if (null == searchAction) {
 126  
          searchAction = new SearchAction();
 127  
       }
 128  
       return searchAction;
 129  
    }
 130  
 
 131  
    private JComboBox getSourceBox() {
 132  
       if (sourceBox == null) {
 133  
          sourceBox = new JComboBox(class="keyword">new Vector(Datasources.getInstance()
 134  
                .getDatasources()));
 135  
          sourceBox.addItemListener(new ItemListener() {
 136  
             public void itemStateChanged(ItemEvent e) {
 137  
                result.clear();
 138  
                model.fireTableDataChanged();
 139  
                queryField.requestFocus();
 140  
                queryField.selectAll();
 141  
             }
 142  
          });
 143  
          sourceBox.setAction(getSearchAction());
 144  
       }
 145  
       return sourceBox;
 146  
    }
 147  
 
 148  
    private JComponent makeResultPanel() {
 149  
       resultTable.setModel(model);
 150  
       resultTable.getSelectionModel().setSelectionMode(
 151  
             ListSelectionModel.SINGLE_SELECTION);
 152  
       resultTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
 153  
       resultTable.getTableHeader().setReorderingAllowed(false);
 154  
       resultTable.getSelectionModel().addListSelectionListener(
 155  
             new ListSelectionListener() {
 156  
                public void valueChanged(ListSelectionEvent e) {
 157  
                   if (e.getValueIsAdjusting())
 158  
                      return;
 159  
                   ListSelectionModel lsm = (ListSelectionModel) e.getSource();
 160  
                   if (!lsm.isSelectionEmpty()) {
 161  
                      logger.debug("valueChanged() - triggered new selection");
 162  
                      int selectedRow = lsm.getMinSelectionIndex();
 163  
                      Food f = model.getFood(selectedRow);
 164  
                      cwapp.getDailySummary().deselect();
 165  
                      foodSelected(f);
 166  
                   }
 167  
                }
 168  
             });
 169  
       resultTable.addMouseListener(new MouseAdapter() {
 170  
          public void mouseClicked(MouseEvent e) {
 171  
             int sel = resultTable.getSelectedRow();
 172  
             if (sel != -1) {
 173  
                if (e.getClickCount() == 2) {
 174  
                   doEditFood();
 175  
                }
 176  
             }
 177  
          }
 178  
       });
 179  
       JScrollPane jsp = new JScrollPane(resultTable);
 180  
       jsp.setPreferredSize(new Dimension(400, 300));
 181  
       jsp.getViewport().setBackground(Color.WHITE);
 182  
       jsp.setBorder(BorderFactory.createEtchedBorder());
 183  
       return jsp;
 184  
    }
 185  
 
 186  
    
 187  
    protected void foodSelected(Food f) {
 188  
       selectedFood = f;
 189  
       getServingEditor().setServing(new Serving(f));
 190  
       getToolBar().setSelectedFood(f);
 191  
       //cwapp.getDailySummary().deselect();
 192  
    }
 193  
    
 194  
 
 195  
    public ServingEditor getServingEditor() {
 196  
       if (null == info) {
 197  
          info = new ServingEditor(cwapp);
 198  
       }
 199  
       return info;
 200  
    }
 201  
    
 202  
    private void doEditFood() {
 203  
       if (selectedFood != null) {
 204  
          FoodEditor.editFood(selectedFood);
 205  
          foodSelected(selectedFood);
 206  
       }
 207  
    }
 208  
    
 209  
    public void deselect() {
 210  
       resultTable.getSelectionModel().clearSelection();
 211  
    }
 212  
 
 213  
    /**
 214  
     * Depending on the selected source, a different database will be searched
 215  
     */
 216  
    public void doDBSearch() {
 217  
 
 218  
       //       DatabaseID id = (DatabaseID) getSourceBox().getSelectedItem();
 219  
       //       Connection con =
 220  
       // ConnectionManager.getInstance(id.getID()).getConnection();
 221  
       //       if (null == con) {
 222  
       //           JOptionPane.showMessageDialog(this,
 223  
       //                   "Sorry, this source cannot yet be searched", "Source Invalid",
 224  
       //                   JOptionPane.ERROR_MESSAGE);
 225  
       //       } else {
 226  
       //           doDBSearch(con);
 227  
       //       }
 228  
 
 229  
       IFoodDatasource ds = (IFoodDatasource) getSourceBox().getSelectedItem();
 230  
       doDBSearch(ds);
 231  
 
 232  
       //      // search the user's foods:
 233  
       //      if (sourceBox.getSelectedItem().equals(USER_DB)) {
 234  
       //         Connection con = ConnectionManager.getInstance(FoodDB.ID)
 235  
       //               .getConnection();
 236  
       //         doDBSearch(con);
 237  
       //         return;
 238  
       //      }
 239  
       //
 240  
       //      // search the default foods:
 241  
       //      if (sourceBox.getSelectedItem().equals(FOOD_DB)) {
 242  
       //         Connection con = ConnectionManager.getInstance(FoodDB.ID)
 243  
       //               .getConnection();
 244  
       //         doDBSearch(con);
 245  
       //         return;
 246  
       //      }
 247  
       //
 248  
       //      JOptionPane.showMessageDialog(this,
 249  
       //            "Sorry, this source cannot yet be searched", "Source Invalid",
 250  
       //            JOptionPane.ERROR_MESSAGE);
 251  
    }
 252  
 
 253  
    /**
 254  
     * Execute a search query for a food.
 255  
     */
 256  
    public void doDBSearch(IFoodDatasource ds) {
 257  
       String query = getQueryField().getText().trim();
 258  
       if (query.length() == 0) {
 259  
          result.clear();
 260  
          if (ds == Datasources.getInstance().getMutableDataSource()) {
 261  
             List foods = ds.findAllFoods();
 262  
             result.addAll(foods);
 263  
          }
 264  
          model.fireTableDataChanged();
 265  
          return;
 266  
       }
 267  
       String[] parts = query.split("\\s");
 268  
       List foods = ds.findFoods(parts);
 269  
       result.clear();
 270  
       result.addAll(foods);
 271  
       //sortResults(); // Note: should only sort on user DB
 272  
       model.fireTableDataChanged();
 273  
    }
 274  
 
 275  
    /**
 276  
     * Sorts the query results by relevance. Currently sorted by number of times
 277  
     * the food has been consumed by the user so that foods they commonly eat
 278  
     * appear first.
 279  
     */
 280  
    private void sortResults() {
 281  
       Comparator c = new Comparator() {
 282  
          public int compare(Object a1, Object b1) {
 283  
             Food a = (Food) a1;
 284  
             Food b = (Food) b1;
 285  
             Integer ai = new Integer(a.getNumTimesConsumed());
 286  
             Integer bi = new Integer(b.getNumTimesConsumed());
 287  
             return bi.compareTo(ai);
 288  
          }
 289  
       };
 290  
       Collections.sort(result, c);
 291  
    }
 292  
 
 293  
    public class ResultsTableModel extends AbstractTableModel {
 294  
       /**
 295  
        * Logger for this class
 296  
        */
 297  
       private final Logger logger = Logger.getLogger(ResultsTableModel.class);
 298  
 
 299  
       private String[] columnNames = { "Description" };
 300  
 
 301  
       public String getColumnName(int col) {
 302  
          return columnNames[col].toString();
 303  
       }
 304  
 
 305  
       public int getRowCount() {
 306  
          return result.size();
 307  
       }
 308  
 
 309  
       public Food getFood(int i) {
 310  
          return (Food) result.get(i);
 311  
       }
 312  
 
 313  
       public int getColumnCount() {
 314  
          return columnNames.length;
 315  
       }
 316  
 
 317  
       public Object getValueAt(int row, class="keyword">int col) {
 318  
          Food f = getFood(row);
 319  
          if (f != null) {
 320  
             switch (col) {
 321  
             case 0:
 322  
                return f.getDescription();
 323  
             }
 324  
          }
 325  
          return "";
 326  
       }
 327  
 
 328  
       public Class getColumnClass(int col) {
 329  
          Object o = getValueAt(0, col);
 330  
          if (o != null) {
 331  
             return o.getClass();
 332  
          }
 333  
          return String.class;
 334  
       }
 335  
 
 336  
       public boolean isCellEditable(int row, class="keyword">int col) {
 337  
          return false;
 338  
       }
 339  
 
 340  
       public void setValueAt(Object value, int row, class="keyword">int col) {
 341  
          fireTableCellUpdated(row, col);
 342  
       }
 343  
 
 344  
    }
 345  
 
 346  
    public void itemStateChanged(ItemEvent e) {
 347  
       // Optimization -- eliminated duplicate DB search. This should save a
 348  
       // lot of time on large result sets.
 349  
       logger.debug("itemStateChanged() - fired with " + e.paramString());
 350  
       if (e.getStateChange() == ItemEvent.SELECTED) {
 351  
          doDBSearch();
 352  
       }
 353  
    }
 354  
 
 355  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.