2
* Copyright (c) 2005-2010 Laf-Widget Kirill Grouchnikov. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
7
* o Redistributions of source code must retain the above copyright notice,
8
* this list of conditions and the following disclaimer.
10
* o Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
14
* o Neither the name of Laf-Widget Kirill Grouchnikov nor the names of
15
* its contributors may be used to endorse or promote products derived
16
* from this software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
package org.pushingpixels.lafwidget.menu;
33
import java.awt.event.*;
34
import java.beans.PropertyChangeEvent;
35
import java.beans.PropertyChangeListener;
40
import org.pushingpixels.lafwidget.*;
43
* Adds menu search panel to menu bars.
45
* @author Kirill Grouchnikov
47
public class MenuSearchWidget extends LafWidgetAdapter<JMenuBar> implements
50
* Boolean flag to prevent infinite loop. Maybe need to use something more
53
private boolean inEvent = false;
56
* Listens on changes to the component orientation.
58
protected PropertyChangeListener propertyListener;
61
* The associated search panel.
63
private SearchPanel searchPanel;
66
* Panel for searching the menus.
68
* @author Kirill Grouchnikov
70
private class SearchPanel extends JPanel {
72
* Toggle button for showing / hiding search controls.
74
private JToggleButton searchButton;
77
* Text field for entering search string.
79
private JTextField searchStringField;
82
// * The associated menu bar.
84
// private JMenuBar menuBar;
87
* The result buttons. Key is {@link Integer}, value is {@link JButton}.
89
private Map<Integer, JButton> resultButtons;
95
* The associated menu bar.
97
public SearchPanel(final JMenuBar menuBar) {
98
// this.menuBar = menuBar;
99
this.setLayout(new SearchResultsLayout(this));
101
// Search button (toggle) with tooltip.
102
LafWidgetSupport support = LafWidgetRepository.getRepository()
104
int iconDim = support.getLookupIconSize();
105
int buttonDim = support.getLookupButtonSize();
106
Icon searchIcon = (support == null) ? LafWidgetUtilities
107
.getSearchIcon(iconDim, jcomp.getComponentOrientation()
108
.isLeftToRight()) : support.getSearchIcon(iconDim,
109
jcomp.getComponentOrientation());
110
this.searchButton = new JToggleButton(searchIcon);
111
this.searchButton.setPreferredSize(new Dimension(buttonDim,
113
ResourceBundle bundle = LafWidgetUtilities
114
.getResourceBundle(menuBar);
115
this.searchButton.setToolTipText(bundle
116
.getString("Tooltip.menuSearchButton"));
117
this.searchButton.setFocusable(false);
119
support.markButtonAsFlat(this.searchButton);
120
this.add(this.searchButton);
122
// Add action listener on the toggle button. Based on the
123
// state of the toggle button, the search field and result buttons
124
// will be set visible or invisible.
125
this.searchButton.addActionListener(new ActionListener() {
127
public void actionPerformed(ActionEvent e) {
128
SwingUtilities.invokeLater(new Runnable() {
131
boolean toShow = SearchPanel.this.searchButton
133
SearchPanel.this.searchStringField
135
SearchPanel.this.searchStringField.requestFocus();
136
for (JButton resultButton : SearchPanel.this.resultButtons
138
resultButton.setVisible(toShow);
140
SearchPanel.this.repaint();
141
SearchPanel.this.revalidate();
146
// add mouse listener to remove the search panel on mouse
147
// click when CTRL button is pressed.
148
this.searchButton.addMouseListener(new MouseAdapter() {
150
public void mousePressed(MouseEvent e) {
151
if ((e.getModifiers() & InputEvent.CTRL_MASK) != 0) {
152
SwingUtilities.invokeLater(new Runnable() {
155
SearchPanel.this.removeAll();
156
SearchPanel.this.repaint();
165
this.searchStringField = new JTextField();
166
this.searchStringField.setColumns(10);
167
this.add(this.searchStringField);
168
this.searchStringField.setVisible(false);
169
this.searchStringField.setToolTipText(bundle
170
.getString("Tooltip.menuSearchField"));
172
// Map to hold the result buttons (need for the icon reset
173
// on theme change and layout manager).
174
this.resultButtons = new HashMap<Integer, JButton>();
175
this.searchStringField.addActionListener(new ActionListener() {
177
public void actionPerformed(ActionEvent e) {
178
String searchString = SearchPanel.this.searchStringField
179
.getText().toLowerCase();
180
// See if there is at least one non-white space character.
181
// This is fix for bug 54
182
if (searchString.trim().length() == 0) {
186
// remove all old buttons
187
for (JButton toRemove : SearchPanel.this.resultButtons
189
SearchPanel.this.remove(toRemove);
191
SearchPanel.this.resultButtons.clear();
192
// find all matching menu items / menus
193
LinkedList<SearchResult> searchResults = SearchPanel.this
194
.findOccurences(searchString);
196
for (SearchResult searchResult : searchResults) {
197
// show only first 16 results.
200
// create new button with binary icon
201
LafWidgetSupport support = LafWidgetRepository
202
.getRepository().getLafSupport();
203
Icon markerIcon = support.getNumberIcon(count + 1);
204
JButton resultButton = new JButton(markerIcon);
205
// set action listener (to show the menu).
207
.addActionListener(new SearchResultListener(
209
// check if the path to the menu (item) has
210
// only enabled items.
211
resultButton.setEnabled(searchResult.isEnabled());
212
SearchPanel.this.add(resultButton);
213
SearchPanel.this.resultButtons.put(count + 1, resultButton);
214
resultButton.setToolTipText("<html><body><b>"
215
+ searchResult.toString()
217
+ LafWidgetUtilities.getResourceBundle(menuBar)
218
.getString("Tooltip.menuSearchTooltip")
221
support.markButtonAsFlat(resultButton);
224
SearchPanel.this.repaint();
231
* Returns all occurences of the specified string in the menus and menu
232
* items of the associated menu bar.
234
* @param searchPattern
235
* Pattern to search (no wildcards yet).
236
* @return All occurences of the specified string in the menus and menu
237
* items of the associated menu bar.
239
private LinkedList<SearchResult> findOccurences(String searchPattern) {
240
LinkedList<SearchResult> result = new LinkedList<SearchResult>();
242
LinkedList<JMenu> currentPath = new LinkedList<JMenu>();
244
for (int i = 0; i < jcomp.getComponentCount(); i++) {
245
Component component = jcomp.getComponent(i);
246
if (component instanceof JMenu) {
247
JMenu menu = (JMenu) component;
248
this.checkMenu(currentPath, menu, searchPattern, result);
256
* Recursively scans the specified menu (item) and updates the list that
257
* contains all occurences of the specified string in the contained
258
* menus and menu items.
261
* The path to the current menu (item). Contains
264
* The menu (item) itself that is being tested.
265
* @param searchPattern
266
* Pattern to search (no wildcards yet).
267
* @param matchingResults
268
* All occurences of the specified string up until now. After
269
* <code>this</code> function returns, will also contain
270
* all occurences of the specified string in the contained
271
* menu (item)s. Contains {@link SearchResult}s.
273
private void checkMenu(LinkedList<JMenu> currentPath,
274
JMenuItem menuItem, String searchPattern,
275
LinkedList<SearchResult> matchingResults) {
276
String menuItemText = menuItem.getText();
277
if (menuItemText.toLowerCase().indexOf(searchPattern) >= 0) {
278
matchingResults.addLast(new SearchResult(jcomp, currentPath,
281
if (menuItem instanceof JMenu) {
282
JMenu menu = (JMenu) menuItem;
283
currentPath.addLast(menu);
284
for (int i = 0; i < menu.getMenuComponentCount(); i++) {
285
Component menuComponent = menu.getMenuComponent(i);
286
if (menuComponent instanceof JMenuItem) {
287
JMenuItem childItem = (JMenuItem) menuComponent;
288
this.checkMenu(currentPath, childItem, searchPattern,
292
currentPath.removeLast();
299
* @see java.awt.Component#setVisible(boolean)
302
public void setVisible(boolean aFlag) {
303
super.setVisible(aFlag);
305
this.searchStringField.requestFocus();
310
* Listener on the <code>search result</code> button. The action itself -
311
* show the associated menu path to the menu item that contains the string
312
* that has been specified during the search.
314
* @author Kirill Grouchnikov
316
private static class SearchResultListener implements ActionListener {
318
* The associated search result.
320
private SearchResult searchResult;
323
* Simple constructor.
325
* @param searchResult
326
* The associated search result.
328
public SearchResultListener(SearchResult searchResult) {
330
this.searchResult = searchResult;
336
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
339
public void actionPerformed(ActionEvent e) {
340
// start opening the menus
341
MenuElement[] menuElements = this.searchResult.menuElements;
342
MenuSelectionManager.defaultManager().setSelectedPath(menuElements);
347
* Single result of menu search.
349
* @author Kirill Grouchnikov
351
private static class SearchResult {
353
* Path to the menu (item). The first element is always {@link JMenuBar},
354
* and after each {@link JMenu} there is it's
355
* {@link JMenu#getPopupMenu()}.
357
private MenuElement[] menuElements;
360
* Simple constructor.
365
* The menus leading to the matching entry. Contains
368
* The menu (item) that matches the search pattern string.
370
public SearchResult(JMenuBar menuBar, LinkedList<JMenu> menuPath,
371
JMenuItem menuLeaf) {
373
if (menuPath != null)
374
count += 2 * menuPath.size();
375
if (menuLeaf != null)
377
this.menuElements = new MenuElement[count];
380
// the first element is the menu bar itself
381
this.menuElements[count++] = menuBar;
382
if (menuPath != null) {
383
for (JMenu menu : menuPath) {
384
// JMenu menu = (JMenu) it.next();
385
this.menuElements[count++] = menu;
386
// important - don't forget the popup menu of the menu
387
this.menuElements[count++] = menu.getPopupMenu();
390
if (menuLeaf != null)
391
this.menuElements[count] = menuLeaf;
395
* Returns the path to the menu (item).
397
* @return Path to the menu (item). The first element is always
398
* {@link JMenuBar}, and after each {@link JMenu} there is it's
399
* {@link JMenu#getPopupMenu()}.
401
public MenuElement[] getMenuElements() {
402
return this.menuElements;
408
* @see java.lang.Object#toString()
411
public String toString() {
412
StringBuffer sb = new StringBuffer();
413
if (this.menuElements != null) {
415
for (int i = 0; i < this.menuElements.length; i++) {
416
MenuElement menuElem = this.menuElements[i];
417
if (menuElem instanceof JMenuItem) {
420
sb.append(((JMenuItem) menuElem).getText());
424
return sb.toString();
428
* Checks that all entries leading to the associated menu (item) are
431
* @return <code>true</code> if all entries leading to the associated
432
* menu (item) are enabled, <code>false</code> otherwise.
434
public boolean isEnabled() {
435
// all parts must be enabled
436
for (int i = 0; i < this.menuElements.length; i++) {
437
MenuElement menuElem = this.menuElements[i];
438
if (menuElem instanceof JMenuItem) {
439
JMenuItem menuItem = (JMenuItem) menuElem;
440
if (!menuItem.isEnabled())
449
* Returns the number of menu items under the specified menu item.
452
* The root menu item.
453
* @return The number of menu items under the specified menu item.
455
private static int getMenuItemCount(JMenuItem menuItem) {
458
if (menuItem instanceof JMenu) {
459
JMenu menu = (JMenu) menuItem;
460
for (int i = 0; i < menu.getMenuComponentCount(); i++) {
461
Component child = menu.getMenuComponent(i);
462
if (child instanceof JMenuItem)
463
result += MenuSearchWidget
464
.getMenuItemCount((JMenuItem) child);
472
* Returns the number of menu items under the specified menu bar.
476
* @return The number of menu items under the specified menu bar.
478
public static int getMenuItemCount(JMenuBar menuBar) {
481
for (int i = 0; i < menuBar.getMenuCount(); i++) {
482
JMenu menu = menuBar.getMenu(i);
484
result += MenuSearchWidget.getMenuItemCount(menu);
492
// * Hides search panels recursively on the specified component.
496
// * @param toRepaint
497
// * Indication whether the relevant menu bars should be repainted.
499
// private static void hideSearchPanels(Component comp, final boolean toRepaint)
501
// if (comp instanceof JFrame) {
502
// JFrame jf = (JFrame) comp;
503
// if (jf.getRootPane() != null) {
504
// JMenuBar menuBar = jf.getJMenuBar();
505
// if (menuBar != null) {
506
// for (int j = 0; j < menuBar.getComponentCount(); j++) {
507
// if (menuBar.getComponent(j) instanceof SearchPanel) {
508
// SearchPanel sPanel = (SearchPanel) menuBar
510
// menuBar.remove(sPanel);
512
// menuBar.repaint();
520
// if (comp instanceof JInternalFrame) {
521
// JInternalFrame jif = (JInternalFrame) comp;
522
// if (jif.getRootPane() != null) {
523
// JMenuBar menuBar = jif.getJMenuBar();
524
// if (menuBar != null) {
525
// for (int j = 0; j < menuBar.getComponentCount(); j++) {
526
// if (menuBar.getComponent(j) instanceof SearchPanel) {
527
// SearchPanel sPanel = (SearchPanel) menuBar
529
// menuBar.remove(sPanel);
531
// menuBar.repaint();
539
// if (comp instanceof Container) {
540
// Container cont = (Container) comp;
541
// for (int i = 0; i < cont.getComponentCount(); i++) {
542
// Component child = cont.getComponent(i);
543
// if (child instanceof JDesktopIcon)
544
// child = ((JDesktopIcon) child).getInternalFrame();
545
// hideSearchPanels(child, toRepaint);
551
// * Hides search panels on all menu bars (both JFrames and JInternalFrames).
553
// * @param toRepaint
554
// * Indication whether the relevant menu bars should be repainted.
556
// public static void hideSearchPanels(final boolean toRepaint) {
557
// SwingUtilities.invokeLater(new Runnable() {
558
// public void run() {
559
// Frame[] frames = Frame.getFrames();
560
// for (int i = 0; i < frames.length; i++) {
561
// hideSearchPanels(frames[i], toRepaint);
568
// * Shows search panels on all descendant internal frames of the specified
574
// protected static void showSearchPanels(Component comp) {
575
// if (comp instanceof JDesktopPane) {
576
// JDesktopPane desktop = (JDesktopPane) comp;
577
// JInternalFrame[] iFrames = desktop.getAllFrames();
578
// for (int i = 0; i < iFrames.length; i++) {
579
// JInternalFrame jif = iFrames[i];
580
// if (jif.getRootPane() != null) {
581
// JMenuBar menuBar = jif.getJMenuBar();
582
// if (menuBar != null)
583
// SwingUtilities.updateComponentTreeUI(menuBar);
588
// if (comp instanceof Container) {
589
// Container cont = (Container) comp;
590
// for (int i = 0; i < cont.getComponentCount(); i++) {
591
// MenuSearchWidget.showSearchPanels(cont.getComponent(i));
597
// * Shows search panels on all menu bars (both JFrames and JInternalFrames).
599
// public static void showSearchPanels() {
600
// SwingUtilities.invokeLater(new Runnable() {
601
// public void run() {
602
// Frame[] frames = Frame.getFrames();
603
// for (int i = 0; i < frames.length; i++) {
604
// Frame frame = frames[i];
606
// if (frame instanceof JFrame) {
607
// JFrame jf = (JFrame) frame;
608
// if (jf.getRootPane() != null) {
609
// JMenuBar menuBar = jf.getJMenuBar();
610
// if (menuBar != null)
611
// SwingUtilities.updateComponentTreeUI(menuBar);
614
// // fix for defect 134 - menubars on internal frames
615
// MenuSearchWidget.showSearchPanels(frame);
624
* @see org.pushingpixels.lafwidget.LafWidgetAdapter#installUI()
627
public void installUI() {
628
final LafWidgetSupport lafSupport = LafWidgetRepository.getRepository()
630
this.searchPanel = new SearchPanel(this.jcomp);
631
this.jcomp.add(searchPanel, this.jcomp.getComponentCount());
632
this.searchPanel.setVisible(lafSupport.toInstallMenuSearch(this.jcomp));
633
// NewMenuSearchWidget.panels.put(this.jcomp, searchPanel);
634
// toAddListener = true;
637
// if (toAddListener) {
638
// need to add a container listener that will move a newly added
639
// JMenu one entry before the last (so that our search panel
640
// will always be the last).
641
this.jcomp.addContainerListener(new ContainerAdapter() {
643
public void componentAdded(ContainerEvent e) {
644
if (!(e.getChild() instanceof JMenu))
648
Component removed = null;
649
for (int i = 0; i < MenuSearchWidget.this.jcomp
650
.getComponentCount(); i++) {
651
if (MenuSearchWidget.this.jcomp.getComponent(i) instanceof SearchPanel) {
652
removed = MenuSearchWidget.this.jcomp
657
if (removed != null) {
658
MenuSearchWidget.this.jcomp.remove(removed);
659
MenuSearchWidget.this.jcomp
660
.add(removed, MenuSearchWidget.this.jcomp
661
.getComponentCount());
662
// Show search panel only if the LAF-specific
663
// support requests this
664
if (lafSupport.toInstallMenuSearch(jcomp))
665
removed.setVisible(true);
667
removed.setVisible(false);
675
// SearchPanel sp = (SearchPanel)
676
// NewMenuSearchWidget.panels.get(this.jcomp);
678
searchPanel.applyComponentOrientation(this.jcomp
679
.getComponentOrientation());
686
* @see org.pushingpixels.lafwidget.LafWidgetAdapter#uninstallUI()
689
public void uninstallUI() {
690
this.jcomp.remove(this.searchPanel);
697
* @see org.pushingpixels.lafwidget.LafWidgetAdapter#installListeners()
700
public void installListeners() {
701
super.installListeners();
703
this.propertyListener = new PropertyChangeListener() {
705
public void propertyChange(final PropertyChangeEvent evt) {
706
if ("componentOrientation".equals(evt.getPropertyName())) {
707
// final SearchPanel sp = (SearchPanel)
708
// NewMenuSearchWidget.panels
709
// .get(NewMenuSearchWidget.this.jcomp);
710
SwingUtilities.invokeLater(new Runnable() {
713
if (searchPanel != null) {
715
.applyComponentOrientation((ComponentOrientation) evt
718
MenuSearchWidget.this.reset();
722
if ("locale".equals(evt.getPropertyName())) {
723
SwingUtilities.invokeLater(new Runnable() {
732
this.jcomp.addPropertyChangeListener(this.propertyListener);
738
* @see org.pushingpixels.lafwidget.LafWidgetAdapter#uninstallListeners()
741
public void uninstallListeners() {
742
this.jcomp.removePropertyChangeListener(this.propertyListener);
743
this.propertyListener = null;
747
public void reset() {
748
LafWidgetSupport support = LafWidgetRepository.getRepository()
750
// SearchPanel searchPanel = (SearchPanel) NewMenuSearchWidget.panels
752
if (searchPanel == null)
754
for (Map.Entry<Integer, JButton> entry : searchPanel.resultButtons
756
// Map.Entry entry = (Map.Entry) it.next();
757
int index = entry.getKey();
758
JButton button = entry.getValue();
760
Icon markerIcon = (support == null) ? LafWidgetUtilities
761
.getHexaMarker(index) : support.getNumberIcon(index);
762
button.setIcon(markerIcon);
764
int iconDim = support.getLookupIconSize();
765
Icon searchIcon = (support == null) ? LafWidgetUtilities.getSearchIcon(
766
iconDim, searchPanel.getComponentOrientation().isLeftToRight())
767
: support.getSearchIcon(iconDim, searchPanel
768
.getComponentOrientation());
769
searchPanel.searchButton.setIcon(searchIcon);
770
ResourceBundle bundle = LafWidgetUtilities
771
.getResourceBundle(this.jcomp);
772
searchPanel.searchButton.setToolTipText(bundle
773
.getString("Tooltip.menuSearchButton"));
774
searchPanel.searchStringField.setToolTipText(bundle
775
.getString("Tooltip.menuSearchField"));
779
* Layout for the search panel. Note that {@link FlowLayout} is almost
780
* perfect for us, but we need the following:
782
* <li>Minimum size to be 16*16 (for the search icon)
783
* <li>When there isn't enough place for result buttons, they should
784
* continue (even if they are unseen) and not flow to the next line.
787
* @author Kirill Grouchnikov
789
private class SearchResultsLayout implements LayoutManager {
791
* The associated search panel.
793
private SearchPanel searchPanel;
796
* Simple constructor.
799
* The associated search panel.
801
public SearchResultsLayout(SearchPanel searchPanel) {
802
this.searchPanel = searchPanel;
808
* @see java.awt.LayoutManager#addLayoutComponent(java.lang.String,
809
* java.awt.Component)
812
public void addLayoutComponent(String name, Component c) {
818
* @see java.awt.LayoutManager#removeLayoutComponent(java.awt.Component)
821
public void removeLayoutComponent(Component c) {
827
* @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container)
830
public Dimension preferredLayoutSize(Container c) {
831
if (this.searchPanel.searchButton.isSelected())
833
int buttonSize = LafWidgetRepository.getRepository()
834
.getLafSupport().getLookupButtonSize();
835
return new Dimension(buttonSize, buttonSize);
841
* @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
844
public Dimension minimumLayoutSize(Container c) {
845
// enough for the search icon
846
int buttonSize = LafWidgetRepository.getRepository()
847
.getLafSupport().getLookupButtonSize();
848
return new Dimension(buttonSize, buttonSize);
854
* @see java.awt.LayoutManager#layoutContainer(java.awt.Container)
857
public void layoutContainer(Container c) {
858
int height = c.getHeight();
859
int width = c.getWidth();
861
if (!this.searchPanel.searchButton.isVisible())
864
boolean leftToRight = jcomp.getComponentOrientation()
868
// start from the toggle button
870
int sbWidth = this.searchPanel.searchButton.getPreferredSize().width;
871
int sbHeight = this.searchPanel.searchButton.getPreferredSize().height;
872
this.searchPanel.searchButton.setBounds(x,
873
(height - sbHeight) / 2, sbWidth, sbHeight);
877
if (this.searchPanel.isVisible()) {
879
int tbWidth = this.searchPanel.searchStringField
880
.getPreferredSize().width;
881
int tbHeight = this.searchPanel.searchStringField
882
.getPreferredSize().height;
883
// make the text field fit in the available height
884
tbHeight = Math.min(tbHeight, height - 2);
885
this.searchPanel.searchStringField.setBounds(x,
886
(height - tbHeight) / 2, tbWidth, tbHeight);
891
int buttonCount = this.searchPanel.resultButtons.size();
892
for (int i = 1; i <= buttonCount; i++) {
893
JButton button = this.searchPanel.resultButtons.get(i);
894
int bw = button.getPreferredSize().width;
895
int bh = button.getPreferredSize().height;
897
button.setBounds(x, (height - bh) / 2, bw, bh);
902
// start from the toggle button
904
int sbWidth = this.searchPanel.searchButton.getPreferredSize().width;
905
int sbHeight = this.searchPanel.searchButton.getPreferredSize().height;
906
this.searchPanel.searchButton.setBounds(x - sbWidth,
907
(height - sbHeight) / 2, sbWidth, sbHeight);
911
if (this.searchPanel.isVisible()) {
913
int tbWidth = this.searchPanel.searchStringField
914
.getPreferredSize().width;
915
int tbHeight = this.searchPanel.searchStringField
916
.getPreferredSize().height;
917
// make the text field fit in the available height
918
tbHeight = Math.min(tbHeight, height - 2);
919
this.searchPanel.searchStringField.setBounds(x - tbWidth,
920
(height - tbHeight) / 2, tbWidth, tbHeight);
925
int buttonCount = this.searchPanel.resultButtons.size();
926
for (int i = 1; i <= buttonCount; i++) {
927
JButton button = this.searchPanel.resultButtons.get(i);
928
int bw = button.getPreferredSize().width;
929
int bh = button.getPreferredSize().height;
931
button.setBounds(x - bw, (height - bh) / 2, bw, bh);
942
* @see org.pushingpixels.lafwidget.LafWidget#requiresCustomLafSupport()
945
public boolean requiresCustomLafSupport() {