1 package org.columba.core.gui.search; 2 3 import java.awt.AlphaComposite ; 4 import java.awt.BorderLayout ; 5 import java.awt.Component ; 6 import java.awt.Container ; 7 import java.awt.Graphics ; 8 import java.awt.Graphics2D ; 9 import java.awt.Insets ; 10 import java.awt.event.ActionEvent ; 11 import java.awt.event.ActionListener ; 12 import java.awt.event.KeyAdapter ; 13 import java.awt.event.KeyEvent ; 14 import java.awt.geom.RoundRectangle2D ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Vector ; 18 19 import javax.swing.BorderFactory ; 20 import javax.swing.Box ; 21 import javax.swing.DefaultListCellRenderer ; 22 import javax.swing.Icon ; 23 import javax.swing.ImageIcon ; 24 import javax.swing.JButton ; 25 import javax.swing.JCheckBox ; 26 import javax.swing.JComboBox ; 27 import javax.swing.JLabel ; 28 import javax.swing.JList ; 29 import javax.swing.JMenuBar ; 30 import javax.swing.JMenuItem ; 31 import javax.swing.JPanel ; 32 import javax.swing.JPopupMenu ; 33 import javax.swing.JToolBar ; 34 import javax.swing.UIManager ; 35 import javax.swing.event.DocumentEvent ; 36 import javax.swing.event.DocumentListener ; 37 import javax.swing.event.PopupMenuEvent ; 38 import javax.swing.event.PopupMenuListener ; 39 40 import org.columba.api.gui.frame.IFrameMediator; 41 import org.columba.core.context.ContextResultListenerAdapter; 42 import org.columba.core.context.api.IContextResultEvent; 43 import org.columba.core.gui.action.AbstractColumbaAction; 44 import org.columba.core.gui.base.AscendingIcon; 45 import org.columba.core.gui.search.api.ICriteriaRenderer; 46 import org.columba.core.gui.search.api.ISearchPanel; 47 import org.columba.core.gui.toolbar.ToolBarButtonFactory; 48 import org.columba.core.resourceloader.IconKeys; 49 import org.columba.core.resourceloader.ImageLoader; 50 import org.columba.core.search.ResultListenerAdapter; 51 import org.columba.core.search.SearchRequest; 52 import org.columba.core.search.api.IResultEvent; 53 import org.columba.core.search.api.ISearchCriteria; 54 import org.columba.core.search.api.ISearchManager; 55 import org.columba.core.search.api.ISearchProvider; 56 import org.columba.core.search.api.ISearchRequest; 57 58 import com.jgoodies.forms.builder.DefaultFormBuilder; 59 import com.jgoodies.forms.layout.FormLayout; 60 61 public class SearchBar extends JPanel implements PopupMenuListener { 62 63 private IconTextField textField; 64 65 private ImageIcon icon = ImageLoader.getSmallIcon(IconKeys.EDIT_FIND); 66 67 private JButton searchButton; 68 69 private JCheckBox searchInsideCheckBox; 70 71 private ISearchPanel searchPanel; 72 73 private JComboBox providerComboBox; 74 75 private JButton contextButton; 76 77 private ContextSearchAction action; 78 79 private SearchDialog searchDialog; 80 81 private JButton moreButton; 82 83 private IFrameMediator frameMediator; 84 85 public SearchBar(final ISearchPanel searchPanel, 86 final IFrameMediator frameMediator) { 87 super(); 88 89 this.searchPanel = searchPanel; 90 this.frameMediator = frameMediator; 91 92 initComponents(); 93 94 layoutComponents(false); 95 96 initListeners(); 97 } 98 99 public void search(Iterator <ICriteriaRenderer> it, boolean matchAll) { 100 101 List <ISearchRequest> list = new Vector <ISearchRequest>(); 103 while (it.hasNext()) { 104 ICriteriaRenderer r = it.next(); 105 ISearchCriteria c = r.getCriteria(); 106 String providerName = r.getProvider().getTechnicalName(); 107 Object value = r.getValue(); 108 if (value == null) 110 continue; 111 112 String searchTerm = value.toString(); 113 114 list.add(new SearchRequest(c.getTechnicalName(), providerName, 115 searchTerm)); 116 } 117 118 searchPanel.searchComplex(list, matchAll, searchInsideCheckBox 120 .isSelected()); 121 } 122 123 public boolean isSelectedSearchInside() { 124 return searchInsideCheckBox.isSelected(); 125 } 126 127 private void toggleButtonStates(boolean enabled) { 128 action.setEnabled(enabled); 129 contextButton.setEnabled(enabled); 130 searchButton.setEnabled(enabled); 131 textField.setEnabled(enabled); 132 searchInsideCheckBox.setEnabled(enabled); 133 try { 134 moreButton.setEnabled(enabled); 135 } catch (RuntimeException e) { 136 e.printStackTrace(); 137 } 138 } 139 140 private void toggleSearchDialogVisibility() { 141 if (searchDialog == null) 142 searchDialog = new SearchDialog(frameMediator.getContainer() 143 .getFrame(), searchPanel.getSearchManager() 144 .getAllProviders()); 145 146 if (!searchDialog.isVisible()) { 147 int x = getLocationOnScreen().x; 148 Container c2 = getParent().getParent(); 150 int y = c2.getLocationOnScreen().y + c2.getHeight(); 151 int maxX = x + getWidth(); 152 153 int xx = maxX - searchDialog.getWidth(); 154 searchDialog.setLocation(xx, y); 155 searchDialog.setVisible(true); 156 157 if (searchDialog.isSuccess()) { 158 search(searchDialog.getAllCriteriaRenderer(), searchDialog 160 .isMatchAll()); 161 } 162 } else { 163 searchDialog.setVisible(false); 164 } 165 } 166 167 private void initListeners() { 168 moreButton.addActionListener(new ActionListener () { 170 public void actionPerformed(ActionEvent e) { 171 toggleSearchDialogVisibility(); 172 } 173 }); 174 175 textField.addKeyListener(new MyKeyListener()); 177 178 textField.getDocument().addDocumentListener(new MyDocumentListener()); 179 180 183 searchPanel.getSearchManager() 185 .addResultListener(new MyResultListener()); 186 187 searchButton.addActionListener(new ActionListener () { 189 public void actionPerformed(ActionEvent e) { 190 toggleButtonStates(false); 191 SearchBar.this.searchPanel.searchAll(textField.getText(), 192 searchInsideCheckBox.isSelected()); 193 } 194 }); 195 196 searchPanel.getContextSearchManager().addResultListener( 198 new MyContextResultListener()); 199 } 200 201 class MyDocumentListener implements DocumentListener { 202 203 public void changedUpdate(DocumentEvent e) { 204 handleEvent(e); 205 } 206 207 public void insertUpdate(DocumentEvent e) { 208 handleEvent(e); 209 } 210 211 public void removeUpdate(DocumentEvent e) { 212 handleEvent(e); 213 } 214 215 private void handleEvent(DocumentEvent e) { 216 updatePopupMenu(textField.getPopupMenu(), textField.getText()); 217 } 220 221 } 222 223 class MyComboBoxRenderer extends DefaultListCellRenderer { 224 225 @Override 226 public Component getListCellRendererComponent(JList list, Object value, 227 int index, boolean isSelected, boolean cellHasFocus) { 228 super.getListCellRendererComponent(list, value, index, isSelected, 229 cellHasFocus); 230 231 if (value instanceof ISearchProvider) { 233 ISearchProvider p = (ISearchProvider) value; 234 setText(p.getName()); 235 setIcon(p.getIcon()); 236 } 237 238 if (getIcon() == null) { 239 setBorder(BorderFactory.createEmptyBorder(0, 240 16 + getIconTextGap(), 0, 0)); 241 } else { 242 setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); 243 } 244 245 return this; 246 } 247 248 } 249 250 class CoolButton extends JButton { 251 252 public CoolButton(String text, Icon icon) { 253 super(text, icon); 254 } 255 256 public void paintComponent(Graphics g) { 257 Graphics2D g2d = (Graphics2D ) g; 258 259 int w = getWidth(); 260 int h = getHeight(); 261 262 g2d.setBackground(UIManager.getColor("control.background")); 263 g2d.setColor(UIManager.getColor("control.text")); 264 265 RoundRectangle2D.Float r2d = new RoundRectangle2D.Float (0, 0, 267 w + 30, h - 1, 20, 20); 268 269 g2d.clip(r2d); 271 272 g2d.fillRect(0, 0, w, h); 275 277 g2d.drawRoundRect(0, 0, w + 30, h - 1, 20, 20); 280 281 g2d.drawRoundRect(1, 1, w + 30, h - 3, 18, 18); 284 285 g2d.drawLine(w - 1, 1, w - 1, h); 288 289 g2d.drawLine(w - 2, 2, w - 2, h - 1); 292 g2d.setComposite(AlphaComposite.getInstance( 294 AlphaComposite.SRC_OVER, 0.1f)); 295 296 super.paintComponent(g); 298 299 } 300 } 301 302 private void layoutComponents(boolean hasResults) { 303 304 this.removeAll(); 305 306 FormLayout layout = new FormLayout( 307 "fill:default:grow, 2dlu, pref,1dlu, pref, 2dlu", 308 "fill:default:grow"); 310 311 DefaultFormBuilder builder = new DefaultFormBuilder(layout, this); 313 314 317 JLabel label = new JLabel ("Search:"); 319 label.setLabelFor(textField); 320 label.setDisplayedMnemonic('s'); 321 builder.append(label); 322 323 builder.append(textField); 324 325 builder.append(moreButton); 326 327 330 332 334 } 335 336 private void initComponents() { 337 textField = new IconTextField(icon, 20); 338 339 searchButton = new JButton ("Search"); 340 searchButton.setMnemonic('s'); 341 342 searchInsideCheckBox = new JCheckBox ("Search Inside"); 343 searchInsideCheckBox 344 .setToolTipText("Search Inside Previous Search Results"); 345 searchInsideCheckBox.setMnemonic('i'); 346 searchInsideCheckBox.setSelected(false); 347 349 action = new ContextSearchAction(frameMediator); 350 351 contextButton = ToolBarButtonFactory.createButton(action); 352 contextButton.setEnabled(true); 353 354 moreButton = ToolBarButtonFactory.createButton("", new AscendingIcon(), 355 false); 356 moreButton.setIcon(new AscendingIcon()); 357 moreButton.setDisabledIcon(new AscendingIcon()); 358 moreButton.setMargin(new Insets (1, 1, 1, 1)); 359 moreButton.setToolTipText("Advanced Search Options..."); 360 361 providerComboBox = new JComboBox (); 362 providerComboBox.setRenderer(new MyComboBoxRenderer()); 363 364 providerComboBox.addItem("Search All"); 365 ISearchManager manager = searchPanel.getSearchManager(); 366 Iterator <ISearchProvider> it = manager.getAllProviders(); 367 while (it.hasNext()) { 368 final ISearchProvider p = it.next(); 369 providerComboBox.addItem(p); 370 } 371 } 372 373 class MyContextResultListener extends ContextResultListenerAdapter { 374 375 @Override 376 public void finished(IContextResultEvent event) { 377 toggleButtonStates(true); 378 } 379 380 } 381 382 class ContextSearchAction extends AbstractColumbaAction { 383 ContextSearchAction(IFrameMediator mediator) { 384 super(mediator, "What's related"); 385 putValue(SMALL_ICON, ImageLoader.getSmallIcon("system-search.png")); 386 387 putValue(LARGE_ICON, ImageLoader.getIcon("system-search.png")); 389 390 putValue(AbstractColumbaAction.SHORT_DESCRIPTION, "What's related"); 391 putValue(AbstractColumbaAction.LONG_DESCRIPTION, "What's related"); 392 393 putValue(TOOLBAR_NAME, "What's related"); 394 395 setShowToolBarText(true); 396 397 } 398 399 public void actionPerformed(ActionEvent e) { 400 toggleButtonStates(false); 401 searchPanel.searchInContext(); 402 } 403 404 } 405 406 class MyKeyListener extends KeyAdapter { 407 408 @Override 409 public void keyReleased(KeyEvent e) { 410 char ch = e.getKeyChar(); 411 412 if (ch == KeyEvent.VK_ENTER) { 413 if (textField.getText().length() == 0) 414 return; 415 416 toggleButtonStates(false); 417 418 429 searchPanel.searchAll(textField.getText(), searchInsideCheckBox 430 .isSelected()); 431 } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { 432 if (textField.getText().length() == 0) 433 return; 434 textField.showPopup(); 435 textField.getPopupMenu().requestFocus(); 436 textField.getPopupMenu().getSelectionModel() 437 .setSelectedIndex(0); 438 } 439 440 } 441 442 } 443 444 public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 445 System.out.println("menu will become visible"); 446 447 updatePopupMenu(textField.getPopupMenu(), textField.getText()); 449 } 450 451 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 452 } 453 454 public void popupMenuCanceled(PopupMenuEvent e) { 455 } 456 457 private void updatePopupMenu(JPopupMenu menu, String searchTerm) { 458 System.out.println("update menu=" + searchTerm); 459 460 menu.removeAll(); 461 462 474 ISearchManager manager = searchPanel.getSearchManager(); 475 Iterator <ISearchProvider> it = manager.getAllProviders(); 476 while (it.hasNext()) { 477 final ISearchProvider p = it.next(); 478 479 492 JMenuItem m; 493 List <ISearchCriteria> v = p.getAllCriteria(searchTerm); 495 Iterator <ISearchCriteria> it2 = v.iterator(); 496 while (it2.hasNext()) { 497 final ISearchCriteria c = it2.next(); 498 if (c == null) 499 continue; 500 501 m = new JMenuItem (c.getTitle()); 502 m.setToolTipText(c.getDescription()); 503 m.setIcon(p.getIcon()); 504 m.addActionListener(new ActionListener () { 505 public void actionPerformed(ActionEvent e) { 506 searchPanel.searchInCriteria(textField.getText(), p 507 .getTechnicalName(), c.getTechnicalName(), 508 searchInsideCheckBox.isSelected()); 509 } 510 }); 511 menu.add(m); 512 } 513 514 if (it.hasNext()) 515 menu.addSeparator(); 516 } 517 518 menu.addSeparator(); 519 520 JMenuItem m = new JMenuItem ("Advanced Search..."); 521 m.setToolTipText("Advanced Search..."); 522 m.addActionListener(new ActionListener () { 523 public void actionPerformed(ActionEvent e) { 524 toggleSearchDialogVisibility(); 525 } 526 }); 527 menu.add(m); 528 529 531 534 555 menu.revalidate(); 556 menu.pack(); 557 } 558 559 public void install(JMenuBar menubar) { 560 if (menubar == null) 561 throw new IllegalArgumentException ("menubar == null"); 562 563 Component box = Box.createHorizontalGlue(); 564 menubar.add(box); 565 566 menubar.add(this); 567 } 568 569 public void install(JToolBar toolbar) { 570 if (toolbar == null) 571 throw new IllegalArgumentException ("toolbar"); 572 573 toolbar.add(contextButton); 574 575 JPanel p = new JPanel (); 576 p.setBorder(BorderFactory.createEmptyBorder(3, 0, 2, 0)); 577 p.setLayout(new BorderLayout ()); 578 p.add(this, BorderLayout.EAST); 579 580 toolbar.add(p); 581 } 582 583 class MyResultListener extends ResultListenerAdapter { 584 585 MyResultListener() { 586 } 587 588 @Override 589 public void finished(IResultEvent event) { 590 toggleButtonStates(true); 593 594 layoutComponents(true); 596 } 597 598 } 599 600 } 601 | Popular Tags |