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    }