001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.dialogs; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Component; 007import java.awt.Dimension; 008import java.awt.event.ActionEvent; 009import java.awt.event.ActionListener; 010import java.awt.event.KeyEvent; 011 012import javax.swing.DefaultListCellRenderer; 013import javax.swing.JLabel; 014import javax.swing.JList; 015import javax.swing.JMenuItem; 016import javax.swing.ListCellRenderer; 017 018import org.openstreetmap.josm.Main; 019import org.openstreetmap.josm.actions.JosmAction; 020import org.openstreetmap.josm.gui.ExtendedDialog; 021import org.openstreetmap.josm.gui.MainMenu; 022import org.openstreetmap.josm.gui.widgets.SearchTextResultListPanel; 023import org.openstreetmap.josm.tools.Shortcut; 024 025public final class MenuItemSearchDialog extends ExtendedDialog { 026 027 private final Selector selector; 028 private static final MenuItemSearchDialog INSTANCE = new MenuItemSearchDialog(Main.main.menu); 029 030 private MenuItemSearchDialog(MainMenu menu) { 031 super(Main.parent, tr("Search menu items"), new String[]{tr("Select"), tr("Cancel")}); 032 this.selector = new Selector(menu); 033 this.selector.setDblClickListener(new ActionListener() { 034 @Override 035 public void actionPerformed(ActionEvent e) { 036 buttonAction(0, null); 037 } 038 }); 039 setContent(selector, false); 040 setPreferredSize(new Dimension(600, 300)); 041 } 042 043 /** 044 * Returns the unique instance of {@code MenuItemSearchDialog}. 045 * 046 * @return the unique instance of {@code MenuItemSearchDialog}. 047 */ 048 public static synchronized MenuItemSearchDialog getInstance() { 049 return INSTANCE; 050 } 051 052 @Override 053 public ExtendedDialog showDialog() { 054 selector.init(); 055 super.showDialog(); 056 selector.clearSelection(); 057 return this; 058 } 059 060 @Override 061 protected void buttonAction(int buttonIndex, ActionEvent evt) { 062 super.buttonAction(buttonIndex, evt); 063 if (buttonIndex == 0 && selector.getSelectedItem() != null && selector.getSelectedItem().isEnabled()) { 064 selector.getSelectedItem().getAction().actionPerformed(evt); 065 } 066 } 067 068 private static class Selector extends SearchTextResultListPanel<JMenuItem> { 069 070 private final MainMenu menu; 071 072 Selector(MainMenu menu) { 073 super(); 074 this.menu = menu; 075 lsResult.setCellRenderer(new CellRenderer()); 076 } 077 078 public JMenuItem getSelectedItem() { 079 final JMenuItem selected = lsResult.getSelectedValue(); 080 if (selected != null) { 081 return selected; 082 } else if (!lsResultModel.isEmpty()) { 083 return lsResultModel.getElementAt(0); 084 } else { 085 return null; 086 } 087 } 088 089 @Override 090 protected void filterItems() { 091 lsResultModel.setItems(menu.findMenuItems(edSearchText.getText(), true)); 092 } 093 } 094 095 private static class CellRenderer implements ListCellRenderer<JMenuItem> { 096 097 private final DefaultListCellRenderer def = new DefaultListCellRenderer(); 098 099 @Override 100 public Component getListCellRendererComponent(JList<? extends JMenuItem> list, JMenuItem value, int index, 101 boolean isSelected, boolean cellHasFocus) { 102 final JLabel label = (JLabel) def.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 103 label.setText(value.getText()); 104 label.setIcon(value.getIcon()); 105 label.setEnabled(value.isEnabled()); 106 final JMenuItem item = new JMenuItem(value.getText()); 107 item.setAction(value.getAction()); 108 if (isSelected) { 109 item.setBackground(list.getSelectionBackground()); 110 item.setForeground(list.getSelectionForeground()); 111 } else { 112 item.setBackground(list.getBackground()); 113 item.setForeground(list.getForeground()); 114 } 115 return item; 116 } 117 } 118 119 public static class Action extends JosmAction { 120 121 public Action() { 122 super(tr("Search menu items"), "dialogs/search", null, 123 Shortcut.registerShortcut("help:search-items", "Search menu items", KeyEvent.VK_SPACE, Shortcut.CTRL), 124 true, "dialogs/search-items", false); 125 } 126 127 @Override 128 public void actionPerformed(ActionEvent e) { 129 MenuItemSearchDialog.getInstance().showDialog(); 130 } 131 } 132}