All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pushingpixels.lafwidget.menu.MenuSearchWidget Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2005-2010 Laf-Widget Kirill Grouchnikov. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  o Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  o Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  o Neither the name of Laf-Widget Kirill Grouchnikov nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.pushingpixels.lafwidget.menu;

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.*;

import javax.swing.*;

import org.pushingpixels.lafwidget.*;

/**
 * Adds menu search panel to menu bars.
 * 
 * @author Kirill Grouchnikov
 */
public class MenuSearchWidget extends LafWidgetAdapter implements
		Resettable {
	/**
	 * Boolean flag to prevent infinite loop. Maybe need to use something more
	 * elegant.
	 */
	private boolean inEvent = false;

	/**
	 * Listens on changes to the component orientation.
	 */
	protected PropertyChangeListener propertyListener;

	/**
	 * The associated search panel.
	 */
	private SearchPanel searchPanel;

	/**
	 * Panel for searching the menus.
	 * 
	 * @author Kirill Grouchnikov
	 */
	private class SearchPanel extends JPanel {
		/**
		 * Toggle button for showing / hiding search controls.
		 */
		private JToggleButton searchButton;

		/**
		 * Text field for entering search string.
		 */
		private JTextField searchStringField;

		// /**
		// * The associated menu bar.
		// */
		// private JMenuBar menuBar;
		//
		/**
		 * The result buttons. Key is {@link Integer}, value is {@link JButton}.
		 */
		private Map resultButtons;

		/**
		 * Simple constructor.
		 * 
		 * @param menuBar
		 *            The associated menu bar.
		 */
		public SearchPanel(final JMenuBar menuBar) {
			// this.menuBar = menuBar;
			this.setLayout(new SearchResultsLayout(this));

			// Search button (toggle) with tooltip.
			LafWidgetSupport support = LafWidgetRepository.getRepository()
					.getLafSupport();
			int iconDim = support.getLookupIconSize();
			int buttonDim = support.getLookupButtonSize();
			Icon searchIcon = (support == null) ? LafWidgetUtilities
					.getSearchIcon(iconDim, jcomp.getComponentOrientation()
							.isLeftToRight()) : support.getSearchIcon(iconDim,
					jcomp.getComponentOrientation());
			this.searchButton = new JToggleButton(searchIcon);
			this.searchButton.setPreferredSize(new Dimension(buttonDim,
					buttonDim));
			ResourceBundle bundle = LafWidgetUtilities
					.getResourceBundle(menuBar);
			this.searchButton.setToolTipText(bundle
					.getString("Tooltip.menuSearchButton"));
			this.searchButton.setFocusable(false);
			if (support != null)
				support.markButtonAsFlat(this.searchButton);
			this.add(this.searchButton);

			// Add action listener on the toggle button. Based on the
			// state of the toggle button, the search field and result buttons
			// will be set visible or invisible.
			this.searchButton.addActionListener(new ActionListener() {
				@Override
                public void actionPerformed(ActionEvent e) {
					SwingUtilities.invokeLater(new Runnable() {
						@Override
                        public void run() {
							boolean toShow = SearchPanel.this.searchButton
									.isSelected();
							SearchPanel.this.searchStringField
									.setVisible(toShow);
							SearchPanel.this.searchStringField.requestFocus();
							for (JButton resultButton : SearchPanel.this.resultButtons
									.values()) {
								resultButton.setVisible(toShow);
							}
							SearchPanel.this.repaint();
							SearchPanel.this.revalidate();
						}
					});
				}
			});
			// add mouse listener to remove the search panel on mouse
			// click when CTRL button is pressed.
			this.searchButton.addMouseListener(new MouseAdapter() {
				@Override
				public void mousePressed(MouseEvent e) {
					if ((e.getModifiers() & InputEvent.CTRL_MASK) != 0) {
						SwingUtilities.invokeLater(new Runnable() {
							@Override
                            public void run() {
								SearchPanel.this.removeAll();
								SearchPanel.this.repaint();
								jcomp.revalidate();
							}
						});
					}
				}
			});

			// Search field.
			this.searchStringField = new JTextField();
			this.searchStringField.setColumns(10);
			this.add(this.searchStringField);
			this.searchStringField.setVisible(false);
			this.searchStringField.setToolTipText(bundle
					.getString("Tooltip.menuSearchField"));

			// Map to hold the result buttons (need for the icon reset
			// on theme change and layout manager).
			this.resultButtons = new HashMap();
			this.searchStringField.addActionListener(new ActionListener() {
				@Override
                public void actionPerformed(ActionEvent e) {
					String searchString = SearchPanel.this.searchStringField
							.getText().toLowerCase();
					// See if there is at least one non-white space character.
					// This is fix for bug 54
					if (searchString.trim().length() == 0) {
						return;
					}

					// remove all old buttons
					for (JButton toRemove : SearchPanel.this.resultButtons
							.values()) {
						SearchPanel.this.remove(toRemove);
					}
					SearchPanel.this.resultButtons.clear();
					// find all matching menu items / menus
					LinkedList searchResults = SearchPanel.this
							.findOccurences(searchString);
					int count = 0;
					for (SearchResult searchResult : searchResults) {
						// show only first 16 results.
						if (count == 16)
							break;
						// create new button with binary icon
						LafWidgetSupport support = LafWidgetRepository
								.getRepository().getLafSupport();
						Icon markerIcon = support.getNumberIcon(count + 1);
						JButton resultButton = new JButton(markerIcon);
						// set action listener (to show the menu).
						resultButton
								.addActionListener(new SearchResultListener(
										searchResult));
						// check if the path to the menu (item) has
						// only enabled items.
						resultButton.setEnabled(searchResult.isEnabled());
						SearchPanel.this.add(resultButton);
						SearchPanel.this.resultButtons.put(count + 1, resultButton);
						resultButton.setToolTipText(""
								+ searchResult.toString()
								+ "
" + LafWidgetUtilities.getResourceBundle(menuBar) .getString("Tooltip.menuSearchTooltip") + ""); if (support != null) support.markButtonAsFlat(resultButton); count++; } SearchPanel.this.repaint(); jcomp.revalidate(); } }); } /** * Returns all occurences of the specified string in the menus and menu * items of the associated menu bar. * * @param searchPattern * Pattern to search (no wildcards yet). * @return All occurences of the specified string in the menus and menu * items of the associated menu bar. */ private LinkedList findOccurences(String searchPattern) { LinkedList result = new LinkedList(); LinkedList currentPath = new LinkedList(); for (int i = 0; i < jcomp.getComponentCount(); i++) { Component component = jcomp.getComponent(i); if (component instanceof JMenu) { JMenu menu = (JMenu) component; this.checkMenu(currentPath, menu, searchPattern, result); } } return result; } /** * Recursively scans the specified menu (item) and updates the list that * contains all occurences of the specified string in the contained * menus and menu items. * * @param currentPath * The path to the current menu (item). Contains * {@link JMenu}s. * @param menuItem * The menu (item) itself that is being tested. * @param searchPattern * Pattern to search (no wildcards yet). * @param matchingResults * All occurences of the specified string up until now. After * this function returns, will also contain * all occurences of the specified string in the contained * menu (item)s. Contains {@link SearchResult}s. */ private void checkMenu(LinkedList currentPath, JMenuItem menuItem, String searchPattern, LinkedList matchingResults) { String menuItemText = menuItem.getText(); if (menuItemText.toLowerCase().indexOf(searchPattern) >= 0) { matchingResults.addLast(new SearchResult(jcomp, currentPath, menuItem)); } if (menuItem instanceof JMenu) { JMenu menu = (JMenu) menuItem; currentPath.addLast(menu); for (int i = 0; i < menu.getMenuComponentCount(); i++) { Component menuComponent = menu.getMenuComponent(i); if (menuComponent instanceof JMenuItem) { JMenuItem childItem = (JMenuItem) menuComponent; this.checkMenu(currentPath, childItem, searchPattern, matchingResults); } } currentPath.removeLast(); } } /* * (non-Javadoc) * * @see java.awt.Component#setVisible(boolean) */ @Override public void setVisible(boolean aFlag) { super.setVisible(aFlag); if (aFlag) this.searchStringField.requestFocus(); } } /** * Listener on the search result button. The action itself - * show the associated menu path to the menu item that contains the string * that has been specified during the search. * * @author Kirill Grouchnikov */ private static class SearchResultListener implements ActionListener { /** * The associated search result. */ private SearchResult searchResult; /** * Simple constructor. * * @param searchResult * The associated search result. */ public SearchResultListener(SearchResult searchResult) { super(); this.searchResult = searchResult; } /* * (non-Javadoc) * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ @Override public void actionPerformed(ActionEvent e) { // start opening the menus MenuElement[] menuElements = this.searchResult.menuElements; MenuSelectionManager.defaultManager().setSelectedPath(menuElements); } } /** * Single result of menu search. * * @author Kirill Grouchnikov */ private static class SearchResult { /** * Path to the menu (item). The first element is always {@link JMenuBar}, * and after each {@link JMenu} there is it's * {@link JMenu#getPopupMenu()}. */ private MenuElement[] menuElements; /** * Simple constructor. * * @param menuBar * The main menu bar. * @param menuPath * The menus leading to the matching entry. Contains * {@link JMenu}s. * @param menuLeaf * The menu (item) that matches the search pattern string. */ public SearchResult(JMenuBar menuBar, LinkedList menuPath, JMenuItem menuLeaf) { int count = 1; if (menuPath != null) count += 2 * menuPath.size(); if (menuLeaf != null) count++; this.menuElements = new MenuElement[count]; count = 0; // the first element is the menu bar itself this.menuElements[count++] = menuBar; if (menuPath != null) { for (JMenu menu : menuPath) { // JMenu menu = (JMenu) it.next(); this.menuElements[count++] = menu; // important - don't forget the popup menu of the menu this.menuElements[count++] = menu.getPopupMenu(); } } if (menuLeaf != null) this.menuElements[count] = menuLeaf; } /** * Returns the path to the menu (item). * * @return Path to the menu (item). The first element is always * {@link JMenuBar}, and after each {@link JMenu} there is it's * {@link JMenu#getPopupMenu()}. */ public MenuElement[] getMenuElements() { return this.menuElements; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { StringBuffer sb = new StringBuffer(); if (this.menuElements != null) { String sep = ""; for (int i = 0; i < this.menuElements.length; i++) { MenuElement menuElem = this.menuElements[i]; if (menuElem instanceof JMenuItem) { sb.append(sep); sep = " -> "; sb.append(((JMenuItem) menuElem).getText()); } } } return sb.toString(); } /** * Checks that all entries leading to the associated menu (item) are * enabled. * * @return true if all entries leading to the associated * menu (item) are enabled, false otherwise. */ public boolean isEnabled() { // all parts must be enabled for (int i = 0; i < this.menuElements.length; i++) { MenuElement menuElem = this.menuElements[i]; if (menuElem instanceof JMenuItem) { JMenuItem menuItem = (JMenuItem) menuElem; if (!menuItem.isEnabled()) return false; } } return true; } } /** * Returns the number of menu items under the specified menu item. * * @param menuItem * The root menu item. * @return The number of menu items under the specified menu item. */ private static int getMenuItemCount(JMenuItem menuItem) { int result = 1; if (menuItem instanceof JMenu) { JMenu menu = (JMenu) menuItem; for (int i = 0; i < menu.getMenuComponentCount(); i++) { Component child = menu.getMenuComponent(i); if (child instanceof JMenuItem) result += MenuSearchWidget .getMenuItemCount((JMenuItem) child); } } return result; } /** * Returns the number of menu items under the specified menu bar. * * @param menuBar * The root menu bar. * @return The number of menu items under the specified menu bar. */ public static int getMenuItemCount(JMenuBar menuBar) { int result = 0; for (int i = 0; i < menuBar.getMenuCount(); i++) { JMenu menu = menuBar.getMenu(i); if (menu != null) { result += MenuSearchWidget.getMenuItemCount(menu); } } return result; } // /** // * Hides search panels recursively on the specified component. // * // * @param comp // * Component. // * @param toRepaint // * Indication whether the relevant menu bars should be repainted. // */ // private static void hideSearchPanels(Component comp, final boolean toRepaint) // { // if (comp instanceof JFrame) { // JFrame jf = (JFrame) comp; // if (jf.getRootPane() != null) { // JMenuBar menuBar = jf.getJMenuBar(); // if (menuBar != null) { // for (int j = 0; j < menuBar.getComponentCount(); j++) { // if (menuBar.getComponent(j) instanceof SearchPanel) { // SearchPanel sPanel = (SearchPanel) menuBar // .getComponent(j); // menuBar.remove(sPanel); // if (toRepaint) // menuBar.repaint(); // break; // } // } // } // } // } // // if (comp instanceof JInternalFrame) { // JInternalFrame jif = (JInternalFrame) comp; // if (jif.getRootPane() != null) { // JMenuBar menuBar = jif.getJMenuBar(); // if (menuBar != null) { // for (int j = 0; j < menuBar.getComponentCount(); j++) { // if (menuBar.getComponent(j) instanceof SearchPanel) { // SearchPanel sPanel = (SearchPanel) menuBar // .getComponent(j); // menuBar.remove(sPanel); // if (toRepaint) // menuBar.repaint(); // break; // } // } // } // } // } // // if (comp instanceof Container) { // Container cont = (Container) comp; // for (int i = 0; i < cont.getComponentCount(); i++) { // Component child = cont.getComponent(i); // if (child instanceof JDesktopIcon) // child = ((JDesktopIcon) child).getInternalFrame(); // hideSearchPanels(child, toRepaint); // } // } // } // // /** // * Hides search panels on all menu bars (both JFrames and JInternalFrames). // * // * @param toRepaint // * Indication whether the relevant menu bars should be repainted. // */ // public static void hideSearchPanels(final boolean toRepaint) { // SwingUtilities.invokeLater(new Runnable() { // public void run() { // Frame[] frames = Frame.getFrames(); // for (int i = 0; i < frames.length; i++) { // hideSearchPanels(frames[i], toRepaint); // } // }; // }); // } // /** // * Shows search panels on all descendant internal frames of the specified // * component. // * // * @param comp // * A component. // */ // protected static void showSearchPanels(Component comp) { // if (comp instanceof JDesktopPane) { // JDesktopPane desktop = (JDesktopPane) comp; // JInternalFrame[] iFrames = desktop.getAllFrames(); // for (int i = 0; i < iFrames.length; i++) { // JInternalFrame jif = iFrames[i]; // if (jif.getRootPane() != null) { // JMenuBar menuBar = jif.getJMenuBar(); // if (menuBar != null) // SwingUtilities.updateComponentTreeUI(menuBar); // } // } // return; // } // if (comp instanceof Container) { // Container cont = (Container) comp; // for (int i = 0; i < cont.getComponentCount(); i++) { // MenuSearchWidget.showSearchPanels(cont.getComponent(i)); // } // } // } // // /** // * Shows search panels on all menu bars (both JFrames and JInternalFrames). // */ // public static void showSearchPanels() { // SwingUtilities.invokeLater(new Runnable() { // public void run() { // Frame[] frames = Frame.getFrames(); // for (int i = 0; i < frames.length; i++) { // Frame frame = frames[i]; // // if (frame instanceof JFrame) { // JFrame jf = (JFrame) frame; // if (jf.getRootPane() != null) { // JMenuBar menuBar = jf.getJMenuBar(); // if (menuBar != null) // SwingUtilities.updateComponentTreeUI(menuBar); // } // } // // fix for defect 134 - menubars on internal frames // MenuSearchWidget.showSearchPanels(frame); // } // }; // }); // } /* * (non-Javadoc) * * @see org.pushingpixels.lafwidget.LafWidgetAdapter#installUI() */ @Override public void installUI() { final LafWidgetSupport lafSupport = LafWidgetRepository.getRepository() .getLafSupport(); this.searchPanel = new SearchPanel(this.jcomp); this.jcomp.add(searchPanel, this.jcomp.getComponentCount()); this.searchPanel.setVisible(lafSupport.toInstallMenuSearch(this.jcomp)); // NewMenuSearchWidget.panels.put(this.jcomp, searchPanel); // toAddListener = true; // } // if (toAddListener) { // need to add a container listener that will move a newly added // JMenu one entry before the last (so that our search panel // will always be the last). this.jcomp.addContainerListener(new ContainerAdapter() { @Override public void componentAdded(ContainerEvent e) { if (!(e.getChild() instanceof JMenu)) return; if (!inEvent) { inEvent = true; Component removed = null; for (int i = 0; i < MenuSearchWidget.this.jcomp .getComponentCount(); i++) { if (MenuSearchWidget.this.jcomp.getComponent(i) instanceof SearchPanel) { removed = MenuSearchWidget.this.jcomp .getComponent(i); break; } } if (removed != null) { MenuSearchWidget.this.jcomp.remove(removed); MenuSearchWidget.this.jcomp .add(removed, MenuSearchWidget.this.jcomp .getComponentCount()); // Show search panel only if the LAF-specific // support requests this if (lafSupport.toInstallMenuSearch(jcomp)) removed.setVisible(true); else removed.setVisible(false); } inEvent = false; } } }); // } // SearchPanel sp = (SearchPanel) // NewMenuSearchWidget.panels.get(this.jcomp); // if (sp != null) { searchPanel.applyComponentOrientation(this.jcomp .getComponentOrientation()); // } } /* * (non-Javadoc) * * @see org.pushingpixels.lafwidget.LafWidgetAdapter#uninstallUI() */ @Override public void uninstallUI() { this.jcomp.remove(this.searchPanel); super.uninstallUI(); } /* * (non-Javadoc) * * @see org.pushingpixels.lafwidget.LafWidgetAdapter#installListeners() */ @Override public void installListeners() { super.installListeners(); this.propertyListener = new PropertyChangeListener() { @Override public void propertyChange(final PropertyChangeEvent evt) { if ("componentOrientation".equals(evt.getPropertyName())) { // final SearchPanel sp = (SearchPanel) // NewMenuSearchWidget.panels // .get(NewMenuSearchWidget.this.jcomp); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (searchPanel != null) { searchPanel .applyComponentOrientation((ComponentOrientation) evt .getNewValue()); } MenuSearchWidget.this.reset(); } }); } if ("locale".equals(evt.getPropertyName())) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { reset(); } }); } } }; this.jcomp.addPropertyChangeListener(this.propertyListener); } /* * (non-Javadoc) * * @see org.pushingpixels.lafwidget.LafWidgetAdapter#uninstallListeners() */ @Override public void uninstallListeners() { this.jcomp.removePropertyChangeListener(this.propertyListener); this.propertyListener = null; } @Override public void reset() { LafWidgetSupport support = LafWidgetRepository.getRepository() .getLafSupport(); // SearchPanel searchPanel = (SearchPanel) NewMenuSearchWidget.panels // .get(this.jcomp); if (searchPanel == null) return; for (Map.Entry entry : searchPanel.resultButtons .entrySet()) { // Map.Entry entry = (Map.Entry) it.next(); int index = entry.getKey(); JButton button = entry.getValue(); Icon markerIcon = (support == null) ? LafWidgetUtilities .getHexaMarker(index) : support.getNumberIcon(index); button.setIcon(markerIcon); } int iconDim = support.getLookupIconSize(); Icon searchIcon = (support == null) ? LafWidgetUtilities.getSearchIcon( iconDim, searchPanel.getComponentOrientation().isLeftToRight()) : support.getSearchIcon(iconDim, searchPanel .getComponentOrientation()); searchPanel.searchButton.setIcon(searchIcon); ResourceBundle bundle = LafWidgetUtilities .getResourceBundle(this.jcomp); searchPanel.searchButton.setToolTipText(bundle .getString("Tooltip.menuSearchButton")); searchPanel.searchStringField.setToolTipText(bundle .getString("Tooltip.menuSearchField")); } /** * Layout for the search panel. Note that {@link FlowLayout} is almost * perfect for us, but we need the following: *
    *
  • Minimum size to be 16*16 (for the search icon) *
  • When there isn't enough place for result buttons, they should * continue (even if they are unseen) and not flow to the next line. *
* * @author Kirill Grouchnikov */ private class SearchResultsLayout implements LayoutManager { /** * The associated search panel. */ private SearchPanel searchPanel; /** * Simple constructor. * * @param searchPanel * The associated search panel. */ public SearchResultsLayout(SearchPanel searchPanel) { this.searchPanel = searchPanel; } /* * (non-Javadoc) * * @see java.awt.LayoutManager#addLayoutComponent(java.lang.String, * java.awt.Component) */ @Override public void addLayoutComponent(String name, Component c) { } /* * (non-Javadoc) * * @see java.awt.LayoutManager#removeLayoutComponent(java.awt.Component) */ @Override public void removeLayoutComponent(Component c) { } /* * (non-Javadoc) * * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container) */ @Override public Dimension preferredLayoutSize(Container c) { if (this.searchPanel.searchButton.isSelected()) return c.getSize(); int buttonSize = LafWidgetRepository.getRepository() .getLafSupport().getLookupButtonSize(); return new Dimension(buttonSize, buttonSize); } /* * (non-Javadoc) * * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container) */ @Override public Dimension minimumLayoutSize(Container c) { // enough for the search icon int buttonSize = LafWidgetRepository.getRepository() .getLafSupport().getLookupButtonSize(); return new Dimension(buttonSize, buttonSize); } /* * (non-Javadoc) * * @see java.awt.LayoutManager#layoutContainer(java.awt.Container) */ @Override public void layoutContainer(Container c) { int height = c.getHeight(); int width = c.getWidth(); if (!this.searchPanel.searchButton.isVisible()) return; boolean leftToRight = jcomp.getComponentOrientation() .isLeftToRight(); if (leftToRight) { // start from the toggle button int x = 2; int sbWidth = this.searchPanel.searchButton.getPreferredSize().width; int sbHeight = this.searchPanel.searchButton.getPreferredSize().height; this.searchPanel.searchButton.setBounds(x, (height - sbHeight) / 2, sbWidth, sbHeight); x += (sbWidth + 4); if (this.searchPanel.isVisible()) { // now - text field int tbWidth = this.searchPanel.searchStringField .getPreferredSize().width; int tbHeight = this.searchPanel.searchStringField .getPreferredSize().height; // make the text field fit in the available height tbHeight = Math.min(tbHeight, height - 2); this.searchPanel.searchStringField.setBounds(x, (height - tbHeight) / 2, tbWidth, tbHeight); x += (tbWidth + 2); // result buttons int buttonCount = this.searchPanel.resultButtons.size(); for (int i = 1; i <= buttonCount; i++) { JButton button = this.searchPanel.resultButtons.get(i); int bw = button.getPreferredSize().width; int bh = button.getPreferredSize().height; button.setBounds(x, (height - bh) / 2, bw, bh); x += (bw + 1); } } } else { // start from the toggle button int x = width - 2; int sbWidth = this.searchPanel.searchButton.getPreferredSize().width; int sbHeight = this.searchPanel.searchButton.getPreferredSize().height; this.searchPanel.searchButton.setBounds(x - sbWidth, (height - sbHeight) / 2, sbWidth, sbHeight); x -= (sbWidth + 4); if (this.searchPanel.isVisible()) { // now - text field int tbWidth = this.searchPanel.searchStringField .getPreferredSize().width; int tbHeight = this.searchPanel.searchStringField .getPreferredSize().height; // make the text field fit in the available height tbHeight = Math.min(tbHeight, height - 2); this.searchPanel.searchStringField.setBounds(x - tbWidth, (height - tbHeight) / 2, tbWidth, tbHeight); x -= (tbWidth + 2); // result buttons int buttonCount = this.searchPanel.resultButtons.size(); for (int i = 1; i <= buttonCount; i++) { JButton button = this.searchPanel.resultButtons.get(i); int bw = button.getPreferredSize().width; int bh = button.getPreferredSize().height; button.setBounds(x - bw, (height - bh) / 2, bw, bh); x -= (bw + 1); } } } } } /* * (non-Javadoc) * * @see org.pushingpixels.lafwidget.LafWidget#requiresCustomLafSupport() */ @Override public boolean requiresCustomLafSupport() { return false; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy