[zhyi~subversion:30] Separated the logic for processing SRT to a single class.
- From: zhyi@kenai.com
- To: commits@zhyi.kenai.com
- Subject: [zhyi~subversion:30] Separated the logic for processing SRT to a single class.
- Date: Sun, 18 Oct 2009 05:18:22 +0000
Project: zhyi
Repository: subversion
Revision: 30
Author: zhyi
Date: 2009-10-18 05:18:16 UTC
Link:
Log Message:
------------
Separated the logic for processing SRT to a single class.
Revisions:
----------
30
Modified Paths:
---------------
SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/Bundle_zh_CN.properties
SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SettingsDialog.form
SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtEditorFrame.form
SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/Bundle.properties
SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtEditorFrame.java
SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SettingsDialog.java
Added Paths:
------------
SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtToolkit.java
Diffs:
------
Index: SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SettingsDialog.java
===================================================================
--- SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SettingsDialog.java
(revision 29)
+++ SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SettingsDialog.java
(revision 30)
@@ -98,6 +98,8 @@
fontLabel.setText(bundle.getString("Font")); // NOI18N
+ fontComboBox.setToolTipText(bundle.getString("FontToolTip")); //
NOI18N
+
GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
@@ -117,7 +119,7 @@
.addComponent(fontLabel)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(fontComboBox, 0, 180, Short.MAX_VALUE))
- .addComponent(jSeparator1, GroupLayout.DEFAULT_SIZE,
235, Short.MAX_VALUE)
+ .addComponent(jSeparator1, GroupLayout.DEFAULT_SIZE,
238, Short.MAX_VALUE)
.addGroup(Alignment.TRAILING,
layout.createSequentialGroup()
.addComponent(okButton)
.addPreferredGap(ComponentPlacement.RELATED)
Index: SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SettingsDialog.form
===================================================================
--- SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SettingsDialog.form
(revision 29)
+++ SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SettingsDialog.form
(revision 30)
@@ -43,7 +43,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="fontComboBox" pref="180" max="32767"
attributes="0"/>
</Group>
- <Component id="jSeparator1" alignment="0" pref="235"
max="32767" attributes="0"/>
+ <Component id="jSeparator1" alignment="0" pref="238"
max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="okButton" linkSize="2" min="-2"
max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
@@ -150,6 +150,11 @@
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="fontComboBox">
+ <Properties>
+ <Property name="toolTipText" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="com/zhyi/srtsubtitleeditor/Bundle.properties" key="FontToolTip"
replaceFormat="bundle.getString("{key}")"/>
+ </Property>
+ </Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom"
type="java.lang.String" value="fontComboBox = new JComboBox(

GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(locale));"/>
</AuxValues>
Index: SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/Bundle.properties
===================================================================
--- SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/Bundle.properties
(revision 29)
+++ SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/Bundle.properties
(revision 30)
@@ -45,7 +45,7 @@
SrtFile=SRT Subtitle File
Ready=Ready
Cancel=Cancel
-BadTime=Bad format at line {0} in the SRT file:\nThe format of the start or
end time may not match "hh:MM:ss,mmm".
+BadTime=Bad format at line {0} in the SRT file:\nThe format of the start or
end time doesn't match "hh:MM:ss,mmm".
FileTooLarge=Seems the chosen file isn't SRT for the size is too large
(>1MB).\nDo you still want to load it?
Warning=Warning
Error=Error
@@ -58,8 +58,13 @@
Charset=Charset:
Language=Language:
CharsetToolTip=<html><b>Select the charset for loading and saving SRT
files</b><br>A wrong charset might result in messy code.</html>
-LanguangeToolTip=<html><b>Select the UI languange</b><br>You have to restart
the application to take effect.</html>
+LanguangeToolTip=<html><b>Select the UI language</b><br>You have to restart
the application to take effect.</html>
OK=OK
#\u9ED8\u8BA4\u8BED\u8A00\uFF08\u82F1\u8BED\uFF09
DefaultLanguage=Default Language (English)
Font=Font:
+FontToolTip=<html><b>Select the UI font</b><br>You have to restart the
application to take effect.</html>
+ContinuousEdit=Continuous Edit
+ContinuousEditToolTip=If selected, once a subtitle is updated, the next
subtitle will automatically be loaded to editor.
+Loading=Loading...
+Saving=Saving...
Index:
SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/Bundle_zh_CN.properties
===================================================================
--- SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/Bundle_zh_CN.properties
(revision 29)
+++ SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/Bundle_zh_CN.properties
(revision 30)
@@ -45,7 +45,7 @@
SrtFile=SRT \u5B57\u5E55\u6587\u4EF6
Ready=\u5C31\u7EEA
Cancel=\u53D6\u6D88
-BadTime=SRT \u6587\u4EF6\u4E2D\u7684\u7B2C {0}
\u884C\u683C\u5F0F\u9519\u8BEF\uFF1A\n\u5F00\u59CB\u6216\u7ED3\u675F\u65F6\u95F4\u7684\u683C\u5F0F\u53EF\u80FD\u4E0D\u7B26\u5408\u201Chh:MM:ss,mm\u201D\u3002
+BadTime=SRT \u6587\u4EF6\u4E2D\u7684\u7B2C {0}
\u884C\u683C\u5F0F\u9519\u8BEF\uFF1A\n\u5F00\u59CB\u6216\u7ED3\u675F\u65F6\u95F4\u7684\u683C\u5F0F\u4E0D\u7B26\u5408\u201Chh:MM:ss,mm\u201D\u3002
FileTooLarge=\u6240\u9009\u7684\u6587\u4EF6\u4F3C\u4E4E\u4E0D\u662F
SRT\uFF0C\u56E0\u4E3A\u5B83\u592A\u5927\u4E86\uFF08>1MB\uFF09\u3002\n\u4F60\u4ECD\u7136\u60F3\u8F7D\u5165\u5B83\u5417\uFF1F
Warning=\u8B66\u544A
Error=\u9519\u8BEF
@@ -63,3 +63,8 @@
#\u9ED8\u8BA4\u8BED\u8A00\uFF08\u82F1\u8BED\uFF09
DefaultLanguage=\u9ED8\u8BA4\u8BED\u8A00\uFF08\u82F1\u6587\uFF09
Font=\u5B57\u4F53\uFF1A
+FontToolTip=<html><b>\u9009\u62E9\u754C\u9762\u5B57\u4F53</b><br>\u5FC5\u987B\u91CD\u542F\u5E94\u7528\u7A0B\u5E8F\u624D\u80FD\u751F\u6548\u3002</html>
+ContinuousEdit=\u8FDE\u7EED\u7F16\u8F91
+ContinuousEditToolTip=\u5982\u679C\u9009\u4E2D\uFF0C\u5219\u5728\u66F4\u65B0\u4E00\u6761\u5B57\u5E55\u540E\uFF0C\u81EA\u52A8\u5C06\u4E0B\u4E00\u6761\u5B57\u5E55\u8F7D\u5165\u5230\u7F16\u8F91\u533A\u3002
+Loading=\u6B63\u5728\u8F7D\u5165\u2026\u2026
+Saving=\u6B63\u5728\u4FDD\u5B58\u2026\u2026
Index: SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtEditorFrame.java
===================================================================
--- SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtEditorFrame.java
(revision 29)
+++ SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtEditorFrame.java
(revision 30)
@@ -18,7 +18,7 @@
*/
package com.zhyi.srtsubtitleeditor;
-import com.zhyi.zylib.SwingToolkit;
+import com.zhyi.zylib.toolkit.SwingToolkit;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
@@ -26,17 +26,15 @@
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.util.ResourceBundle;
-import java.util.regex.Pattern;
+import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
+import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
@@ -58,6 +56,7 @@
import javax.swing.WindowConstants;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
/**
@@ -67,25 +66,20 @@
public class SrtEditorFrame extends JFrame implements ActionListener,
WindowListener {
private final int maxLength = 1024 * 1024;
- private final Pattern timePattern = Pattern.compile(
- "^\\d{2}(:[0-5]\\d){2},\\d{3}$");
private final TableModel emptyModel = new DefaultTableModel();
private SettingsDialog settingsDialog;
+ private ResourceBundle bundle = Context.getBundle();
// Used to trace the bad format of an SRT file.
private int lineNumber;
private int subtitleIndex;
private DefaultTableModel tableModel;
- private ResourceBundle bundle;
- private String[] columnNames;
public SrtEditorFrame() {
settingsDialog = new SettingsDialog(this, true);
- initEnvironment();
initComponents();
- fixComboBoxUIForWindows();
- enableComponents(false);
+ enableEditingComponents(false);
}
/**
@@ -112,6 +106,7 @@
contentScrollPane = new JScrollPane();
contentTextArea = new JTextArea();
updateSubtitleButton = new JButton();
+ continuousEditCheckBox = new JCheckBox();
addBeforeButton = new JButton();
addAfterButton = new JButton();
moveUpButton = new JButton();
@@ -171,6 +166,9 @@
updateSubtitleButton.setText(bundle.getString("UpdateSubtitle")); //
NOI18N
+ continuousEditCheckBox.setSelected(true);
+ continuousEditCheckBox.setText(bundle.getString("ContinuousEdit"));
// NOI18N
+
GroupLayout editSubtitlePanelLayout = new
GroupLayout(editSubtitlePanel);
editSubtitlePanel.setLayout(editSubtitlePanelLayout);
editSubtitlePanelLayout.setHorizontalGroup(
@@ -181,16 +179,19 @@
.addGroup(editSubtitlePanelLayout.createSequentialGroup()
.addComponent(beginTimeLabel)
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(beginTimeTextField,
GroupLayout.DEFAULT_SIZE, 142, Short.MAX_VALUE)
+ .addComponent(beginTimeTextField,
GroupLayout.DEFAULT_SIZE, 144, Short.MAX_VALUE)
.addGap(18, 18, 18)
.addComponent(endTimeLabel)
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(endTimeTextField,
GroupLayout.DEFAULT_SIZE, 143, Short.MAX_VALUE))
+ .addComponent(endTimeTextField,
GroupLayout.DEFAULT_SIZE, 145, Short.MAX_VALUE))
.addGroup(editSubtitlePanelLayout.createSequentialGroup()
.addComponent(contentLabel)
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(contentScrollPane,
GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE))
- .addComponent(updateSubtitleButton, Alignment.TRAILING))
+ .addComponent(contentScrollPane,
GroupLayout.DEFAULT_SIZE, 377, Short.MAX_VALUE))
+ .addGroup(Alignment.TRAILING,
editSubtitlePanelLayout.createSequentialGroup()
+ .addComponent(continuousEditCheckBox)
+ .addPreferredGap(ComponentPlacement.RELATED, 113,
Short.MAX_VALUE)
+ .addComponent(updateSubtitleButton)))
.addContainerGap())
);
editSubtitlePanelLayout.setVerticalGroup(
@@ -205,9 +206,11 @@
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(editSubtitlePanelLayout.createParallelGroup(Alignment.LEADING)
.addComponent(contentLabel)
- .addComponent(contentScrollPane,
GroupLayout.DEFAULT_SIZE, 72, Short.MAX_VALUE))
+ .addComponent(contentScrollPane,
GroupLayout.DEFAULT_SIZE, 75, Short.MAX_VALUE))
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(updateSubtitleButton)
+
.addGroup(editSubtitlePanelLayout.createParallelGroup(Alignment.BASELINE)
+ .addComponent(updateSubtitleButton)
+ .addComponent(continuousEditCheckBox))
.addContainerGap())
);
@@ -253,7 +256,7 @@
.addGroup(ajustTimePanelLayout.createSequentialGroup()
.addComponent(amountLabel)
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(amountTextField,
GroupLayout.DEFAULT_SIZE, 52, Short.MAX_VALUE)
+ .addComponent(amountTextField,
GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(msLabel))
.addGroup(ajustTimePanelLayout.createSequentialGroup()
@@ -321,25 +324,25 @@
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
- .addComponent(srtScrollPane, GroupLayout.DEFAULT_SIZE,
620, Short.MAX_VALUE)
+ .addComponent(srtScrollPane, GroupLayout.DEFAULT_SIZE,
644, Short.MAX_VALUE)
.addGroup(Alignment.TRAILING,
layout.createSequentialGroup()
.addComponent(loadButton)
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(pathTextField,
GroupLayout.DEFAULT_SIZE, 363, Short.MAX_VALUE)
+ .addComponent(pathTextField,
GroupLayout.DEFAULT_SIZE, 365, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(saveButton)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(saveAsButton))
.addGroup(layout.createSequentialGroup()
- .addComponent(addBeforeButton,
GroupLayout.DEFAULT_SIZE, 122, Short.MAX_VALUE)
+ .addComponent(addBeforeButton,
GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(addAfterButton,
GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE)
+ .addComponent(addAfterButton,
GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(moveUpButton,
GroupLayout.DEFAULT_SIZE, 119, Short.MAX_VALUE)
+ .addComponent(moveUpButton,
GroupLayout.DEFAULT_SIZE, 123, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(moveDownButton,
GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE)
+ .addComponent(moveDownButton,
GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
- .addComponent(deleteButton,
GroupLayout.DEFAULT_SIZE, 115, Short.MAX_VALUE))
+ .addComponent(deleteButton,
GroupLayout.DEFAULT_SIZE, 123, Short.MAX_VALUE))
.addGroup(Alignment.TRAILING,
layout.createSequentialGroup()
.addComponent(editSubtitlePanel,
GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
@@ -352,7 +355,7 @@
.addComponent(progressBar,
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(toolBar, GroupLayout.PREFERRED_SIZE,
GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
- .addComponent(separator1, GroupLayout.DEFAULT_SIZE, 620,
Short.MAX_VALUE))
+ .addComponent(separator1, GroupLayout.DEFAULT_SIZE, 644,
Short.MAX_VALUE))
.addContainerGap())
);
@@ -435,25 +438,6 @@
public void windowOpened(java.awt.event.WindowEvent evt) {
}// </editor-fold>//GEN-END:initComponents
- private void initEnvironment() {
- bundle = Context.getBundle();
- columnNames = new String[] {
- bundle.getString("IndexTableHeader"),
- bundle.getString("BeginTimeTableHeader"),
- bundle.getString("EndTimeTableHeader"),
- bundle.getString("ContentTableHeader")
- };
- }
-
- // Removes the unnecessary border of JComboBox for Windows Vista and
above.
- private void fixComboBoxUIForWindows() {
- String osName = System.getProperty("os.name");
- double osVersion =
Double.parseDouble(System.getProperty("os.version"));
- if (osName.startsWith("Windows") && osVersion >= 6.0) {
- directionComboBox.setBorder(null);
- }
- }
-
private void aboutButtonActionPerformed(ActionEvent evt)
{//GEN-FIRST:event_aboutButtonActionPerformed
JOptionPane.showMessageDialog(this, bundle.getString("AboutContent"),
bundle.getString("AboutTitle"),
JOptionPane.INFORMATION_MESSAGE);
@@ -472,34 +456,8 @@
return;
}
}
-
pathTextField.setText(srt.getPath());
- enableComponents(false);
- srtTable.setModel(emptyModel);
- new SwingWorker<Void, Void>() {
-
- @Override
- protected Void doInBackground() throws Exception {
- // TO DO: Should show up exception if an error
occurred...
- loadSrt();
- return null;
- }
-
- @Override
- protected void done() {
- try {
- srtTable.setModel(tableModel);
-
srtTable.getTableHeader().setReorderingAllowed(false);
-
srtTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-// srtTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
- } catch (Exception ex) {
- showException(ex);
- } finally {
- enableComponents(true);
- }
- }
-
- }.execute();
+ loadSrt();
}
}//GEN-LAST:event_loadButtonActionPerformed
@@ -517,7 +475,7 @@
}
}//GEN-LAST:event_formWindowClosing
- private void enableComponents(boolean enabled) {
+ private void enableEditingComponents(boolean enabled) {
saveButton.setEnabled(enabled);
saveAsButton.setEnabled(enabled);
srtTable.setEnabled(enabled);
@@ -538,104 +496,68 @@
cancelTaskButton.setEnabled(enabled);
}
- private void loadSrt() throws SubtitleFormatException, IOException {
- tableModel = new DefaultTableModel(columnNames, 0) {
+ private void showException(Exception ex) {
+ JOptionPane.showMessageDialog(this, ex.getMessage(),
+ bundle.getString("Error"), JOptionPane.ERROR_MESSAGE);
+ }
+ private void loadSrt() {
+ loadButton.setEnabled(false);
+ enableEditingComponents(false);
+ srtTable.setModel(emptyModel);
+ progressBar.setIndeterminate(true);
+ progressBar.setString(bundle.getString("Loading"));
+ new SwingWorker<Vector<Vector<Object>>, Void>() {
+
@Override
- public boolean isCellEditable(int row, int column) {
- return false;
+ protected Vector<Vector<Object>> doInBackground() throws
Exception {
+ return SrtToolkit.parseSrt(new
File(pathTextField.getText()));
}
- };
- BufferedReader in = new BufferedReader(new InputStreamReader(
- new FileInputStream(pathTextField.getText()),
Context.getCharset()));
- lineNumber = 0;
- subtitleIndex = 1;
- while (readOneSubtitle(in)) {
- }
- }
+ @Override
+ protected void done() {
+ try {
+ Vector<String> columnNames = new Vector<String>();
+ columnNames.add(bundle.getString("IndexTableHeader"));
+
columnNames.add(bundle.getString("BeginTimeTableHeader"));
+ columnNames.add(bundle.getString("EndTimeTableHeader"));
+ columnNames.add(bundle.getString("ContentTableHeader"));
+ srtTable.setModel(new DefaultTableModel(get(),
columnNames) {
- /**
- * Read one subtitle from the reader and insert the parsed data to
- * {@code tableModel}.
- * @param in The reader to read the subtitles from.
- * @return {@code true} if one subtitle is read, otherwise {@code false}.
- * @throws SubtitleFormatException If the format is wrong.
- * @throws IOException If an I/O error occured.
- */
- private boolean readOneSubtitle(BufferedReader in)
- throws SubtitleFormatException, IOException {
- // If there're more subtitles, the line should be the index.
- String index = readNonEmptyLine(in);
- if (index == null) {
- return false;
- }
+ @Override
+ public boolean isCellEditable(int row, int column) {
+ return false;
+ }
- // Start to read a subtitle.
- // We can bypass the index, for it's easy and safe to regenerate
them.
- // Read begin and end times.
- String[] times = readStartAndEndTimes(in);
- if (times == null) {
- return false;
- }
-
- tableModel.addRow(new Object[] {
- subtitleIndex++, times[0], times[1], readContent(in)
- });
- return true;
- }
-
- private String readNonEmptyLine(BufferedReader in) throws IOException {
- String line = null;
- // Skip empty lines.
- do {
- line = readLine(in);
- if (line == null) {
- return null;
+ });
+ srtTable.getTableHeader().setReorderingAllowed(false);
+
srtTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ srtTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+ TableColumnModel columnModel = srtTable.getColumnModel();
+ columnModel.getColumn(0).setPreferredWidth(50);
+ columnModel.getColumn(1).setPreferredWidth(100);
+ columnModel.getColumn(2).setPreferredWidth(100);
+ columnModel.getColumn(3).setPreferredWidth(500);
+ } catch (Exception ex) {
+ Throwable cause = ex.getCause();
+ if (cause != null && (cause instanceof IOException
+ || cause instanceof SubtitleFormatException)) {
+ showException((Exception) cause);
+ } else {
+ showException(ex);
+ }
+ return;
+ } finally {
+ loadButton.setEnabled(true);
+ progressBar.setIndeterminate(false);
+ progressBar.setString(bundle.getString("Ready"));
+ }
+ enableEditingComponents(true);
}
- } while (line.isEmpty());
- return line;
- }
- private String[] readStartAndEndTimes(BufferedReader in)
- throws SubtitleFormatException, IOException {
- String time = readLine(in);
- if (time == null) {
- return null;
- }
- String[] times = time.split(" --> ");
- if (times.length != 2
- || !timePattern.matcher(times[0]).matches()
- || !timePattern.matcher(times[1]).matches()) {
- throw new SubtitleFormatException(bundle.getString("BadTime"));
- }
- return times;
+ }.execute();
}
- private String readContent(BufferedReader in) throws IOException {
- String content = "";
- String line = readLine(in);
- while (line != null) {
- if (line.isEmpty()) {
- break;
- }
- content = content + line + "\n";
- line = readLine(in);
- }
- return content;
- }
-
- private String readLine(BufferedReader in) throws IOException {
- String line = in.readLine();
- lineNumber++;
- return line;
- }
-
- private void showException(Exception ex) {
- JOptionPane.showMessageDialog(this, ex.getMessage(),
- bundle.getString("Error"), JOptionPane.ERROR_MESSAGE);
- }
-
public static void main(String args[]) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
@@ -674,6 +596,7 @@
private JLabel contentLabel;
private JScrollPane contentScrollPane;
private JTextArea contentTextArea;
+ private JCheckBox continuousEditCheckBox;
private JButton deleteButton;
private JComboBox directionComboBox;
private JLabel directionLabel;
Index: SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtEditorFrame.form
===================================================================
--- SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtEditorFrame.form
(revision 29)
+++ SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtEditorFrame.form
(revision 30)
@@ -44,26 +44,26 @@
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
- <Component id="srtScrollPane" alignment="0" pref="620"
max="32767" attributes="0"/>
+ <Component id="srtScrollPane" alignment="0" pref="644"
max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="loadButton" min="-2" max="-2"
attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
- <Component id="pathTextField" pref="363" max="32767"
attributes="0"/>
+ <Component id="pathTextField" pref="365" max="32767"
attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="saveButton" linkSize="7" min="-2"
max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="saveAsButton" linkSize="7" min="-2"
max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
- <Component id="addBeforeButton" pref="122" max="32767"
attributes="0"/>
+ <Component id="addBeforeButton" pref="126" max="32767"
attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
- <Component id="addAfterButton" pref="120" max="32767"
attributes="0"/>
+ <Component id="addAfterButton" pref="124" max="32767"
attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
- <Component id="moveUpButton" pref="119" max="32767"
attributes="0"/>
+ <Component id="moveUpButton" pref="123" max="32767"
attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
- <Component id="moveDownButton" pref="120" max="32767"
attributes="0"/>
+ <Component id="moveDownButton" pref="124" max="32767"
attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
- <Component id="deleteButton" pref="115" max="32767"
attributes="0"/>
+ <Component id="deleteButton" pref="123" max="32767"
attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="editSubtitlePanel" max="32767"
attributes="0"/>
@@ -79,7 +79,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="toolBar" min="-2" max="-2"
attributes="0"/>
</Group>
- <Component id="separator1" alignment="0" pref="620"
max="32767" attributes="0"/>
+ <Component id="separator1" alignment="0" pref="644"
max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@@ -182,18 +182,22 @@
<Group type="102" alignment="0" attributes="0">
<Component id="beginTimeLabel" min="-2" max="-2"
attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
- <Component id="beginTimeTextField" pref="142"
max="32767" attributes="0"/>
+ <Component id="beginTimeTextField" pref="144"
max="32767" attributes="0"/>
<EmptySpace type="separate" min="-2" max="-2"
attributes="0"/>
<Component id="endTimeLabel" min="-2" max="-2"
attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
- <Component id="endTimeTextField" pref="143"
max="32767" attributes="0"/>
+ <Component id="endTimeTextField" pref="145"
max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="contentLabel" min="-2" max="-2"
attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
- <Component id="contentScrollPane" pref="361"
max="32767" attributes="0"/>
+ <Component id="contentScrollPane" pref="377"
max="32767" attributes="0"/>
</Group>
- <Component id="updateSubtitleButton" alignment="1"
min="-2" max="-2" attributes="0"/>
+ <Group type="102" alignment="1" attributes="0">
+ <Component id="continuousEditCheckBox" min="-2"
max="-2" attributes="0"/>
+ <EmptySpace pref="113" max="32767" attributes="0"/>
+ <Component id="updateSubtitleButton" min="-2"
max="-2" attributes="0"/>
+ </Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@@ -212,10 +216,13 @@
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="contentLabel" min="-2" max="-2"
attributes="1"/>
- <Component id="contentScrollPane" pref="72"
max="32767" attributes="1"/>
+ <Component id="contentScrollPane" pref="75"
max="32767" attributes="1"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
- <Component id="updateSubtitleButton" min="-2" max="-2"
attributes="0"/>
+ <Group type="103" groupAlignment="3" attributes="0">
+ <Component id="updateSubtitleButton" alignment="3"
min="-2" max="-2" attributes="0"/>
+ <Component id="continuousEditCheckBox" alignment="3"
min="-2" max="-2" attributes="0"/>
+ </Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@@ -269,6 +276,14 @@
</Property>
</Properties>
</Component>
+ <Component class="javax.swing.JCheckBox"
name="continuousEditCheckBox">
+ <Properties>
+ <Property name="selected" type="boolean" value="true"/>
+ <Property name="text" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="com/zhyi/srtsubtitleeditor/Bundle.properties" key="ContinuousEdit"
replaceFormat="bundle.getString("{key}")"/>
+ </Property>
+ </Properties>
+ </Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="addBeforeButton">
@@ -336,7 +351,7 @@
<Group type="102" alignment="0" attributes="0">
<Component id="amountLabel" linkSize="3" min="-2"
max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
- <Component id="amountTextField" pref="52"
max="32767" attributes="0"/>
+ <Component id="amountTextField" pref="53"
max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="msLabel" min="-2" max="-2"
attributes="0"/>
</Group>
Index: SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtToolkit.java
===================================================================
--- SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtToolkit.java
(revision 0)
+++ SrtSubtitleEditor/src/com/zhyi/srtsubtitleeditor/SrtToolkit.java
(revision 30)
@@ -0,0 +1,162 @@
+/*
+ * SrtToolkit.java
+ *
+ * Copyright (C) 2009 Zhao Yi
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.zhyi.srtsubtitleeditor;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.text.MessageFormat;
+import java.util.Vector;
+import java.util.regex.Pattern;
+
+/**
+ * This class contains methods for processing SRT files.
+ * @author Zhao Yi
+ */
+public class SrtToolkit {
+
+ private static final Pattern TIME_PATTERN = Pattern.compile(
+ "^\\d{2}(:[0-5]\\d){2},\\d{3}$");
+ private static int lineNumber = 0;
+ private static int subtitleIndex = 1;
+
+ /**
+ * Parses a SRT file to a vector of vectors which can be used directly
for
+ * constructing a {@code DefaultTableModel} object. Each sub-vector
+ * represents a subtitle (index, begin time, end time and content).
+ * @param srtFile The SR file.
+ * @return A vector of vector containing all subtitles.
+ * @throws SubtitleFormatException If the begin or end time of a subtitle
+ * is bad formatted.
+ * @throws IOException If any I/O error occureed.
+ */
+ public static Vector<Vector<Object>> parseSrt(File srtFile)
+ throws SubtitleFormatException, IOException {
+ lineNumber = 0;
+ subtitleIndex = 0;
+ BufferedReader in = new BufferedReader(new InputStreamReader(
+ new FileInputStream(srtFile), Context.getCharset()));
+ Vector<Vector<Object>> subtitles = new Vector<Vector<Object>>();
+ Vector<Object> subtitle = readOneSubtitle(in);
+ while (subtitle != null) {
+ subtitles.add(subtitle);
+ subtitle = readOneSubtitle(in);
+ }
+ in.close();
+ return subtitles;
+ }
+
+ /**
+ * Saves subtitles to an SRT file.
+ * @param subtitles A vector of vector containing all subtitles which can
+ * be got from the SRT table's model.
+ * @param srtFile The SRT file.
+ * @throws IOException If any I/O error occureed.
+ */
+ public static void saveSrt(Vector<Vector<Object>> subtitles, File
srtFile)
+ throws IOException {
+ BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(srtFile), Context.getCharset()));
+ for (Vector<Object> subtitle : subtitles) {
+ for (Object datum : subtitle) {
+ out.write((String) datum);
+ out.newLine();
+ }
+ out.newLine();
+ }
+ out.close();
+ }
+
+ private static Vector<Object> readOneSubtitle(BufferedReader in)
+ throws SubtitleFormatException, IOException {
+ // If there're more subtitles, the line should be the index. However,
+ // the index is ignored, for it will be added automatically later.
+ String index = readNonEmptyLine(in);
+ if (index == null) {
+ return null;
+ }
+
+ // Read begin and end times.
+ String[] times = readBeginAndEndTimes(in);
+ if (times == null) {
+ return null;
+ }
+
+ Vector<Object> subtitle = new Vector<Object>();
+ subtitle.add(subtitleIndex++);
+ subtitle.add(times[0]);
+ subtitle.add(times[1]);
+ subtitle.add(readContent(in));
+ return subtitle;
+ }
+
+ private static String readNonEmptyLine(BufferedReader in) throws
IOException {
+ String line = null;
+ // Skip empty lines.
+ do {
+ line = readLine(in);
+ if (line == null) {
+ // The end of file.
+ return null;
+ }
+ } while (line.isEmpty());
+ return line;
+ }
+
+ private static String[] readBeginAndEndTimes(BufferedReader in)
+ throws SubtitleFormatException, IOException {
+ String time = readLine(in);
+ if (time == null) {
+ return null;
+ }
+ String[] times = time.split(" --> ");
+ if (times.length != 2
+ || !TIME_PATTERN.matcher(times[0]).matches()
+ || !TIME_PATTERN.matcher(times[1]).matches()) {
+ throw new SubtitleFormatException(MessageFormat.format(
+ Context.getBundle().getString("BadTime"), lineNumber));
+ }
+ return times;
+ }
+
+ private static String readContent(BufferedReader in) throws IOException {
+ String content = "";
+ String line = readLine(in);
+ while (line != null) {
+ if (line.isEmpty()) {
+ break;
+ }
+ content = content + line + "\n";
+ line = readLine(in);
+ }
+ return content;
+ }
+
+ private static String readLine(BufferedReader in) throws IOException {
+ String line = in.readLine();
+ lineNumber++;
+ return line;
+ }
+
+}
|
[zhyi~subversion:30] Separated the logic for processing SRT to a single class. |
zhyi | 10/18/2009 |





