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 package sears.gui; 019 020 import java.awt.BorderLayout; 021 import java.awt.GridBagConstraints; 022 import java.awt.GridBagLayout; 023 import java.awt.event.ActionEvent; 024 import java.awt.event.ActionListener; 025 import java.awt.event.FocusEvent; 026 import java.awt.event.FocusListener; 027 028 import javax.swing.JLabel; 029 import javax.swing.JOptionPane; 030 import javax.swing.JPanel; 031 import javax.swing.JSlider; 032 import javax.swing.JTextField; 033 import javax.swing.event.ChangeEvent; 034 import javax.swing.event.ChangeListener; 035 036 import sears.tools.SearsResourceBundle; 037 import sears.tools.Trace; 038 039 /** 040 * Class DelayDialog. 041 * <br><b>Summary:</b><br> 042 * This class is a Dialog which permits to delay some subtitles. 043 */ 044 public class DelayDialog extends SearsJDialog { 045 046 private static final long serialVersionUID = -365612092452966123L; 047 048 private JPanel mainPanel = null; 049 050 private JPanel delayPanel = null; 051 052 private JLabel labelDelay = null; 053 054 private JTextField textDelay = null; 055 056 private JSlider jSliderDelay; 057 058 /** 059 * This is the default constructor 060 */ 061 public DelayDialog() { 062 super(SearsResourceBundle.getResource("delay_title")); 063 this.setContentPane(getMainPanel()); 064 configureSize(); 065 } 066 067 /** 068 * This method initializes jContentPane 069 * 070 * @return javax.swing.JPanel 071 */ 072 private JPanel getMainPanel() { 073 if (mainPanel == null) { 074 mainPanel = new JPanel(); 075 mainPanel.setLayout(new BorderLayout()); 076 mainPanel.setBorder(super.createEmptyBorder()); 077 mainPanel.add(getDelayPanel(), java.awt.BorderLayout.CENTER); 078 mainPanel.add(getJPanelButtons(), java.awt.BorderLayout.SOUTH); 079 } 080 return mainPanel; 081 } 082 083 /** 084 * This method initializes jPanel 085 * 086 * @return javax.swing.JPanel 087 */ 088 private JPanel getDelayPanel() { 089 if (delayPanel == null) { 090 labelDelay = new JLabel(); 091 labelDelay.setText(SearsResourceBundle.getResource("delay_label")); 092 delayPanel = new JPanel(); 093 delayPanel.setLayout(new GridBagLayout()); 094 GridBagConstraints gbc1 = new GridBagConstraints(); 095 gbc1.gridx = 0; 096 gbc1.gridy = 0; 097 gbc1.ipadx = 4; 098 delayPanel.add(labelDelay, gbc1); 099 GridBagConstraints gbc2 = new GridBagConstraints(); 100 gbc2.gridx = 1; 101 gbc2.gridy = 0; 102 gbc2.fill = GridBagConstraints.HORIZONTAL; 103 gbc2.weightx = 1; 104 delayPanel.add(getTextDelay(), gbc2); 105 GridBagConstraints gbc3 = new GridBagConstraints(); 106 gbc3.gridx = 0; 107 gbc3.gridy = 1; 108 gbc3.gridwidth = 2; 109 gbc3.fill = GridBagConstraints.HORIZONTAL; 110 gbc3.weightx = 1; 111 delayPanel.add(getJSliderDelay(), gbc3); 112 } 113 return delayPanel; 114 } 115 116 /** 117 * Method getJSpinnerDelay. 118 * <br><b>Summary:</b><br> 119 * This method creates the JSpinner to control the delay 120 * @return JSpinner. 121 */ 122 private JSlider getJSliderDelay() { 123 if(jSliderDelay == null){ 124 jSliderDelay = new JSlider(-100, 100); 125 jSliderDelay.setValue(10); 126 jSliderDelay.addChangeListener(new ChangeListener() { 127 public void stateChanged(ChangeEvent e) { 128 valueChanged(e.getSource()); 129 } 130 }); 131 } 132 return jSliderDelay; 133 } 134 135 /** 136 * Method valueChanged. 137 * <br><b>Summary:</b><br> 138 * This method is called when textField changed, or when JSpinner changed. 139 * @param source The one which change the first. 140 */ 141 protected void valueChanged(Object source) { 142 //If the slider triggered the change, update the textField (if necessary). 143 if (source.equals(jSliderDelay)) { 144 //by default we will not update the textField value. 145 boolean updateTextField = false; 146 //retrieve the slider delay value 147 double sliderDelayValue = ((double) jSliderDelay.getValue()) / 10; 148 updateTextField = true; 149 try { 150 // retrieve the TextField value. 151 double delay = getDoubleTextDelayValue(); 152 if (delay != sliderDelayValue) { 153 updateTextField = true; 154 } 155 } catch (NumberFormatException e) { 156 //TextField value is not valid : update ! 157 updateTextField = true; 158 } 159 //update textField if necessary 160 if (updateTextField) { 161 getTextDelay().setText("" + sliderDelayValue); 162 } 163 } else if (source.equals(textDelay)) { 164 //If the textDelay triggered the event, update the slider if necessary. 165 //Source is the TextDelay 166 try { 167 // retrieve the TextField value. 168 double delay = getDoubleTextDelayValue(); 169 double sliderDelayValue = ((double) jSliderDelay.getValue()) / 10; 170 if (delay != sliderDelayValue) { 171 // Udate slider. 172 //Beware if textField value is bigger than slider max 173 int newSliderValue = (int) (delay * 10); 174 if(Math.abs(newSliderValue) > jSliderDelay.getMaximum()){ 175 jSliderDelay.setMaximum(Math.abs(newSliderValue)); 176 jSliderDelay.setMinimum(-Math.abs(newSliderValue)); 177 } 178 jSliderDelay.setValue(newSliderValue); 179 } 180 } catch (NumberFormatException e) { 181 //TextField value is not valid : do not update slider! 182 } 183 } 184 } 185 186 187 /** 188 * Method getDoubleTextDelayValue. 189 * <br><b>Summary:</b><br> 190 * This method returns the double value of the delay in the textfield. 191 * @return double The double value of the delay in the textfield. 192 * @throws NumberFormatException 193 */ 194 public double getDoubleTextDelayValue() throws NumberFormatException{ 195 //the result of the method. 196 double result = 0; 197 String delayString = getTextDelay().getText(); 198 if (delayString != null && !delayString.equals("")) { 199 result = Double.parseDouble(delayString); 200 }else{ 201 result = 0; 202 } 203 //return the result; 204 return result; 205 } 206 /** 207 * Method okAction. 208 * <br><b>Summary:</b><br> 209 * This method is called when user validate the dialog. 210 */ 211 protected void okAction() { 212 //Just have to check parameters validity, if valids, dispose dialog,and set validation status to true. 213 String error = checkParameters(); 214 if (error != null && !error.equals("")) { 215 //Show error message. 216 JOptionPane.showMessageDialog(this, error, SearsResourceBundle.getResource("error_delayConfigurationError"), JOptionPane.ERROR_MESSAGE); 217 Trace.trace("Error in Delay parameters:" + error, Trace.WARNING_PRIORITY); 218 } else { 219 //else split configuration is valid, release dialog. 220 validationStatus = true; 221 dispose(); 222 } 223 } 224 225 /** 226 * Method checkParameters. 227 * <br><b>Summary:</b><br> 228 * This method checks the parameters. 229 * @return <b>String</b> "" if there is no error, or the error message. 230 */ 231 private String checkParameters() { 232 //Check file to open 233 String errorMessage = ""; 234 //check delay. 235 String delay = getTextDelay().getText(); 236 if (delay != null && !delay.equals("")) { 237 try { 238 Double.parseDouble(delay); 239 } catch (NumberFormatException e) { 240 //Delay value is not a number. 241 errorMessage += SearsResourceBundle.getResource("error_delayNotValid")+"\n"; 242 } 243 } else { 244 //Delay value is null. 245 errorMessage += SearsResourceBundle.getResource("error_delayNull")+"\n"; 246 } 247 return errorMessage; 248 } 249 250 /** 251 * This method initializes jTextField 252 * 253 * @return javax.swing.JTextField 254 */ 255 private JTextField getTextDelay() { 256 if (textDelay == null) { 257 textDelay = new JTextField(5); 258 textDelay.setToolTipText(SearsResourceBundle.getResource("delay_tip")); 259 textDelay.setText("1"); 260 //add an action listener to validate when user press 'enter' in textField. 261 textDelay.addActionListener(new ActionListener() { 262 public void actionPerformed(ActionEvent e) { 263 okAction(); 264 } 265 }); 266 //Add a focus listener, to update slider when textfield lost focus. 267 textDelay.addFocusListener(new FocusListener() { 268 public void focusLost(FocusEvent e) { 269 valueChanged(e.getSource()); 270 } 271 272 public void focusGained(FocusEvent e) { 273 //Nothing to do on focus gain 274 } 275 }); 276 } 277 return textDelay; 278 } 279 280 281 /** 282 * Method getDelay. 283 * <br><b>Summary:</b><br> 284 * Return the entered delay. 285 * @return <b>double</b> The entered delay. 286 */ 287 public double getDelay() { 288 return Double.parseDouble(getTextDelay().getText()); 289 } 290 291 /* (non-Javadoc) 292 * @see sears.gui.SearsJDialog#getDialogName() 293 */ 294 protected String getDialogName() { 295 return "delay"; 296 } 297 }