/* * (C) Copyright 2014 Boni Garcia (http://bonigarcia.github.io/) * * 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 io.github.bonigarcia.dualsub.gui; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.Properties; import java.util.prefs.Preferences; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.border.TitledBorder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jgoodies.plaf.plastic.Plastic3DLookAndFeel; import io.github.bonigarcia.dualsub.srt.SrtUtils; import io.github.bonigarcia.dualsub.util.Charset; import io.github.bonigarcia.dualsub.util.Font; import io.github.bonigarcia.dualsub.util.I18N; /** * DualSub. * * @author Boni Garcia ([email protected]) * @since 1.0.0 */ public class DualSub { private static final Logger log = LoggerFactory.getLogger(DualSub.class); // Preferences and Properties private Preferences preferences; private Properties properties; // UI Elements private JFrame frame; private JList<File> leftSubtitles; private JList<File> rightSubtitles; private JTextField outputFolder; private Splash splash; private Cursor cursor; private MergeButtonListener mergeButtonListener; private AddFileListener leftFileListener; private AddFileListener rightFileListener; private AddFolderListener folderListener; private Menu menu; private JProgressBar progressBar; private Color background; private JButton mergeButton; // Panels (options) private PanelTiming panelTiming; private PanelPlayer panelPlayer; private PanelOutput panelOutput; private PanelTranslation panelTranslation; // Dialogs private ExceptionDialog exception; private HelpPlayerDialog helpPlayer; private HelpTimingDialog helpTiming; private HelpOutputDialog helpOutput; private HelpTranslationDialog helpTranslation; private HelpSubtitlesDialog helpSubtitles; private KeyTranslationDialog keyTranslationDialog; /** * Create the GUI. * * @throws IOException */ public DualSub() throws IOException { // Look and feel try { // UIManager.setLookAndFeel(new NimbusLookAndFeel()); UIManager.setLookAndFeel(new Plastic3DLookAndFeel()); JFrame.setDefaultLookAndFeelDecorated(false); JDialog.setDefaultLookAndFeelDecorated(false); // UIManager.setLookAndFeel(UIManager // .getCrossPlatformLookAndFeelClassName()); // JFrame.setDefaultLookAndFeelDecorated(true); // JDialog.setDefaultLookAndFeelDecorated(true); } catch (Exception e) { log.warn(e.getMessage()); } splash = new Splash(ClassLoader.getSystemResource("img/splash.png")); cursor = new Cursor(Cursor.HAND_CURSOR); loadProperties(); // Default language String locale = preferences.get("locale", properties.getProperty("locale")); if (!locale.isEmpty()) { I18N.setLocale(locale); } initialize(); menu = new Menu(this, locale); menu.addMenu(leftFileListener, rightFileListener, folderListener, mergeButtonListener); showFrame(); } public void close() { frame.dispose(); } private void loadProperties() throws IOException { // Load properties properties = new Properties(); InputStream inputStream = Thread.currentThread().getContextClassLoader() .getResourceAsStream("dualsub.properties"); Reader reader = new InputStreamReader(inputStream, Charset.ISO88591); properties.load(reader); Font.setProperties(properties); // Instantiate preferences preferences = Preferences.userNodeForPackage(DualSub.class); } /** * Initialize the contents of the frame. */ private void initialize() { frame = new JFrame(); background = new Color(240, 240, 240); frame.getContentPane().setBackground(background); // Alert initialization Alert.setFrame(frame); // Progress bar progressBar = new JProgressBar(); progressBar.setIndeterminate(true); progressBar.setBounds(308, 110, 95, 15); progressBar.setBackground(background); progressBar.setVisible(false); frame.getContentPane().add(progressBar); // Left subtitles JScrollPane leftSubtitlesScroll = new JScrollPane(); leftSubtitlesScroll.setBounds(46, 37, 260, 121); frame.getContentPane().add(leftSubtitlesScroll); leftSubtitles = new JList<File>(new DefaultListModel<File>()); leftSubtitles.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent key) { if (key.getKeyCode() == KeyEvent.VK_DELETE) { Validator.deleteSelected(leftSubtitles); } } }); leftSubtitles.setCellRenderer(new FileCellRenderer()); leftSubtitles .setTransferHandler(new ListTransferHandler(leftSubtitles)); leftSubtitles.setDragEnabled(true); leftSubtitles.setDropMode(javax.swing.DropMode.INSERT); leftSubtitles.setBorder( new TitledBorder(UIManager.getBorder("TitledBorder.border"), I18N.getHtmlText("Window.leftSubtitles.borderTitle"))); String leftColor = preferences.get("leftColor", ""); if (leftColor != null && !leftColor.isEmpty()) { leftSubtitles.setBackground(Color.decode(leftColor)); SrtUtils.setLeftColor(leftColor); } leftSubtitlesScroll.setViewportView(leftSubtitles); // Right subtitles JScrollPane rightSubtitlesScroll = new JScrollPane(); rightSubtitlesScroll.setBounds(405, 37, 260, 121); frame.getContentPane().add(rightSubtitlesScroll); rightSubtitles = new JList<File>(new DefaultListModel<File>()); rightSubtitles.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent key) { if (key.getKeyCode() == KeyEvent.VK_DELETE) { Validator.deleteSelected(rightSubtitles); } } }); rightSubtitles.setCellRenderer(new FileCellRenderer()); rightSubtitles .setTransferHandler(new ListTransferHandler(rightSubtitles)); rightSubtitles.setDragEnabled(true); rightSubtitles.setDropMode(javax.swing.DropMode.INSERT); rightSubtitles.setBorder( new TitledBorder(UIManager.getBorder("TitledBorder.border"), I18N.getHtmlText("Window.rightSubtitles.borderTitle"))); String rightColor = preferences.get("rightColor", ""); if (rightColor != null && !rightColor.isEmpty()) { rightSubtitles.setBackground(Color.decode(rightColor)); SrtUtils.setRightColor(rightColor); } rightSubtitlesScroll.setViewportView(rightSubtitles); // Output folder JButton outputFolderButton = new JButton( I18N.getHtmlText("Window.outputFolderButton.text")); outputFolderButton.setBounds(46, 180, 117, 29); outputFolderButton.setCursor(cursor); frame.getContentPane().add(outputFolderButton); outputFolder = new JTextField(); outputFolder.setBounds(165, 181, 500, 28); outputFolder.setColumns(10); outputFolder.setText( preferences.get("output", properties.getProperty("output"))); frame.getContentPane().add(outputFolder); folderListener = new AddFolderListener(frame, outputFolder); outputFolderButton.addActionListener(folderListener); // Left buttons leftFileListener = new AddFileListener(frame, leftSubtitles); new LateralButtons(cursor, frame, leftSubtitles, leftFileListener, 16); // Right buttons rightFileListener = new AddFileListener(frame, rightSubtitles); new LateralButtons(cursor, frame, rightSubtitles, rightFileListener, 673); // Color Buttons new ColorButtons(cursor, frame, leftSubtitles, rightSubtitles); // Merge Button mergeButton = new JButton(I18N.getHtmlText("Window.mergeButton.text")); mergeButtonListener = new MergeButtonListener(this); mergeButton.addActionListener(mergeButtonListener); mergeButton.setBounds(308, 80, 95, 29); mergeButton.setCursor(cursor); frame.getContentPane().add(mergeButton); // Timing panel panelTiming = new PanelTiming(this); frame.getContentPane().add(panelTiming); // Player panel panelPlayer = new PanelPlayer(this); frame.getContentPane().add(panelPlayer); // Output panel panelOutput = new PanelOutput(this); frame.getContentPane().add(panelOutput); // Translation panel panelTranslation = new PanelTranslation(this); frame.getContentPane().add(panelTranslation); // Help JButton buttonHelpSub = new JButton( new ImageIcon(ClassLoader.getSystemResource("img/help.png"))); buttonHelpSub.setBounds(345, 50, 22, 22); buttonHelpSub.setCursor(cursor); final DualSub top = this; buttonHelpSub.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { HelpSubtitlesDialog helpSubtitlesDialog = getHelpSubtitles(); if (helpSubtitlesDialog == null) { helpSubtitlesDialog = new HelpSubtitlesDialog(top, true); } helpSubtitlesDialog.setVisible(); } }); frame.add(buttonHelpSub); // Frame frame.setBounds(100, 100, 720, 520); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); frame.setLocation((dim.width - frame.getWidth()) / 2, (dim.height - frame.getHeight()) / 2); frame.setResizable(false); frame.setIconImage( new ImageIcon(ClassLoader.getSystemResource("img/dualsub.png")) .getImage()); frame.setTitle(I18N.getText("Window.name.text")); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.addWindowListener(new ExitListener(this)); frame.getContentPane().setLayout(null); } private void showFrame() { if (!frame.isVisible()) { splash.setVisible(false); frame.setVisible(true); frame.requestFocus(); } } public JFrame getFrame() { return frame; } public PanelTiming getPanelTiming() { return panelTiming; } public PanelPlayer getPanelPlayer() { return panelPlayer; } public PanelOutput getPanelOutput() { return panelOutput; } public PanelTranslation getPanelTranslation() { return panelTranslation; } public Preferences getPreferences() { return preferences; } public Properties getProperties() { return properties; } public Cursor getCursor() { return cursor; } public Color getBackground() { return background; } public JProgressBar getProgressBar() { return progressBar; } public JList<File> getLeftSubtitles() { return leftSubtitles; } public JList<File> getRightSubtitles() { return rightSubtitles; } public JTextField getOutputFolder() { return outputFolder; } public ExceptionDialog getException() { return exception; } public void setException(ExceptionDialog exception) { this.exception = exception; } public HelpPlayerDialog getHelpPlayer() { return helpPlayer; } public HelpTimingDialog getHelpTiming() { return helpTiming; } public HelpOutputDialog getHelpOutput() { return helpOutput; } public HelpTranslationDialog getHelpTranslation() { return helpTranslation; } public HelpSubtitlesDialog getHelpSubtitles() { return helpSubtitles; } public void setHelpPlayer(HelpPlayerDialog helpPlayer) { this.helpPlayer = helpPlayer; } public void setHelpTiming(HelpTimingDialog helpTiming) { this.helpTiming = helpTiming; } public void setHelpOutput(HelpOutputDialog helpOutput) { this.helpOutput = helpOutput; } public void setHelpTranslation(HelpTranslationDialog helpTranslation) { this.helpTranslation = helpTranslation; } public void setHelpSubtitles(HelpSubtitlesDialog helpSubtitles) { this.helpSubtitles = helpSubtitles; } public KeyTranslationDialog getKeyTranslationDialog() { return keyTranslationDialog; } public void setKeyTranslationDialog( KeyTranslationDialog keyTranslationDialog) { this.keyTranslationDialog = keyTranslationDialog; } public Menu getMenu() { return menu; } public JButton getMergeButton() { return mergeButton; } /** * Launch the application. * * @throws IOException */ public static void main(String[] args) throws IOException { new DualSub(); } }