001package jmri.util.swing; 002 003import java.awt.*; 004import java.awt.event.*; 005 006import javax.swing.*; 007 008/** 009 * Provides a standard "search bar" for addition to 010 * other panels. Actual search is via call-back. 011 * 012 * @author Bob Jacobsen 013 */ 014public class SearchBar extends javax.swing.JPanel { 015 016 Runnable forward; 017 Runnable backward; 018 Runnable done; 019 020 JTextField textField = new JTextField(); 021 JButton rightButton = new JButton(">"); 022 JButton leftButton = new JButton("<"); 023 JButton doneButton = new JButton(Bundle.getMessage("ButtonDone")); 024 025 public SearchBar(Runnable forward, Runnable backward, Runnable done) { 026 super(); 027 this.forward = forward; 028 this.backward = backward; 029 this.done = done; 030 031 // create GUI 032 setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 033 add(textField); 034 add(Box.createHorizontalGlue()); 035 add(leftButton); 036 add(rightButton); 037 add(doneButton); 038 039 leftButton.setToolTipText("Search backwards"); 040 rightButton.setToolTipText("Search forwards"); 041 doneButton.setToolTipText("Close search bar"); 042 043 // add actions 044 doneButton.addActionListener(new java.awt.event.ActionListener() { 045 @Override 046 public void actionPerformed(ActionEvent e) { 047 if (done != null) { 048 log.debug("firing done"); 049 done.run(); 050 } else { 051 log.warn("no search done defined, setting invisible"); 052 SearchBar.this.setVisible(false); 053 } 054 } 055 }); 056 057 leftButton.addActionListener(new java.awt.event.ActionListener() { 058 @Override 059 public void actionPerformed(ActionEvent e) { 060 if (backward != null) { 061 log.debug("firing backward"); 062 backward.run(); 063 } else { 064 log.warn("no backward search defined"); 065 } 066 } 067 }); 068 069 rightButton.addActionListener(new java.awt.event.ActionListener() { 070 @Override 071 public void actionPerformed(ActionEvent e) { 072 if (forward != null) { 073 log.debug("firing forward"); 074 forward.run(); 075 } else { 076 log.warn("no forward search defined"); 077 } 078 } 079 }); 080 081 // Enter in the text field does a forward search 082 // and then leaves forward search selected for the next one 083 textField.addActionListener(new java.awt.event.ActionListener() { 084 @Override 085 public void actionPerformed(ActionEvent e) { 086 if (forward != null) { 087 log.debug("firing forward"); 088 forward.run(); 089 } else { 090 log.warn("no forward search defined"); 091 } 092 rightButton.requestFocusInWindow(); 093 } 094 }); 095 096 } 097 098 public String getSearchString() { 099 return textField.getText(); 100 } 101 102 /** 103 * A service routine to connect the SearchBar to 104 * the usual modifier keys 105 * @param frame JFrame containing this search bar; used to set key maps 106 */ 107 @SuppressWarnings("deprecation") // getMenuShortcutKeyMask() 108 public void configureKeyModifiers(JFrame frame) { 109 JRootPane rootPane = frame.getRootPane(); 110 111 rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( 112 KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()), "openSearch"); 113 114 rootPane.getActionMap().put("openSearch", new AbstractAction() { 115 @Override 116 public void actionPerformed(ActionEvent e) { 117 118 // don't retain last text? 119 textField.setText(""); 120 121 // alternate visible 122 SearchBar.this.setVisible(! SearchBar.this.isVisible()); 123 124 // if visible, move focus 125 if (SearchBar.this.isVisible()) { 126 SearchBar.this.textField.requestFocusInWindow(); 127 } 128 } 129 }); 130 131 rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( 132 KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()|java.awt.event.InputEvent.SHIFT_DOWN_MASK), "forwardSearch"); 133 134 rootPane.getActionMap().put("forwardSearch", new AbstractAction() { 135 @Override 136 public void actionPerformed(ActionEvent e) { 137 138 // same as button 139 leftButton.doClick(); 140 } 141 }); 142 143 rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( 144 KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()), "backwardSearch"); 145 146 rootPane.getActionMap().put("backwardSearch", new AbstractAction() { 147 @Override 148 public void actionPerformed(ActionEvent e) { 149 150 // same as button 151 rightButton.doClick(); 152 } 153 }); 154 } 155 156 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SearchBar.class); 157}