001 ///////////////////////////////////////////////// 002 //This file is part of Sears project. 003 //Subtitle Editor And Re-Synch 004 //A tool to easily modify and resynch movies subtitles. 005 ///////////////////////////////////////////////// 006 //This program is free software; 007 //you can redistribute it and/or modify it under the terms 008 //of the GNU General Public License 009 //as published by the Free Software Foundation; 010 //either version 2 of the License, or (at your option) any later version. 011 ///////////////////////////////////////////////// 012 //Sears project is available under sourceforge 013 //at adress: http://sourceforge.net/projects/sears/ 014 //Copyright (C) 2005 Booba Skaya 015 //Mail: booba.skaya@gmail.com 016 ///////////////////////////////////////////////// 017 018 // some suggestions about this class: floriaen@gmail.com 019 020 package sears.gui; 021 022 import java.awt.BorderLayout; 023 import java.awt.Dimension; 024 import java.awt.Font; 025 import java.awt.GridBagConstraints; 026 import java.awt.GridBagLayout; 027 import java.awt.Insets; 028 import java.awt.event.KeyAdapter; 029 import java.awt.event.KeyEvent; 030 import java.awt.event.WindowEvent; 031 032 import javax.swing.JButton; 033 import javax.swing.JLabel; 034 import javax.swing.JPanel; 035 import javax.swing.JTextField; 036 import javax.swing.event.CaretEvent; 037 import javax.swing.event.CaretListener; 038 039 import sears.gui.search.FindDialog; 040 import sears.tools.SearsResourceBundle; 041 042 /** 043 * This class represents a dialog to allow to search a word in the opened subtitle. 044 */ 045 public class JDialogFind extends SearsJDialog implements FindDialog { 046 047 private static final long serialVersionUID = -3289742897531861980L; 048 049 // used for a good display of the ghostLabel 050 private static String ghost_text = ""; 051 052 // we store the user's search word: 053 private static String stringToFind = null; 054 // PANELS 055 private JPanel panel = null; 056 private JPanel jPanelButtons = null; 057 058 private JLabel label = null; 059 private JTextField textField = null; 060 private JLabel ghostLabel = null; 061 062 // BUTTONS 063 private JButton jButtonNext = null; 064 private JButton jButtonPrevious = null; 065 066 private MainWindow mainWindow; 067 068 /** 069 * Constructs a new object 070 * @param frame the frame which calls the dialog 071 * @throws NullPointerException if <tt>frame</tt> is <tt>null</tt> 072 */ 073 public JDialogFind(MainWindow frame) { 074 super(SearsResourceBundle.getResource("find_title")); 075 if( frame == null ) { 076 throw new NullPointerException("MainWindow instance cannot be null"); 077 } 078 mainWindow = frame; 079 configureDialog(); 080 } 081 082 /** 083 * Configure the size dialog and add all the panels 084 */ 085 private void configureDialog() { 086 // we fix the dialog window size: 087 this.setResizable(false); 088 this.setSize(new Dimension(300,120)); 089 // and add components: 090 this.setLayout(new BorderLayout()); 091 this.add(getFindPanel(), BorderLayout.PAGE_START); 092 this.add(getJPanelButtons(), BorderLayout.LINE_END); 093 } 094 095 /** 096 * initialize the ghost_text (final like) 097 * @return the initialize ghost text 098 */ 099 private String getGhostText() { 100 if( ghost_text == "" ) { 101 String text = SearsResourceBundle.getResource("find_not_found"); 102 for(int i=0;i<text.length();i++) { 103 ghost_text += " "; 104 } 105 } 106 return ghost_text; 107 } 108 109 private void enabled(boolean aFlag) { 110 jButtonNext.setEnabled(aFlag); 111 jButtonPrevious.setEnabled(aFlag); 112 if( !aFlag ) { 113 ghostLabel.setText(getGhostText()); 114 } 115 } 116 117 /** 118 * this method constructs the principal panel 119 * @return the panel 120 */ 121 private JPanel getFindPanel() { 122 if( panel == null ) { 123 panel = new JPanel(); 124 panel.setLayout(new GridBagLayout()); 125 126 label = new JLabel(SearsResourceBundle.getResource("find_title") + ":"); 127 // the text field: 128 textField = new JTextField(stringToFind); 129 // if exists selected all the text: 130 if(stringToFind != null && stringToFind.length() > 0) { 131 textField.setSelectionStart(0); 132 textField.setSelectionEnd(stringToFind.length()); 133 } 134 textField.setPreferredSize(new Dimension(170,20)); 135 textField.addKeyListener(new KeyAdapter() { 136 public void keyPressed(KeyEvent ke) { 137 onKeyPressed(ke); 138 } 139 }); 140 textField.addCaretListener(new CaretListener() { 141 public void caretUpdate(CaretEvent e) { 142 enabled( (textField.getText().trim().length() > 0) ); 143 } 144 }); 145 146 // the ghost label: 147 ghostLabel = new JLabel(getGhostText()); 148 ghostLabel.setFont(new Font(null, 149 textField.getFont().getStyle(), 150 textField.getFont().getSize() - 2)); 151 152 // we place components: 153 GridBagConstraints c = new GridBagConstraints(); 154 c.anchor = GridBagConstraints.LINE_START; 155 156 c.weighty = 0.5; 157 c.insets = new Insets(10,3,2,3); 158 159 c.gridx = 0; 160 c.gridy = 0; 161 panel.add(label, c); 162 163 c.gridx = 1; 164 c.gridy = 0; 165 panel.add(textField, c); 166 167 c.gridx = 0; 168 c.gridy = 1; 169 c.insets = new Insets(2,3,10,3); 170 c.gridwidth = 2; 171 panel.add(ghostLabel, c); 172 } 173 return panel; 174 } 175 176 /** 177 * When user pressed <b>ENTER</b> key a next find action is perform 178 * if <b>SHIFT</b> key is also pressed then it's a previous find action that is perform. 179 */ 180 private void onKeyPressed(KeyEvent ke) { 181 // if user pressed the Enter key: 182 if( ke.getKeyCode() == KeyEvent.VK_ENTER ){ 183 if( !ke.isShiftDown() ) { 184 getJButtonNext().doClick(); 185 } else { 186 getJButtonPrevious().doClick(); 187 } 188 } 189 } 190 191 /* 192 * (non-Javadoc) 193 * @see sears.gui.SearsJDialog#getDialogName() 194 */ 195 protected String getDialogName() { 196 return "Find"; 197 } 198 199 /* 200 * (non-Javadoc) 201 * @see sears.gui.SearsJDialog#getJPanelButtons() 202 */ 203 protected JPanel getJPanelButtons(){ 204 if (jPanelButtons == null) { 205 jPanelButtons = new JPanel(); 206 //jPanelButtons.setBorder(BorderFactory.createEmptyBorder(2, 2, 20, 2)); 207 jPanelButtons.add(getJButtonPrevious(), null); 208 jPanelButtons.add(getJButtonNext(), null); 209 } 210 return jPanelButtons; 211 } 212 213 /** 214 * Construct the next button 215 * @return the next button 216 */ 217 private JButton getJButtonNext() { 218 if (jButtonNext == null) { 219 jButtonNext = new JButton(SearsResourceBundle.getResource("find_next")); 220 if( textField.getText().trim().length() == 0 ) { 221 jButtonNext.setEnabled(false); 222 } 223 jButtonNext.addActionListener(new java.awt.event.ActionListener() { 224 public void actionPerformed(java.awt.event.ActionEvent e) { 225 Thread next = new Thread(new Runnable() { 226 public void run() { 227 findStringInSubtitle(false); 228 } 229 }); 230 next.start(); 231 } 232 }); 233 } 234 return jButtonNext; 235 } 236 237 /** 238 * Construct the previous button 239 * @return the previous button 240 */ 241 private JButton getJButtonPrevious() { 242 if (jButtonPrevious == null) { 243 jButtonPrevious = new JButton(SearsResourceBundle.getResource("find_previous")); 244 if( textField.getText().length() == 0 ) { 245 jButtonPrevious.setEnabled(false); 246 } 247 jButtonPrevious.addActionListener(new java.awt.event.ActionListener() { 248 public void actionPerformed(java.awt.event.ActionEvent e) { 249 Thread previous = new Thread(new Runnable() { 250 public void run() { 251 findStringInSubtitle(true); 252 } 253 }); 254 previous.start(); 255 } 256 }); 257 } 258 return jButtonPrevious; 259 } 260 261 /** 262 * performs a find action in the subtitle. 263 * @param previous if true call a previous find action, if false it's a next one 264 */ 265 private void findStringInSubtitle(boolean previous) { 266 // perform a find also if user did not enter anything 267 mainWindow.find(this, previous); 268 269 } 270 271 /** 272 * Gets the text entered by user 273 * @return the text entered by user, if the text is null, null is returned 274 */ 275 public String getText() { 276 return textField.getText(); 277 } 278 279 /** 280 * Sets the count of occurrences of the searched text in subtitle file 281 * <br>This method is not thread-safe. 282 * @param occurencesCount the count of occurrences 283 */ 284 public void setOccurencesCount(int occurencesCount) { 285 if(occurencesCount <= 0) { 286 ghostLabel.setText(SearsResourceBundle.getResource("find_not_found")); 287 } else { 288 String text = ""; 289 if( occurencesCount == 1 ) { 290 text = SearsResourceBundle.getResource("find_match_found"); 291 } else { 292 text = SearsResourceBundle.getResource("find_matches_found"); 293 } 294 ghostLabel.setText(String.valueOf(occurencesCount + " " + text)); 295 } 296 } 297 298 /* 299 * (non-Javadoc) 300 * @see sears.gui.SearsJDialog#windowClosed(java.awt.event.WindowEvent) 301 */ 302 public void windowClosed(WindowEvent e) { 303 super.windowClosed(e); 304 // use method as a ready-made: 305 //mainWindow.find(null, false); 306 // we save the text entered by user: 307 stringToFind = textField.getText(); 308 mainWindow.fireFindStop(); 309 } 310 311 public void windowOpened(WindowEvent e) { 312 super.windowOpened(e); 313 // fire MainWindow 314 } 315 316 public void setFindEnabled(Boolean inFlag) { 317 // TODO Auto-generated method stub 318 319 } 320 }