001 package nl.cwi.sen1.gui.plugin.editor; 002 003 import java.awt.BorderLayout; 004 import java.awt.Frame; 005 import java.awt.GridBagConstraints; 006 import java.awt.GridBagLayout; 007 import java.awt.Insets; 008 import java.awt.event.ActionEvent; 009 import java.awt.event.ActionListener; 010 import java.awt.event.KeyEvent; 011 import java.awt.event.WindowAdapter; 012 import java.awt.event.WindowEvent; 013 import java.util.ArrayList; 014 import java.util.List; 015 016 import javax.swing.AbstractAction; 017 import javax.swing.ActionMap; 018 import javax.swing.ButtonGroup; 019 import javax.swing.InputMap; 020 import javax.swing.JButton; 021 import javax.swing.JCheckBox; 022 import javax.swing.JComboBox; 023 import javax.swing.JComponent; 024 import javax.swing.JLabel; 025 import javax.swing.JPanel; 026 import javax.swing.JRadioButton; 027 import javax.swing.KeyStroke; 028 029 public class SearchReplaceDialog extends BaseDialog { 030 private EditorPane editor; 031 032 private JRadioButton backwardRadioButton; 033 034 private JCheckBox caseSensitiveCheck; 035 036 private JButton closeButton; 037 038 private ButtonGroup directionButtonGroup; 039 040 private JPanel directionPanel; 041 042 private JButton findButton; 043 044 private JComboBox findCombo; 045 046 private JLabel findLabel; 047 048 private JRadioButton forwardRadioButton; 049 050 private JPanel jPanel1; 051 052 private JPanel mainPanel; 053 054 private JPanel optionsPanel; 055 056 private JButton replaceAllButton; 057 058 private JButton replaceButton; 059 060 private JButton replaceFindButton; 061 062 private JLabel replaceLabel; 063 064 private JComboBox replaceWithCombo; 065 066 private JCheckBox wrapSearchCheck; 067 068 public String getFindText() { 069 String findText = findCombo.getEditor().getItem().toString(); 070 return findText; 071 } 072 073 public void setFindText(String findText) { 074 updateComboBox(findCombo, findText); 075 } 076 077 public boolean getFindDirection() { 078 return forwardRadioButton.isSelected(); 079 } 080 081 public boolean isCaseSensitiveSearch() { 082 return caseSensitiveCheck.isSelected(); 083 } 084 085 public boolean isWrappedSearch() { 086 return wrapSearchCheck.isSelected(); 087 } 088 089 public void setVisible(boolean b) { 090 if (b) { 091 String newSearch = editor.getSelectedText(); 092 if (newSearch != null && newSearch.length() != 0) { 093 findCombo.insertItemAt(newSearch, 0); 094 findCombo.setSelectedIndex(0); 095 } 096 findCombo.getEditor().selectAll(); 097 findCombo.requestFocus(); 098 } 099 super.setVisible(b); 100 } 101 102 public SearchReplaceDialog(EditorPane editor, Frame frame) { 103 super(frame); 104 setTitle("Find/Replace"); 105 this.editor = editor; 106 initComponents(); 107 forwardRadioButton.setSelected(true); 108 wrapSearchCheck.setSelected(true); 109 110 initBindings(); 111 } 112 113 private void initBindings() { 114 InputMap inputMap = this.getRootPane().getInputMap( 115 JComponent.WHEN_IN_FOCUSED_WINDOW); 116 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape"); 117 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter"); 118 119 ActionMap actionMap = this.getRootPane().getActionMap(); 120 actionMap.put("escape", new AbstractAction() { 121 public void actionPerformed(ActionEvent evt) { 122 closeButtonActionPerformed(); 123 } 124 }); 125 actionMap.put("enter", new AbstractAction() { 126 public void actionPerformed(ActionEvent evt) { 127 System.err.println("Enter action performed"); 128 findButtonActionPerformed(); 129 } 130 }); 131 132 findCombo.getEditor().getEditorComponent().addKeyListener( 133 new java.awt.event.KeyAdapter() { 134 public void keyPressed(java.awt.event.KeyEvent e) { 135 if (e.getKeyCode() == KeyEvent.VK_ENTER) { 136 findButtonActionPerformed(); 137 e.consume(); 138 } 139 } 140 }); 141 142 replaceWithCombo.getEditor().getEditorComponent().addKeyListener( 143 new java.awt.event.KeyAdapter() { 144 public void keyPressed(java.awt.event.KeyEvent e) { 145 if (e.getKeyCode() == KeyEvent.VK_ENTER) { 146 findButtonActionPerformed(); 147 e.consume(); 148 } 149 } 150 }); 151 } 152 153 private void initComponents() { 154 GridBagConstraints gridBagConstraints; 155 156 directionButtonGroup = new ButtonGroup(); 157 jPanel1 = new JPanel(); 158 findButton = new JButton(); 159 replaceFindButton = new JButton(); 160 replaceButton = new JButton(); 161 replaceAllButton = new JButton(); 162 closeButton = new JButton(); 163 mainPanel = new JPanel(); 164 findLabel = new JLabel(); 165 replaceLabel = new JLabel(); 166 findCombo = new JComboBox(); 167 replaceWithCombo = new JComboBox(); 168 directionPanel = new JPanel(); 169 forwardRadioButton = new JRadioButton(); 170 backwardRadioButton = new JRadioButton(); 171 optionsPanel = new JPanel(); 172 caseSensitiveCheck = new JCheckBox(); 173 wrapSearchCheck = new JCheckBox(); 174 175 addWindowListener(new WindowAdapter() { 176 public void windowClosing(WindowEvent evt) { 177 closeDialog(); 178 } 179 }); 180 181 jPanel1.setLayout(new GridBagLayout()); 182 183 findButton.setMnemonic('n'); 184 findButton.setText("Find"); 185 findButton.addActionListener(new ActionListener() { 186 public void actionPerformed(ActionEvent evt) { 187 findButtonActionPerformed(); 188 } 189 }); 190 191 gridBagConstraints = new GridBagConstraints(); 192 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; 193 gridBagConstraints.anchor = GridBagConstraints.EAST; 194 gridBagConstraints.weightx = 0.5; 195 gridBagConstraints.insets = new Insets(2, 2, 2, 2); 196 jPanel1.add(findButton, gridBagConstraints); 197 198 replaceFindButton.setMnemonic('d'); 199 replaceFindButton.setText("Replace/Find"); 200 replaceFindButton.addActionListener(new ActionListener() { 201 public void actionPerformed(ActionEvent evt) { 202 replaceFindButtonActionPerformed(); 203 } 204 }); 205 206 gridBagConstraints = new GridBagConstraints(); 207 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; 208 gridBagConstraints.anchor = GridBagConstraints.WEST; 209 gridBagConstraints.weightx = 0.5; 210 gridBagConstraints.insets = new Insets(2, 2, 2, 2); 211 jPanel1.add(replaceFindButton, gridBagConstraints); 212 213 replaceButton.setMnemonic('R'); 214 replaceButton.setText("Replace"); 215 replaceButton.addActionListener(new ActionListener() { 216 public void actionPerformed(ActionEvent evt) { 217 replaceButtonActionPerformed(); 218 } 219 }); 220 221 gridBagConstraints = new GridBagConstraints(); 222 gridBagConstraints.gridx = 0; 223 gridBagConstraints.gridy = 1; 224 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; 225 gridBagConstraints.anchor = GridBagConstraints.EAST; 226 gridBagConstraints.weightx = 0.5; 227 gridBagConstraints.insets = new Insets(2, 2, 2, 2); 228 jPanel1.add(replaceButton, gridBagConstraints); 229 230 replaceAllButton.setMnemonic('A'); 231 replaceAllButton.setText("Replace All"); 232 replaceAllButton.addActionListener(new ActionListener() { 233 public void actionPerformed(ActionEvent evt) { 234 replaceAllButtonActionPerformed(); 235 } 236 }); 237 238 gridBagConstraints = new GridBagConstraints(); 239 gridBagConstraints.gridx = 1; 240 gridBagConstraints.gridy = 1; 241 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; 242 gridBagConstraints.anchor = GridBagConstraints.WEST; 243 gridBagConstraints.weightx = 0.5; 244 gridBagConstraints.insets = new Insets(2, 2, 2, 2); 245 jPanel1.add(replaceAllButton, gridBagConstraints); 246 247 closeButton.setText("Close"); 248 closeButton.addActionListener(new ActionListener() { 249 public void actionPerformed(ActionEvent evt) { 250 closeButtonActionPerformed(); 251 } 252 }); 253 254 gridBagConstraints = new GridBagConstraints(); 255 gridBagConstraints.gridx = 1; 256 gridBagConstraints.gridy = 2; 257 gridBagConstraints.anchor = GridBagConstraints.NORTHEAST; 258 gridBagConstraints.insets = new Insets(2, 2, 2, 2); 259 jPanel1.add(closeButton, gridBagConstraints); 260 261 getContentPane().add(jPanel1, BorderLayout.SOUTH); 262 263 mainPanel.setLayout(new GridBagLayout()); 264 265 findLabel.setText("Find:"); 266 gridBagConstraints = new GridBagConstraints(); 267 gridBagConstraints.anchor = GridBagConstraints.EAST; 268 gridBagConstraints.insets = new Insets(2, 0, 2, 2); 269 mainPanel.add(findLabel, gridBagConstraints); 270 271 replaceLabel.setText("Replace with:"); 272 gridBagConstraints = new GridBagConstraints(); 273 gridBagConstraints.gridx = 0; 274 gridBagConstraints.gridy = 1; 275 gridBagConstraints.anchor = GridBagConstraints.EAST; 276 gridBagConstraints.insets = new Insets(2, 0, 2, 2); 277 mainPanel.add(replaceLabel, gridBagConstraints); 278 279 findCombo.setEditable(true); 280 gridBagConstraints = new GridBagConstraints(); 281 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; 282 gridBagConstraints.anchor = GridBagConstraints.WEST; 283 gridBagConstraints.weightx = 1.0; 284 gridBagConstraints.insets = new Insets(2, 2, 2, 2); 285 mainPanel.add(findCombo, gridBagConstraints); 286 287 replaceWithCombo.setEditable(true); 288 gridBagConstraints = new GridBagConstraints(); 289 gridBagConstraints.gridx = 1; 290 gridBagConstraints.gridy = 1; 291 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; 292 gridBagConstraints.anchor = GridBagConstraints.WEST; 293 gridBagConstraints.weightx = 1.0; 294 gridBagConstraints.insets = new Insets(2, 2, 2, 2); 295 mainPanel.add(replaceWithCombo, gridBagConstraints); 296 297 directionPanel.setLayout(new GridBagLayout()); 298 299 directionPanel.setBorder(new javax.swing.border.TitledBorder( 300 "Direction")); 301 forwardRadioButton.setText("Forward"); 302 directionButtonGroup.add(forwardRadioButton); 303 gridBagConstraints = new GridBagConstraints(); 304 gridBagConstraints.anchor = GridBagConstraints.WEST; 305 gridBagConstraints.weightx = 0.5; 306 directionPanel.add(forwardRadioButton, gridBagConstraints); 307 308 backwardRadioButton.setText("Backward"); 309 directionButtonGroup.add(backwardRadioButton); 310 gridBagConstraints = new GridBagConstraints(); 311 gridBagConstraints.anchor = GridBagConstraints.EAST; 312 gridBagConstraints.weightx = 0.5; 313 directionPanel.add(backwardRadioButton, gridBagConstraints); 314 315 gridBagConstraints = new GridBagConstraints(); 316 gridBagConstraints.gridx = 0; 317 gridBagConstraints.gridy = 2; 318 gridBagConstraints.gridwidth = 2; 319 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; 320 gridBagConstraints.insets = new Insets(2, 2, 2, 2); 321 mainPanel.add(directionPanel, gridBagConstraints); 322 323 optionsPanel.setLayout(new GridBagLayout()); 324 325 optionsPanel.setBorder(new javax.swing.border.TitledBorder("Options")); 326 caseSensitiveCheck.setText("Case Sensitive"); 327 gridBagConstraints = new GridBagConstraints(); 328 gridBagConstraints.anchor = GridBagConstraints.WEST; 329 gridBagConstraints.weightx = 0.5; 330 optionsPanel.add(caseSensitiveCheck, gridBagConstraints); 331 332 wrapSearchCheck.setText("Wrap Search"); 333 gridBagConstraints = new GridBagConstraints(); 334 gridBagConstraints.anchor = GridBagConstraints.EAST; 335 gridBagConstraints.weightx = 0.5; 336 optionsPanel.add(wrapSearchCheck, gridBagConstraints); 337 338 gridBagConstraints = new GridBagConstraints(); 339 gridBagConstraints.gridx = 0; 340 gridBagConstraints.gridy = 3; 341 gridBagConstraints.gridwidth = 2; 342 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; 343 gridBagConstraints.insets = new Insets(2, 2, 2, 2); 344 mainPanel.add(optionsPanel, gridBagConstraints); 345 346 getContentPane().add(mainPanel, BorderLayout.CENTER); 347 348 pack(); 349 } 350 351 private void closeButtonActionPerformed() { 352 this.setVisible(false); 353 } 354 355 private void replaceAllButtonActionPerformed() { 356 String textToFind = getFindText(); 357 updateComboBox(findCombo, textToFind); 358 String textToReplaceWith = (String) replaceWithCombo.getSelectedItem(); 359 updateComboBox(replaceWithCombo, textToReplaceWith); 360 editor.replaceAll(textToFind, textToReplaceWith, 361 !isCaseSensitiveSearch()); 362 } 363 364 private void replaceButtonActionPerformed() { 365 String textToFind = getFindText(); 366 String selectedText = editor.getSelectedText(); 367 368 if ((isCaseSensitiveSearch() && textToFind.equals(selectedText)) 369 || (!isCaseSensitiveSearch() && textToFind 370 .equalsIgnoreCase(selectedText))) { 371 String textToReplaceWith = (String) replaceWithCombo 372 .getSelectedItem(); 373 374 if (textToReplaceWith != null) { 375 updateComboBox(replaceWithCombo, textToReplaceWith); 376 int selectionStart = editor.getSelectionStart(); 377 editor.replaceSelection(textToReplaceWith); 378 editor.setSelectionStart(selectionStart); 379 editor.setSelectionEnd(selectionStart 380 + textToReplaceWith.length()); 381 } 382 } 383 } 384 385 private void findButtonActionPerformed() { 386 String textToFind = getFindText(); 387 updateComboBox(findCombo, textToFind); 388 editor.find(textToFind, !isCaseSensitiveSearch(), isWrappedSearch(), 389 getFindDirection()); 390 } 391 392 private void replaceFindButtonActionPerformed() { 393 replaceButtonActionPerformed(); 394 findButtonActionPerformed(); 395 } 396 397 private void updateComboBox(JComboBox combo, String latestEntry) { 398 int numItems = combo.getItemCount(); 399 List<String> items = new ArrayList<String>(); 400 for (int i = 0; i < numItems; i++) { 401 String current = (String) combo.getItemAt(i); 402 if ((current != null) && !current.equals(latestEntry)) { 403 items.add(current); 404 } 405 } 406 numItems = items.size(); 407 combo.removeAllItems(); 408 combo.addItem(latestEntry); 409 for (int i = 0; i < numItems; i++) { 410 combo.addItem(items.get(i)); 411 } 412 } 413 }