/*
* JAME 6.2.1
* http://jame.sourceforge.net
*
* Copyright 2001, 2016 Andrea Medeghini
*
* This file is part of JAME.
*
* JAME is an application for creating fractals and other graphics artifacts.
*
* JAME 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.
*
* JAME 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 JAME. If not, see <http://www.gnu.org/licenses/>.
*
*/
package net.sf.jame.twister.swing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.Properties;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellRenderer;
import net.sf.jame.core.extension.ConfigurableExtension;
import net.sf.jame.core.extension.ExtensionException;
import net.sf.jame.core.swing.extension.ConfigurableExtensionComboBoxModel;
import net.sf.jame.core.swing.extension.ExtensionListCellRenderer;
import net.sf.jame.core.swing.util.AlternateTableCellRenderer;
import net.sf.jame.core.swing.util.ExtendedGUIWorker;
import net.sf.jame.core.swing.util.GUIFactory;
import net.sf.jame.core.swing.util.GUIUtil;
import net.sf.jame.core.swing.util.WorkerProgressDialog;
import net.sf.jame.core.swing.util.ZIPFileFilter;
import net.sf.jame.core.util.Rectangle;
import net.sf.jame.core.xml.XML;
import net.sf.jame.queue.LibraryService;
import net.sf.jame.queue.PreviewListener;
import net.sf.jame.queue.RenderService;
import net.sf.jame.queue.RenderService.ServiceCallback;
import net.sf.jame.queue.RenderServiceRegistry;
import net.sf.jame.queue.clip.RenderClip;
import net.sf.jame.queue.clip.RenderClipDataRow;
import net.sf.jame.queue.profile.RenderProfile;
import net.sf.jame.queue.profile.RenderProfileDataRow;
import net.sf.jame.queue.spool.JobServiceListener;
import net.sf.jame.queue.spool.extension.SpoolExtensionConfig;
import net.sf.jame.queue.spool.extension.SpoolExtensionRuntime;
import net.sf.jame.twister.TwisterClip;
import net.sf.jame.twister.TwisterClipXMLImporter;
import net.sf.jame.twister.TwisterConfig;
import net.sf.jame.twister.TwisterConfigBuilder;
import net.sf.jame.twister.TwisterSequence;
import net.sf.jame.twister.swing.encoder.EncoderDialog;
import org.w3c.dom.Document;
public class ServiceFrame extends JFrame {
private static final long serialVersionUID = 1L;
private static final String SERVICE_FRAME_TITLE = "serviceFrame.title";
private static final String SERVICE_FRAME_WIDTH = "serviceFrame.width";
private static final String SERVICE_FRAME_HEIGHT = "serviceFrame.height";
private static final String SERVICE_FRAME_ICON = "serviceFrame.icon";
private ServicePanel servicePanel;
/**
* @param context
* @param service
* @param clipModel
* @param profileModel
* @param jobModel
* @throws HeadlessException
*/
public ServiceFrame(final ServiceContext context, final RenderService service, final RenderClipTableModel clipModel, final RenderProfileTableModel profileModel, final RenderJobTableModel jobModel) throws HeadlessException {
servicePanel = new ServicePanel(context, service, clipModel, profileModel, jobModel);
getContentPane().add(servicePanel);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
final int defaultWidth = Integer.parseInt(TwisterSwingResources.getInstance().getString(ServiceFrame.SERVICE_FRAME_WIDTH));
final int defaultHeight = Integer.parseInt(TwisterSwingResources.getInstance().getString(ServiceFrame.SERVICE_FRAME_HEIGHT));
final int width = Integer.getInteger(ServiceFrame.SERVICE_FRAME_WIDTH, defaultWidth);
final int height = Integer.getInteger(ServiceFrame.SERVICE_FRAME_HEIGHT, defaultHeight);
setTitle(TwisterSwingResources.getInstance().getString(ServiceFrame.SERVICE_FRAME_TITLE));
final URL resource = ServiceFrame.class.getClassLoader().getResource(TwisterSwingResources.getInstance().getString(ServiceFrame.SERVICE_FRAME_ICON));
if (resource != null) {
setIconImage(getToolkit().createImage(resource));
}
setSize(new Dimension(width, height));
final Point p = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
p.x -= getWidth() / 2;
p.y -= getHeight() / 2;
this.setLocation(p);
addWindowListener(new ServiceWindowListener(servicePanel));
}
/**
* @see java.awt.Window#dispose()
*/
@Override
public void dispose() {
super.dispose();
if (servicePanel != null) {
servicePanel.dispose();
servicePanel = null;
}
}
private class ServiceWindowListener extends WindowAdapter {
private final ServicePanel servicePanel;
/**
* @param canvas
*/
public ServiceWindowListener(final ServicePanel servicePanel) {
this.servicePanel = servicePanel;
}
/**
* @see java.awt.event.WindowAdapter#windowOpened(java.awt.event.WindowEvent)
*/
@Override
public void windowOpened(final WindowEvent e) {
GUIUtil.executeTask(new Runnable() {
public void run() {
if (servicePanel != null) {
try {
if (!servicePanel.isStarted()) {
servicePanel.start();
}
}
catch (final ExtensionException x) {
x.printStackTrace();
}
}
}
}, true);
}
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosing(final WindowEvent e) {
if (servicePanel != null) {
if (servicePanel.isStarted()) {
servicePanel.stop();
}
}
}
/**
* @see java.awt.event.WindowAdapter#windowDeiconified(java.awt.event.WindowEvent)
*/
@Override
public void windowDeiconified(final WindowEvent e) {
GUIUtil.executeTask(new Runnable() {
public void run() {
if (servicePanel != null) {
try {
if (!servicePanel.isStarted()) {
servicePanel.start();
}
}
catch (final ExtensionException x) {
x.printStackTrace();
}
}
}
}, true);
}
/**
* @see java.awt.event.WindowAdapter#windowIconified(java.awt.event.WindowEvent)
*/
@Override
public void windowIconified(final WindowEvent e) {
if (servicePanel != null) {
if (servicePanel.isStarted()) {
servicePanel.stop();
}
}
}
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosed(final WindowEvent e) {
}
}
public static class ServicePanel extends JPanel {
private static final Logger logger = Logger.getLogger(ServicePanel.class.getName());
private static final long serialVersionUID = 1L;
private static final String STRING_FRAME_TAB_CLIPS = "tab.clips";
private static final String STRING_FRAME_TAB_JOBS = "tab.jobs";
private final JButton clipOpenButton = GUIFactory.createSmallButton(new ClipOpenAction(), TwisterSwingResources.getInstance().getString("tooltip.openClip"));
private final JButton clipCreateButton = GUIFactory.createSmallButton(new ClipCreateAction(), TwisterSwingResources.getInstance().getString("tooltip.createClip"));
private final JButton clipDeleteButton = GUIFactory.createSmallButton(new ClipDeleteAction(), TwisterSwingResources.getInstance().getString("tooltip.deleteClip"));
private final JButton clipModifyButton = GUIFactory.createSmallButton(new ClipModifyAction(), TwisterSwingResources.getInstance().getString("tooltip.modifyClip"));
private final JButton clipImportButton = GUIFactory.createSmallButton(new ClipImportAction(), TwisterSwingResources.getInstance().getString("tooltip.importClip"));
private final JButton clipExportButton = GUIFactory.createSmallButton(new ClipExportAction(), TwisterSwingResources.getInstance().getString("tooltip.exportClip"));
private final JButton profileCreateButton = GUIFactory.createSmallButton(new ProfileCreateAction(), TwisterSwingResources.getInstance().getString("tooltip.createProfile"));
private final JButton profileDeleteButton = GUIFactory.createSmallButton(new ProfileDeleteAction(), TwisterSwingResources.getInstance().getString("tooltip.deleteProfile"));
private final JButton profileModifyButton = GUIFactory.createSmallButton(new ProfileModifyAction(), TwisterSwingResources.getInstance().getString("tooltip.modifyProfile"));
private final JButton profileRenderButton = GUIFactory.createSmallButton(new ProfileRenderAction(), TwisterSwingResources.getInstance().getString("tooltip.renderProfile"));
private final JButton profileCleanButton = GUIFactory.createSmallButton(new ProfileCleanAction(), TwisterSwingResources.getInstance().getString("tooltip.cleanProfile"));
private final JButton profileAbortButton = GUIFactory.createSmallButton(new ProfileAbortAction(), TwisterSwingResources.getInstance().getString("tooltip.abortProfile"));
private final JButton profileStartButton = GUIFactory.createSmallButton(new ProfileStartAction(), TwisterSwingResources.getInstance().getString("tooltip.startProfile"));
private final JButton profileStopButton = GUIFactory.createSmallButton(new ProfileStopAction(), TwisterSwingResources.getInstance().getString("tooltip.stopProfile"));
private final JButton profileExportButton = GUIFactory.createSmallButton(new ProfileExportAction(), TwisterSwingResources.getInstance().getString("tooltip.exportProfile"));
private final JButton changeWorkspaceButton = GUIFactory.createSmallButton(new ChangeWorkspaceAction(), TwisterSwingResources.getInstance().getString("tooltip.changeWorkspace"));
private final JButton checkUpdateButton = GUIFactory.createSmallButton(new CheckUpdateAction(), TwisterSwingResources.getInstance().getString("tooltip.checkUpdate"));
private final JButton showAboutButton = GUIFactory.createSmallButton(new ShowAboutAction(), TwisterSwingResources.getInstance().getString("tooltip.showAbout"));
private final JFileChooser clipChooser = new JFileChooser(System.getProperty("user.home"));
private final JFileChooser fileChooser = new JFileChooser(System.getProperty("user.home"));
private final JLabel spoolStatusLabel;
private final JComboBox extensionComboBox;
private final EncoderDialog encoderDialog;
private final TwisterPreviewCanvas preview;
private final ServiceTable clipTable;
private final ServiceTable profileTable;
private final ServiceTable jobTable;
private final RenderClipTableModel clipModel;
private final RenderProfileTableModel profileModel;
private final RenderJobTableModel jobModel;
private final Semaphore semaphore = new Semaphore(0, true);
private final ServiceContext context;
private final RenderService service;
private final JobServiceListener listener;
private final RefreshTask refreshTask;
private final TableListener tableListener;
private final PreviewListener previewListener;
private final JLabel jobLabel;
private final JLabel clipLabel;
private final JLabel profileLabel;
private volatile int copyProcessServiceStatus;
private volatile int postProcessServiceStatus;
private volatile int processServiceStatus;
/**
* @param context
* @param service
* @param clipModel
* @param profileModel
* @param jobModel
*/
@SuppressWarnings("unchecked")
public ServicePanel(final ServiceContext context, final RenderService service, final RenderClipTableModel clipModel, final RenderProfileTableModel profileModel, final RenderJobTableModel jobModel) {
this.context = context;
final JPanel clipPreview = new JPanel(new BorderLayout());
preview = new TwisterPreviewCanvas();
clipPreview.add(preview, BorderLayout.CENTER);
clipPreview.add(Box.createVerticalStrut(40), BorderLayout.SOUTH);
clipPreview.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.preview"));
clipPreview.setBorder(BorderFactory.createEmptyBorder(28, 2, 2, 4));
encoderDialog = new EncoderDialog(new JFrame(), service);
setLayout(new BorderLayout());
clipChooser.setFileFilter(new ZIPFileFilter());
clipChooser.setMultiSelectionEnabled(false);
fileChooser.setDialogTitle(TwisterSwingResources.getInstance().getString("label.workspace"));
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setMultiSelectionEnabled(false);
final JPanel panel = new JPanel(new BorderLayout());
clipTable = new ServiceTable(clipModel);
clipTable.setRowHeight(24);
clipTable.setGridColor(Color.LIGHT_GRAY);
final JPanel clipTablePanel = new JPanel(new BorderLayout());
final Box clipButtonPanel = Box.createHorizontalBox();
clipButtonPanel.add(Box.createHorizontalGlue());
clipButtonPanel.add(clipCreateButton);
clipButtonPanel.add(clipModifyButton);
clipButtonPanel.add(clipDeleteButton);
clipButtonPanel.add(clipImportButton);
clipButtonPanel.add(clipExportButton);
clipButtonPanel.add(clipOpenButton);
clipButtonPanel.add(Box.createHorizontalGlue());
clipButtonPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 0));
Dimension labelSize = new Dimension(200, 20);
jobLabel = new JLabel(TwisterSwingResources.getInstance().getString("label.jobPanel"));
jobLabel.setMinimumSize(labelSize);
jobLabel.setMaximumSize(labelSize);
jobLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
clipLabel = new JLabel(TwisterSwingResources.getInstance().getString("label.clipPanel"));
clipLabel.setMinimumSize(labelSize);
clipLabel.setMaximumSize(labelSize);
clipLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
profileLabel = new JLabel(TwisterSwingResources.getInstance().getString("label.profilePanel"));
profileLabel.setMinimumSize(labelSize);
profileLabel.setMaximumSize(labelSize);
profileLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
clipTablePanel.add(clipLabel, BorderLayout.NORTH);
clipTablePanel.add(new JScrollPane(clipTable), BorderLayout.CENTER);
clipTablePanel.add(clipButtonPanel, BorderLayout.SOUTH);
profileTable = new ServiceTable(profileModel);
profileTable.setGridColor(Color.LIGHT_GRAY);
final JPanel profileTablePanel = new JPanel(new BorderLayout());
final Box profileButtonPanel = Box.createHorizontalBox();
profileButtonPanel.add(Box.createHorizontalGlue());
profileButtonPanel.add(profileCreateButton);
profileButtonPanel.add(profileModifyButton);
profileButtonPanel.add(profileDeleteButton);
profileButtonPanel.add(profileRenderButton);
profileButtonPanel.add(profileCleanButton);
profileButtonPanel.add(profileAbortButton);
profileButtonPanel.add(profileStartButton);
profileButtonPanel.add(profileStopButton);
profileButtonPanel.add(profileExportButton);
profileButtonPanel.add(Box.createHorizontalGlue());
profileButtonPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 0));
profileTablePanel.add(profileLabel, BorderLayout.NORTH);
profileTablePanel.add(new JScrollPane(profileTable), BorderLayout.CENTER);
profileTablePanel.add(profileButtonPanel, BorderLayout.SOUTH);
jobTable = new ServiceTable(jobModel);
jobTable.setGridColor(Color.LIGHT_GRAY);
final JPanel jobTablePanel = new JPanel(new BorderLayout());
final Box jobButtonPanel = Box.createHorizontalBox();
final ConfigurableExtensionComboBoxModel model = new ConfigurableExtensionComboBoxModel(RenderServiceRegistry.getInstance().getSpoolRegistry(), false);
spoolStatusLabel = GUIFactory.createLabel("", JLabel.LEFT);
spoolStatusLabel.setPreferredSize(new Dimension(300, GUIFactory.DEFAULT_HEIGHT));
model.setSelectedItemByExtensionId(service.getJobServiceReference().getExtensionId());
extensionComboBox = GUIFactory.createSmallComboBox(model, TwisterSwingResources.getInstance().getString("tooltip.spool"));
listener = new JobServiceListener() {
public void stateChanged(final int serviceId, final int status, final String message) {
GUIUtil.executeTask(new Runnable() {
public void run() {
switch (serviceId) {
case RenderService.SERVICE_COPY_PROCESS: {
copyProcessServiceStatus = status;
updateButtons();
break;
}
case RenderService.SERVICE_POST_PROCESS: {
postProcessServiceStatus = status;
updateButtons();
break;
}
case RenderService.SERVICE_PROCESS: {
spoolStatusLabel.setText(message);
processServiceStatus = status;
updateButtons();
break;
}
default:
break;
}
}
}, true);
}
};
spoolStatusLabel.setText("");
service.addJobServiceListener(listener);
extensionComboBox.setPreferredSize(new Dimension(160, GUIFactory.DEFAULT_HEIGHT));
extensionComboBox.setRenderer(new ExtensionListCellRenderer());
extensionComboBox.setOpaque(false);
jobButtonPanel.add(extensionComboBox);
jobButtonPanel.add(Box.createHorizontalStrut(8));
jobButtonPanel.add(spoolStatusLabel);
jobButtonPanel.add(Box.createHorizontalGlue());
jobButtonPanel.add(changeWorkspaceButton);
// jobButtonPanel.add(checkUpdateButton);
jobButtonPanel.add(showAboutButton);
jobButtonPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 0));
jobTablePanel.add(jobLabel, BorderLayout.NORTH);
jobTablePanel.add(new JScrollPane(jobTable), BorderLayout.CENTER);
jobTablePanel.add(jobButtonPanel, BorderLayout.SOUTH);
clipTablePanel.setOpaque(false);
profileTablePanel.setOpaque(false);
jobTablePanel.setOpaque(false);
final JSplitPane clipsTableSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, clipTablePanel, clipPreview);
clipsTableSplitPane.setOneTouchExpandable(true);
clipsTableSplitPane.setDividerLocation(550);
clipsTableSplitPane.setDividerSize(10);
final JSplitPane clipsSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, clipsTableSplitPane, profileTablePanel);
clipsSplitPane.setOneTouchExpandable(false);
clipsSplitPane.setDividerLocation(250);
clipsSplitPane.setDividerSize(10);
final FontMetrics clipTableFM = getFontMetrics(clipTable.getTableHeader().getFont());
for (int i = 0; i < clipTable.getColumnCount(); i++) {
clipTable.getColumnModel().getColumn(i).setCellRenderer(new AlternateTableCellRenderer());
clipTable.getColumnModel().getColumn(i).setPreferredWidth(SwingUtilities.computeStringWidth(clipTableFM, (((String) clipTable.getColumnModel().getColumn(i).getHeaderValue()))));
}
clipTable.getColumnModel().getColumn(RenderClipTableModel.PREVIEW).setCellRenderer(new ImageRenderer());
clipTable.getColumnModel().getColumn(RenderClipTableModel.PREVIEW).setMinWidth(64);
clipTable.getColumnModel().getColumn(RenderClipTableModel.PREVIEW).setMaxWidth(64);
clipTable.getColumnModel().getColumn(RenderClipTableModel.NAME).setPreferredWidth(100);
final FontMetrics profileTableFM = getFontMetrics(profileTable.getTableHeader().getFont());
for (int i = 0; i < profileTable.getColumnCount(); i++) {
profileTable.getColumnModel().getColumn(i).setCellRenderer(new AlternateTableCellRenderer());
profileTable.getColumnModel().getColumn(i).setPreferredWidth(SwingUtilities.computeStringWidth(profileTableFM, (((String) profileTable.getColumnModel().getColumn(i).getHeaderValue()))));
}
profileTable.getColumnModel().getColumn(RenderProfileTableModel.NAME).setPreferredWidth(60);
profileTable.getColumnModel().getColumn(RenderProfileTableModel.STATUS).setPreferredWidth(50);
final FontMetrics jobTableFM = getFontMetrics(jobTable.getTableHeader().getFont());
for (int i = 0; i < jobTable.getColumnCount(); i++) {
jobTable.getColumnModel().getColumn(i).setCellRenderer(new AlternateTableCellRenderer());
jobTable.getColumnModel().getColumn(i).setPreferredWidth(SwingUtilities.computeStringWidth(jobTableFM, (((String) jobTable.getColumnModel().getColumn(i).getHeaderValue()))));
}
jobTable.getColumnModel().getColumn(RenderJobTableModel.NAME).setPreferredWidth(100);
jobTable.getColumnModel().getColumn(RenderJobTableModel.TYPE).setPreferredWidth(80);
jobTablePanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
clipTablePanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
profileTablePanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
clipsTableSplitPane.setBorder(BorderFactory.createEmptyBorder());
clipsSplitPane.setBorder(BorderFactory.createEmptyBorder());
this.add(panel, BorderLayout.CENTER);
final JPanel clipsPanel = new JPanel(new BorderLayout());
final JPanel jobsPanel = new JPanel(new BorderLayout());
clipsPanel.setOpaque(false);
jobsPanel.setOpaque(false);
jobTablePanel.setOpaque(true);
clipsPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4), BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)));
jobsPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4), BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)));
clipsPanel.add(clipsSplitPane);
jobsPanel.add(jobTablePanel, BorderLayout.CENTER);
final JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab(TwisterSwingResources.getInstance().getString(ServicePanel.STRING_FRAME_TAB_CLIPS), clipsPanel);
tabbedPane.addTab(TwisterSwingResources.getInstance().getString(ServicePanel.STRING_FRAME_TAB_JOBS), jobsPanel);
panel.add(tabbedPane);
tabbedPane.addChangeListener(new ChangeListener() {
public void stateChanged(final ChangeEvent e) {
if (tabbedPane.getSelectedIndex() == 0) {
if (clipTable.getSelectedRowCount() == 1) {
profileModel.clear();
updateButtons();
final int clipId = clipModel.getClip(clipTable.convertRowIndexToModel(clipTable.getSelectedRow())).getClipId();
service.execute(new ServiceCallback<RenderClipDataRow>() {
public void executed(final RenderClipDataRow profile) {
profileModel.reload(clipId);
try {
final TwisterClipXMLImporter importer = new TwisterClipXMLImporter();
final InputStream is = service.getLibraryService().getClipInputStream(clipId);
final Document doc = XML.loadDocument(is, "twister-clip.xml");
is.close();
final TwisterClip clip = importer.importFromElement(doc.getDocumentElement());
try {
preview.acquire();
preview.stopRenderers();
preview.stop();
preview.start(clip);
preview.startRenderers();
preview.setArea(null);
preview.release();
preview.refresh();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
catch (final Exception x) {
ServicePanel.logger.log(Level.WARNING, "Can't load the clip " + clipId, x);
x.printStackTrace();
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.loadClip"), TwisterSwingResources.getInstance().getString("label.loadClip"), JOptionPane.ERROR_MESSAGE);
}
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't get the clip " + clipId);
throwable.printStackTrace();
}
public RenderClipDataRow execute(final LibraryService service) throws Exception {
return service.getClip(clipId);
}
});
}
else {
profileModel.clear();
updateButtons();
}
}
else {
try {
preview.acquire();
preview.stopRenderers();
preview.stop();
preview.setArea(null);
preview.release();
preview.refresh();
}
catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
});
clipTable.getSelectionModel().addListSelectionListener(new ClipListSelectionListener());
profileTable.getSelectionModel().addListSelectionListener(new ProfileListSelectionListener());
this.clipModel = clipModel;
this.profileModel = profileModel;
this.jobModel = jobModel;
this.service = service;
previewListener = new PreviewListener() {
public void updated(final int clipId) {
clipTable.repaint();
}
};
service.addPreviewListener(previewListener);
extensionComboBox.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
service.setJobServiceReference(((ConfigurableExtension<SpoolExtensionRuntime<?>, SpoolExtensionConfig>) ((ConfigurableExtensionComboBoxModel) extensionComboBox.getModel()).getSelectedItem()).getExtensionReference());
resumeSpool();
}
});
tableListener = new TableListener();
profileModel.addTableModelListener(tableListener);
clipModel.addTableModelListener(tableListener);
jobModel.addTableModelListener(tableListener);
resumeSpool();
refreshTask = new RefreshTask();
refreshTask.start();
}
private void resumeSpool() {
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
jobModel.reload();
}
public void failed(final Throwable throwable) {
}
public Object execute(final LibraryService service) throws Exception {
service.resumeJobs();
return null;
}
});
}
public void dispose() {
profileModel.removeTableModelListener(tableListener);
clipModel.removeTableModelListener(tableListener);
jobModel.removeTableModelListener(tableListener);
service.removeJobServiceListener(listener);
}
/**
* @return
*/
public boolean isStarted() {
return preview.isStarted();
}
/**
* @throws ExtensionException
*/
public void start() throws ExtensionException {
if (clipTable.getSelectedRowCount() > 0) {
profileModel.clear();
updateButtons();
}
else {
if (clipTable.getRowCount() > 0) {
clipTable.getSelectionModel().setSelectionInterval(0, 0);
}
profileModel.clear();
updateButtons();
}
service.addPreviewListener(previewListener);
preview.start();
refreshTask.start();
}
/**
*
*/
public void stop() {
refreshTask.stop();
preview.stop();
service.removePreviewListener(previewListener);
}
private void updateButtons() {
clipCreateButton.setEnabled(true);
clipDeleteButton.setEnabled((clipTable.getSelectedRowCount() > 0) && clipStatusEquals(0));
clipModifyButton.setEnabled((clipTable.getSelectedRowCount() == 1) && clipStatusEquals(0));
clipImportButton.setEnabled((clipTable.getSelectedRowCount() == 1) && clipStatusEquals(0));
clipExportButton.setEnabled(clipTable.getSelectedRowCount() > 0);
clipOpenButton.setEnabled(clipTable.getSelectedRowCount() == 1);
profileCreateButton.setEnabled(clipTable.getSelectedRowCount() == 1);
profileDeleteButton.setEnabled((clipTable.getSelectedRowCount() == 1) && (profileTable.getSelectedRowCount() > 0) && profileStatusEquals(0));
profileModifyButton.setEnabled((clipTable.getSelectedRowCount() == 1) && (profileTable.getSelectedRowCount() == 1) && profileStatusEquals(0));
profileRenderButton.setEnabled((clipTable.getSelectedRowCount() == 1) && (profileTable.getSelectedRowCount() > 0) && profileStatusEquals(0));
profileCleanButton.setEnabled((clipTable.getSelectedRowCount() == 1) && (profileTable.getSelectedRowCount() > 0) && profileStatusEquals(0));
profileAbortButton.setEnabled((clipTable.getSelectedRowCount() == 1) && (profileTable.getSelectedRowCount() > 0) && profileStatusNotEquals(0));
profileStartButton.setEnabled((clipTable.getSelectedRowCount() == 1) && (profileTable.getSelectedRowCount() > 0) && profileStatusNotEquals(0));
profileStopButton.setEnabled((clipTable.getSelectedRowCount() == 1) && (profileTable.getSelectedRowCount() > 0) && profileStatusNotEquals(0));
if (profileTable.getSelectedRowCount() == 1) {
final RenderProfileDataRow profile = profileModel.getProfile(profileTable.convertRowIndexToModel(profileTable.getSelectedRow()));
final boolean busy = (profile.getStatus() == 0) && (profile.getJobCreated() == profile.getJobStored()) && (profile.getJobStored() > 0);
profileExportButton.setEnabled((clipTable.getSelectedRowCount() == 1) && (profileTable.getSelectedRowCount() == 1) && busy);
}
else {
profileExportButton.setEnabled(false);
}
final boolean idle = (processServiceStatus == JobServiceListener.STATUS_IDLE) && (copyProcessServiceStatus == JobServiceListener.STATUS_IDLE) && (postProcessServiceStatus == JobServiceListener.STATUS_IDLE);
changeWorkspaceButton.setEnabled(idle);
extensionComboBox.setEnabled(idle);
}
private boolean clipStatusEquals(final int status) {
if (clipTable.getSelectedRowCount() == 0) {
return false;
}
final int[] rows = clipTable.getSelectedRows();
for (int i = 0; i < rows.length; i++) {
if (clipModel.getClip(clipTable.convertRowIndexToModel(rows[i])).getStatus() != status) {
return false;
}
}
return true;
}
private boolean profileStatusEquals(final int status) {
if (profileTable.getSelectedRowCount() == 0) {
return false;
}
final int[] rows = profileTable.getSelectedRows();
for (int i = 0; i < rows.length; i++) {
if (profileModel.getProfile(profileTable.convertRowIndexToModel(rows[i])).getStatus() != status) {
return false;
}
}
return true;
}
private boolean profileStatusNotEquals(final int status) {
if (profileTable.getSelectedRowCount() == 0) {
return false;
}
final int[] rows = profileTable.getSelectedRows();
for (int i = 0; i < rows.length; i++) {
if (profileModel.getProfile(profileTable.convertRowIndexToModel(rows[i])).getStatus() == status) {
return false;
}
}
return true;
}
private RenderClipDataRow createDefaultRenderClip() {
final RenderClipDataRow clip = new RenderClipDataRow(new RenderClip());
clip.setClipName("New Clip");
clip.setDescription("Default Configuration");
return clip;
}
private RenderProfileDataRow createDefaultRenderProfile(final int clipId) {
final RenderProfileDataRow profile = new RenderProfileDataRow(new RenderProfile());
profile.setClipId(clipId);
profile.setProfileName("New Profile");
profile.setImageWidth(640);
profile.setImageHeight(480);
profile.setQuality(100);
return profile;
}
private void showEditClipWindow(final RenderClipDataRow clip) {
final EditClipDialog editClipDialog = new EditClipDialog(service, clip);
GUIUtil.centerWindow(editClipDialog, ServicePanel.this.getLocationOnScreen(), ServicePanel.this.getBounds());
editClipDialog.setVisible(true);
}
private void showEditProfileWindow(final RenderProfileDataRow profile) {
final EditProfileDialog editProfileDialog = new EditProfileDialog(service, profile);
GUIUtil.centerWindow(editProfileDialog, ServicePanel.this.getLocationOnScreen(), ServicePanel.this.getBounds());
editProfileDialog.setVisible(true);
}
private class RefreshTask implements Runnable {
private final Object lock = new Object();
private Thread refreshThread;
private boolean running;
private boolean dirty;
/**
* @see java.lang.Runnable#run()
*/
public void run() {
try {
for (;;) {
synchronized (lock) {
if (!running) {
break;
}
while (!dirty) {
lock.wait();
}
dirty = false;
}
Thread.sleep(500);
GUIUtil.executeTask(new Runnable() {
public void run() {
int[] selectedRows = clipTable.getSelectedRows();
if ((selectedRows != null) && (selectedRows.length > 0)) {
final int clipId = clipModel.getClip(clipTable.convertRowIndexToModel(selectedRows[selectedRows.length - 1])).getClipId();
service.execute(new ServiceCallback<RenderClipDataRow>() {
public void executed(final RenderClipDataRow profile) {
profileModel.reload(clipId);
try {
final TwisterClipXMLImporter importer = new TwisterClipXMLImporter();
final InputStream is = service.getLibraryService().getClipInputStream(clipId);
final Document doc = XML.loadDocument(is, "twister-clip.xml");
is.close();
final TwisterClip clip = importer.importFromElement(doc.getDocumentElement());
try {
preview.acquire();
preview.stopRenderers();
preview.stop();
preview.start(clip);
preview.startRenderers();
preview.setArea(null);
preview.release();
preview.refresh();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
catch (final Exception x) {
ServicePanel.logger.log(Level.WARNING, "Can't load the clip " + clipId, x);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.loadClip"), TwisterSwingResources.getInstance().getString("label.loadClip"), JOptionPane.ERROR_MESSAGE);
}
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't get the clip " + clipId);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.loadClip"), TwisterSwingResources.getInstance().getString("label.loadClip"), JOptionPane.ERROR_MESSAGE);
}
public RenderClipDataRow execute(final LibraryService service) throws Exception {
return service.getClip(clipId);
}
});
}
else {
try {
preview.acquire();
preview.stopRenderers();
preview.stop();
preview.setArea(null);
preview.release();
preview.refresh();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
updateButtons();
}
}, false);
}
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public void start() {
if (refreshThread == null) {
refreshThread = new Thread(this, "Refresh Thread");
refreshThread.setPriority(Thread.NORM_PRIORITY);
refreshThread.setDaemon(true);
running = true;
refreshThread.start();
}
}
public void stop() {
if (refreshThread != null) {
running = false;
refreshThread.interrupt();
try {
refreshThread.join();
}
catch (InterruptedException e) {
}
refreshThread = null;
}
}
public void wakeup() {
synchronized (lock) {
dirty = true;
lock.notify();
}
}
}
private class ClipListSelectionListener implements ListSelectionListener {
public void valueChanged(final ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
refreshTask.wakeup();
}
}
}
private class ProfileListSelectionListener implements ListSelectionListener {
public void valueChanged(final ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
if (profileTable.getSelectedRowCount() > 0) {
final int profileId = profileModel.getProfile(profileTable.convertRowIndexToModel(profileTable.getSelectedRow())).getProfileId();
service.execute(new ServiceCallback<RenderProfileDataRow>() {
public void executed(final RenderProfileDataRow profile) {
preview.setArea(new Rectangle(profile.getOffsetX(), profile.getOffsetY(), profile.getImageWidth(), profile.getImageHeight()));
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't load the profile " + profileId);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.loadProfile"), TwisterSwingResources.getInstance().getString("label.loadProfile"), JOptionPane.ERROR_MESSAGE);
}
public RenderProfileDataRow execute(final LibraryService service) throws Exception {
return service.getProfile(profileId);
}
});
}
updateButtons();
}
}
}
private class ClipOpenAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ClipOpenAction() {
super(TwisterSwingResources.getInstance().getString("action.open"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (clipTable.getSelectedRowCount() == 1) {
final int row = clipTable.getSelectedRow();
final RenderClipDataRow clip = clipModel.getClip(clipTable.convertRowIndexToModel(row));
service.execute(new ServiceCallback<RenderClipDataRow>() {
public void executed(final RenderClipDataRow value) {
try {
final InputStream is = service.getLibraryService().getClipInputStream(clip.getClipId());
final Document doc = XML.loadDocument(is, "twister-clip.xml");
final TwisterClipXMLImporter importer = new TwisterClipXMLImporter();
final TwisterClip clip = importer.importFromElement(doc.getDocumentElement());
is.close();
context.openClip(clip);
semaphore.release();
}
catch (final Exception x) {
ServicePanel.logger.log(Level.WARNING, "Can't load the clip", x);
semaphore.release();
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.loadClip"), TwisterSwingResources.getInstance().getString("label.openClip"), JOptionPane.ERROR_MESSAGE);
}
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't open the clip", throwable);
semaphore.release();
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.openClip"), TwisterSwingResources.getInstance().getString("label.openClip"), JOptionPane.ERROR_MESSAGE);
}
public RenderClipDataRow execute(final LibraryService service) throws Exception {
return service.getClip(clip.getClipId());
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
}
private class ClipCreateAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ClipCreateAction() {
super(TwisterSwingResources.getInstance().getString("action.create"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
final RenderClipDataRow dataRow = createDefaultRenderClip();
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't create the clip", throwable);
semaphore.release();
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.createClip"), TwisterSwingResources.getInstance().getString("label.createClip"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
final TwisterConfigBuilder configBuilder = new TwisterConfigBuilder();
final TwisterClip clip = new TwisterClip();
final TwisterSequence sequence = new TwisterSequence();
clip.addSequence(sequence);
final TwisterConfig config = configBuilder.createDefaultConfig();
sequence.setFinalConfig(config);
service.createClip(dataRow, clip);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
private class ClipDeleteAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ClipDeleteAction() {
super(TwisterSwingResources.getInstance().getString("action.delete"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (clipTable.getSelectedRowCount() > 0) {
if (JOptionPane.showConfirmDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.confirmDeleteClips"), TwisterSwingResources.getInstance().getString("label.deleteClips"), JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION) {
final WorkerProgressDialog dialog = new WorkerProgressDialog(new ClipDeleteWorker(), false);
GUIUtil.centerWindow(dialog, getLocationOnScreen(), ServicePanel.this.getBounds());
dialog.start();
updateButtons();
}
}
}
private class ClipDeleteWorker extends ExtendedGUIWorker {
/**
* @see net.sf.jame.core.swing.util.DefaultGUIWorker#doInBackground()
*/
@Override
public Object doInBackground() throws Exception {
final int[] rows = clipTable.getSelectedRows();
final RenderClipDataRow[] clips = new RenderClipDataRow[rows.length];
final boolean[] error = new boolean[] { false };
for (int i = 0; i < rows.length; i++) {
clips[i] = clipModel.getClip(clipTable.convertRowIndexToModel(rows[i]));
}
for (int i = 0; i < rows.length; i++) {
final int percentage = (int) Math.rint((((float) i) / (rows.length - 1)) * 100f);
final RenderClipDataRow clip = clips[i];
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't delete the clip", throwable);
error[0] = true;
semaphore.release();
failed(throwable);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.deleteClip"), TwisterSwingResources.getInstance().getString("label.deleteClip"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
stateChanged(TwisterSwingResources.getInstance().getString("message.deletingClip") + " " + clip.getClipId() + "...", percentage);
service.deleteClip(clip);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
if (error[0]) {
break;
}
}
clipTable.clearSelection();
return null;
}
}
}
private class ClipModifyAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ClipModifyAction() {
super(TwisterSwingResources.getInstance().getString("action.modify"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (clipTable.getSelectedRowCount() == 1) {
final int row = clipTable.getSelectedRow();
final RenderClipDataRow clip = clipModel.getClip(clipTable.convertRowIndexToModel(row));
service.execute(new ServiceCallback<RenderClipDataRow>() {
public void executed(final RenderClipDataRow clip) {
GUIUtil.executeTask(new Runnable() {
public void run() {
showEditClipWindow(clip);
}
}, true);
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't get the clip " + clip.getClipId(), throwable);
semaphore.release();
}
public RenderClipDataRow execute(final LibraryService service) throws Exception {
return service.getClip(clip.getClipId());
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
}
private class ClipImportAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ClipImportAction() {
super(TwisterSwingResources.getInstance().getString("action.importClip"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (clipTable.getSelectedRowCount() > 0) {
if (JOptionPane.showConfirmDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.confirmImportClips"), TwisterSwingResources.getInstance().getString("label.importClips"), JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION) {
final int[] rows = clipTable.getSelectedRows();
final boolean[] error = new boolean[] { false };
for (final int row : rows) {
final RenderClipDataRow clip = clipModel.getClip(clipTable.convertRowIndexToModel(row));
clipChooser.setDialogTitle(TwisterSwingResources.getInstance().getString("label.importClip"));
final int returnVal = clipChooser.showOpenDialog(ServicePanel.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
final File file = clipChooser.getSelectedFile();
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't import the clip", throwable);
error[0] = true;
semaphore.release();
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.importClip"), TwisterSwingResources.getInstance().getString("label.importClip"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
service.importClip(clip, file);
service.resetProfiles(clip.getClipId());
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
if (error[0]) {
break;
}
}
}
}
if (clipTable.getSelectedRowCount() > 0) {
profileModel.clear();
updateButtons();
final int clipId = clipModel.getClip(clipTable.convertRowIndexToModel(clipTable.getSelectedRow())).getClipId();
service.execute(new ServiceCallback<RenderClipDataRow>() {
public void executed(final RenderClipDataRow profile) {
profileModel.reload(clipId);
try {
final TwisterClipXMLImporter importer = new TwisterClipXMLImporter();
final InputStream is = service.getLibraryService().getClipInputStream(clipId);
final Document doc = XML.loadDocument(is, "twister-clip.xml");
is.close();
final TwisterClip clip = importer.importFromElement(doc.getDocumentElement());
try {
preview.acquire();
preview.stopRenderers();
preview.stop();
preview.start(clip);
preview.startRenderers();
preview.setArea(null);
preview.release();
preview.refresh();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
catch (final Exception x) {
ServicePanel.logger.log(Level.WARNING, "Can't load the clip " + clipId, x);
x.printStackTrace();
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.loadClip"), TwisterSwingResources.getInstance().getString("label.loadClip"), JOptionPane.ERROR_MESSAGE);
}
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't get the clip " + clipId);
throwable.printStackTrace();
}
public RenderClipDataRow execute(final LibraryService service) throws Exception {
return service.getClip(clipId);
}
});
}
else {
profileModel.clear();
updateButtons();
}
}
}
private class ClipExportAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ClipExportAction() {
super(TwisterSwingResources.getInstance().getString("action.exportClip"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (clipTable.getSelectedRowCount() > 0) {
final int[] rows = clipTable.getSelectedRows();
final boolean[] error = new boolean[] { false };
for (final int row : rows) {
clipChooser.setDialogTitle(TwisterSwingResources.getInstance().getString("label.exportClip"));
final int returnVal = clipChooser.showSaveDialog(ServicePanel.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
final File file = clipChooser.getSelectedFile();
if (file.exists()) {
if (JOptionPane.showConfirmDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.confirmOverwrite"), TwisterSwingResources.getInstance().getString("label.exportClips"), JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION) {
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't export the clip", throwable);
error[0] = true;
semaphore.release();
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.exportClip"), TwisterSwingResources.getInstance().getString("label.exportClip"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
service.exportClip(clipModel.getClip(clipTable.convertRowIndexToModel(row)), file);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
else {
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't export the clip", throwable);
error[0] = true;
semaphore.release();
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.exportClip"), TwisterSwingResources.getInstance().getString("label.exportClip"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
service.exportClip(clipModel.getClip(clipTable.convertRowIndexToModel(row)), file);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
if (error[0]) {
break;
}
}
}
}
}
private class ProfileCreateAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ProfileCreateAction() {
super(TwisterSwingResources.getInstance().getString("action.create"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (clipTable.getSelectedRowCount() == 1) {
final int clipId = clipModel.getClip(clipTable.convertRowIndexToModel(clipTable.getSelectedRow())).getClipId();
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't create the profile", throwable);
semaphore.release();
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.createProfile"), TwisterSwingResources.getInstance().getString("label.createProfile"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
service.createProfile(createDefaultRenderProfile(clipId));
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
}
private class ProfileDeleteAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ProfileDeleteAction() {
super(TwisterSwingResources.getInstance().getString("action.delete"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (profileTable.getSelectedRowCount() > 0) {
if (JOptionPane.showConfirmDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.confirmDeleteProfiles"), TwisterSwingResources.getInstance().getString("label.deleteProfiles"), JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION) {
final WorkerProgressDialog dialog = new WorkerProgressDialog(new ProfileDeleteWorker(), false);
GUIUtil.centerWindow(dialog, getLocationOnScreen(), ServicePanel.this.getBounds());
dialog.start();
updateButtons();
}
}
}
private class ProfileDeleteWorker extends ExtendedGUIWorker {
/**
* @see net.sf.jame.core.swing.util.DefaultGUIWorker#doInBackground()
*/
@Override
public Object doInBackground() throws Exception {
final int[] rows = profileTable.getSelectedRows();
final boolean[] error = new boolean[] { false };
final RenderProfileDataRow[] profiles = new RenderProfileDataRow[rows.length];
for (int i = 0; i < rows.length; i++) {
profiles[i] = profileModel.getProfile(profileTable.convertRowIndexToModel(rows[i]));
}
for (int i = 0; i < rows.length; i++) {
final int percentage = (int) Math.rint((((float) i) / (rows.length - 1)) * 100f);
final RenderProfileDataRow profile = profiles[i];
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't delete the profile", throwable);
error[0] = true;
semaphore.release();
failed(throwable);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.deleteProfile"), TwisterSwingResources.getInstance().getString("label.deleteProfile"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
stateChanged(TwisterSwingResources.getInstance().getString("message.deletingProfile") + " " + profile.getProfileId() + "...", percentage);
service.deleteProfile(profile);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
if (error[0]) {
break;
}
profileTable.clearSelection();
}
return null;
}
}
}
private class ProfileModifyAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ProfileModifyAction() {
super(TwisterSwingResources.getInstance().getString("action.modify"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (profileTable.getSelectedRowCount() == 1) {
final int row = profileTable.getSelectedRow();
final RenderProfileDataRow profile = profileModel.getProfile(profileTable.convertRowIndexToModel(row));
service.execute(new ServiceCallback<RenderProfileDataRow>() {
public void executed(final RenderProfileDataRow profile) {
GUIUtil.executeTask(new Runnable() {
public void run() {
showEditProfileWindow(profile);
updateButtons();
service.execute(new ServiceCallback<RenderProfileDataRow>() {
public RenderProfileDataRow execute(final LibraryService service) throws Exception {
RenderProfileDataRow profileDataRow = service.getProfile(profile.getProfileId());
preview.setArea(new Rectangle(profileDataRow.getOffsetX(), profileDataRow.getOffsetY(), profileDataRow.getImageWidth(), profileDataRow.getImageHeight()));
return null;
}
public void executed(final RenderProfileDataRow value) {
}
public void failed(final Throwable throwable) {
}
});
}
}, true);
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't get the profile " + profile.getProfileId(), throwable);
semaphore.release();
}
public RenderProfileDataRow execute(final LibraryService service) throws Exception {
return service.getProfile(profile.getProfileId());
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
}
private class ProfileRenderAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ProfileRenderAction() {
super(TwisterSwingResources.getInstance().getString("action.render"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (profileTable.getSelectedRowCount() > 0) {
if (JOptionPane.showConfirmDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.confirmRenderProfiles"), TwisterSwingResources.getInstance().getString("label.renderProfiles"), JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION) {
final WorkerProgressDialog dialog = new WorkerProgressDialog(new ProfileRenderWorker(), false);
GUIUtil.centerWindow(dialog, getLocationOnScreen(), ServicePanel.this.getBounds());
dialog.start();
updateButtons();
}
}
}
private class ProfileRenderWorker extends ExtendedGUIWorker {
/**
* @see net.sf.jame.core.swing.util.DefaultGUIWorker#doInBackground()
*/
@Override
public Object doInBackground() throws Exception {
final int[] rows = profileTable.getSelectedRows();
final boolean[] error = new boolean[] { false };
for (int i = 0; i < rows.length; i++) {
final int percentage = (int) Math.rint((((float) i) / (rows.length - 1)) * 100f);
final RenderProfileDataRow profile = profileModel.getProfile(profileTable.convertRowIndexToModel(rows[i]));
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't render the profile", throwable);
error[0] = true;
semaphore.release();
failed(throwable);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.deleteJobs"), TwisterSwingResources.getInstance().getString("label.renderProfile"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
service.deleteJobs(profile.getProfileId(), ProfileRenderWorker.this, TwisterSwingResources.getInstance().getString("message.deletingJobs") + " " + profile.getProfileId() + "...", percentage / 3f);
service.createJobs(profile.getProfileId(), ProfileRenderWorker.this, TwisterSwingResources.getInstance().getString("message.creatingJobs") + " " + profile.getProfileId() + "...", percentage / 3f);
service.startJobs(profile.getProfileId(), ProfileRenderWorker.this, TwisterSwingResources.getInstance().getString("message.startingJobs") + " " + profile.getProfileId() + "...", percentage / 3f);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
if (error[0]) {
break;
}
}
return null;
}
}
}
private class ProfileAbortAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ProfileAbortAction() {
super(TwisterSwingResources.getInstance().getString("action.abort"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (profileTable.getSelectedRowCount() > 0) {
if (JOptionPane.showConfirmDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.confirmAbortProfiles"), TwisterSwingResources.getInstance().getString("label.abortProfiles"), JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION) {
final WorkerProgressDialog dialog = new WorkerProgressDialog(new ProfileAbortWorker(), false);
GUIUtil.centerWindow(dialog, getLocationOnScreen(), ServicePanel.this.getBounds());
dialog.start();
updateButtons();
}
}
}
private class ProfileAbortWorker extends ExtendedGUIWorker {
/**
* @see net.sf.jame.core.swing.util.DefaultGUIWorker#doInBackground()
*/
@Override
public Object doInBackground() throws Exception {
final int[] rows = profileTable.getSelectedRows();
final boolean[] error = new boolean[] { false };
for (int i = 0; i < rows.length; i++) {
final int percentage = (int) Math.rint((((float) i) / (rows.length - 1)) * 100f);
final RenderProfileDataRow profile = profileModel.getProfile(profileTable.convertRowIndexToModel(rows[i]));
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't abort the profile", throwable);
error[0] = true;
semaphore.release();
failed(throwable);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.deleteJobs"), TwisterSwingResources.getInstance().getString("label.abortProfile"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
service.deleteJobs(profile.getProfileId(), ProfileAbortWorker.this, TwisterSwingResources.getInstance().getString("message.deletingJobs") + " " + profile.getProfileId() + "...", percentage);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
if (error[0]) {
break;
}
}
return null;
}
}
}
private class ProfileCleanAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ProfileCleanAction() {
super(TwisterSwingResources.getInstance().getString("action.clean"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (profileTable.getSelectedRowCount() > 0) {
if (JOptionPane.showConfirmDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.confirmCleanProfiles"), TwisterSwingResources.getInstance().getString("label.cleanProfiles"), JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION) {
final WorkerProgressDialog dialog = new WorkerProgressDialog(new ProfileCleanWorker(), false);
GUIUtil.centerWindow(dialog, getLocationOnScreen(), ServicePanel.this.getBounds());
dialog.start();
updateButtons();
}
}
}
private class ProfileCleanWorker extends ExtendedGUIWorker {
/**
* @see net.sf.jame.core.swing.util.DefaultGUIWorker#doInBackground()
*/
@Override
public Object doInBackground() throws Exception {
final int[] rows = profileTable.getSelectedRows();
final boolean[] error = new boolean[] { false };
for (int i = 0; i < rows.length; i++) {
final int percentage = (int) Math.rint((((float) i) / (rows.length - 1)) * 100f);
final RenderProfileDataRow profile = profileModel.getProfile(profileTable.convertRowIndexToModel(rows[i]));
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't clean the profile", throwable);
error[0] = true;
semaphore.release();
failed(throwable);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.cleanProfile"), TwisterSwingResources.getInstance().getString("label.cleanProfile"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
stateChanged(TwisterSwingResources.getInstance().getString("message.cleaningProfile") + " " + profile.getProfileId() + "...", percentage);
service.cleanProfile(profile);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
if (error[0]) {
break;
}
}
return null;
}
}
}
private class ProfileStartAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ProfileStartAction() {
super(TwisterSwingResources.getInstance().getString("action.start"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (profileTable.getSelectedRowCount() > 0) {
final WorkerProgressDialog dialog = new WorkerProgressDialog(new ProfileStartWorker(), false);
GUIUtil.centerWindow(dialog, getLocationOnScreen(), ServicePanel.this.getBounds());
dialog.start();
updateButtons();
}
}
}
private class ProfileStartWorker extends ExtendedGUIWorker {
/**
* @see net.sf.jame.core.swing.util.DefaultGUIWorker#doInBackground()
*/
@Override
public Object doInBackground() throws Exception {
final int[] rows = profileTable.getSelectedRows();
final boolean[] error = new boolean[] { false };
for (int i = 0; i < rows.length; i++) {
final int percentage = (int) Math.rint((((float) i) / (rows.length - 1)) * 100f);
final RenderProfileDataRow profile = profileModel.getProfile(profileTable.convertRowIndexToModel(rows[i]));
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't start the profile", throwable);
error[0] = true;
semaphore.release();
failed(throwable);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.startJobs"), TwisterSwingResources.getInstance().getString("label.startProfile"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
service.startJobs(profile.getProfileId(), ProfileStartWorker.this, TwisterSwingResources.getInstance().getString("message.startingJobs") + " " + profile.getProfileId() + "...", percentage);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
if (error[0]) {
break;
}
}
return null;
}
}
private class ProfileStopAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ProfileStopAction() {
super(TwisterSwingResources.getInstance().getString("action.stop"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (profileTable.getSelectedRowCount() > 0) {
if (JOptionPane.showConfirmDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.confirmStopProfiles"), TwisterSwingResources.getInstance().getString("label.stopProfiles"), JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION) {
final WorkerProgressDialog dialog = new WorkerProgressDialog(new ProfileStopWorker(), false);
GUIUtil.centerWindow(dialog, getLocationOnScreen(), ServicePanel.this.getBounds());
dialog.start();
updateButtons();
}
}
}
private class ProfileStopWorker extends ExtendedGUIWorker {
/**
* @see net.sf.jame.core.swing.util.DefaultGUIWorker#doInBackground()
*/
@Override
public Object doInBackground() throws Exception {
final int[] rows = profileTable.getSelectedRows();
final boolean[] error = new boolean[] { false };
for (int i = 0; i < rows.length; i++) {
final int percentage = (int) Math.rint((((float) i) / (rows.length - 1)) * 100f);
final RenderProfileDataRow profile = profileModel.getProfile(profileTable.convertRowIndexToModel(rows[i]));
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
ServicePanel.logger.log(Level.WARNING, "Can't stop the profile", throwable);
error[0] = true;
semaphore.release();
failed(throwable);
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.stopJobs"), TwisterSwingResources.getInstance().getString("label.stopProfile"), JOptionPane.ERROR_MESSAGE);
}
public Object execute(final LibraryService service) throws Exception {
service.stopJobs(profile.getProfileId(), ProfileStopWorker.this, TwisterSwingResources.getInstance().getString("message.stoppingJobs") + " " + profile.getProfileId() + "...", percentage);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
if (error[0]) {
break;
}
}
return null;
}
}
}
private class ProfileExportAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ProfileExportAction() {
super(TwisterSwingResources.getInstance().getString("action.export"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (profileTable.getSelectedRowCount() > 0) {
final int[] rows = profileTable.getSelectedRows();
encoderDialog.setModal(true);
for (final int row : rows) {
final RenderProfileDataRow profile = profileModel.getProfile(profileTable.convertRowIndexToModel(row));
GUIUtil.centerWindow(encoderDialog, getLocationOnScreen(), ServicePanel.this.getBounds());
encoderDialog.setProfile(profile);
encoderDialog.setVisible(true);
}
updateButtons();
}
}
}
private class CheckUpdateAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public CheckUpdateAction() {
super(TwisterSwingResources.getInstance().getString("action.checkUpdate"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
final WorkerProgressDialog dialog = new WorkerProgressDialog(TwisterSwingResources.getInstance().getString("action.checkUpdate"), new CheckUpdateWorker(), true);
GUIUtil.centerWindow(dialog, getLocationOnScreen(), ServicePanel.this.getBounds());
dialog.start();
}
private class CheckUpdateWorker extends ExtendedGUIWorker {
/**
* @see net.sf.jame.core.swing.util.DefaultGUIWorker#doInBackground()
*/
@Override
public Object doInBackground() throws Exception {
BufferedReader reader = null;
try {
stateChanged(TwisterSwingResources.getInstance().getString("message.downloadingReleases") + "...");
final URL url = new URL(TwisterSwingResources.getInstance().getString("url.releases"));
final URLConnection connection = url.openConnection();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String newRelease = null;
String release = null;
String line = null;
stateChanged(TwisterSwingResources.getInstance().getString("message.checkingReleases") + "...");
while ((line = reader.readLine()) != null) {
if (line.length() > 0) {
release = line;
if (release.equals(TwisterSwingResources.getInstance().getString("release"))) {
break;
}
}
}
while ((line = reader.readLine()) != null) {
if (line.length() > 0) {
release = line;
if (!release.equals(TwisterSwingResources.getInstance().getString("release"))) {
if (TwisterSwingResources.getInstance().getString("acceptRC").equals("true") || (release.indexOf("RC") == -1)) {
newRelease = release;
break;
}
}
}
}
if (newRelease != null) {
GUIUtil.executeTask(new Runnable() {
public void run() {
try {
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.newReleaseAvailable"), TwisterSwingResources.getInstance().getString("action.checkUpdate"), JOptionPane.PLAIN_MESSAGE);
ServiceDesktop.browse(new URI(TwisterSwingResources.getInstance().getString("url.download")));
}
catch (Exception e) {
e.printStackTrace();
}
}
}, false);
}
else {
GUIUtil.executeTask(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("message.newReleaseNotAvailable"), TwisterSwingResources.getInstance().getString("action.checkUpdate"), JOptionPane.PLAIN_MESSAGE);
}
}, false);
}
}
catch (final Exception x) {
GUIUtil.executeTask(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(ServicePanel.this, TwisterSwingResources.getInstance().getString("error.checkUpdate"), TwisterSwingResources.getInstance().getString("action.checkUpdate"), JOptionPane.WARNING_MESSAGE);
}
}, false);
}
finally {
if (reader != null) {
try {
reader.close();
}
catch (final IOException x) {
}
}
}
return null;
}
}
}
private class ShowAboutAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ShowAboutAction() {
super(TwisterSwingResources.getInstance().getString("action.showAbout"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/about.txt")));
String line = null;
final StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append("\n");
}
builder.append("\nProgram version = ");
builder.append(TwisterSwingResources.getInstance().getString("release"));
builder.append("\nJava version = ");
builder.append(System.getProperty("java.version"));
builder.append("\nJava vendor = ");
builder.append(System.getProperty("java.vendor"));
builder.append("\nOS = ");
builder.append(System.getProperty("os.name"));
builder.append(" ");
builder.append(System.getProperty("os.version"));
builder.append(" (");
builder.append(System.getProperty("os.arch"));
builder.append(")");
builder.append("\nAvailable processors = ");
builder.append(Runtime.getRuntime().availableProcessors());
builder.append("\nUsed memory = ");
builder.append(Runtime.getRuntime().totalMemory() / 1024);
builder.append("kb");
builder.append("\nFree memory = ");
builder.append(Runtime.getRuntime().freeMemory() / 1024);
builder.append("kb");
JOptionPane.showMessageDialog(ServicePanel.this, builder.toString(), TwisterSwingResources.getInstance().getString("label.about"), JOptionPane.PLAIN_MESSAGE);
}
catch (final Exception x) {
x.printStackTrace();
}
finally {
if (reader != null) {
try {
reader.close();
}
catch (final IOException x) {
}
}
}
}
}
private class ChangeWorkspaceAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
*
*/
public ChangeWorkspaceAction() {
super(TwisterSwingResources.getInstance().getString("action.changeWorkspace"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
final Properties properties = new Properties();
File workspace = null;
try {
properties.load(new FileInputStream(System.getProperty("user.home") + "/JAME.properties"));
if (properties.get("workspace") == null) {
workspace = new File(System.getProperty("user.home") + "/" + System.getProperty("jame.workspace", "JAME-workspace"));
} else {
workspace = new File((String) properties.get("workspace"));
}
}
catch (final Exception x) {
x.printStackTrace();
}
fileChooser.setCurrentDirectory(workspace);
final int returnVal = fileChooser.showSaveDialog(new JFrame());
if (returnVal == JFileChooser.APPROVE_OPTION) {
workspace = fileChooser.getSelectedFile().getAbsoluteFile().getAbsoluteFile();
if (workspace != null) {
properties.put("workspace", workspace.getAbsolutePath());
try {
properties.store(new FileOutputStream(System.getProperty("user.home") + "/JAME.properties"), null);
context.restart();
}
catch (final Exception x) {
x.printStackTrace();
}
}
}
}
}
// private class DefaultServiceListener extends ServiceAdapter {
// /**
// * @see net.sf.jame.service.swing.ServiceAdapter#clipCreated(net.sf.jame.service.clip.RenderClipDataRow)
// */
// @Override
// public void clipCreated(final RenderClipDataRow clip) {
// }
//
// /**
// * @see net.sf.jame.service.swing.ServiceAdapter#clipDeleted(net.sf.jame.service.clip.RenderClipDataRow)
// */
// @Override
// public void clipDeleted(final RenderClipDataRow clip) {
// }
//
// /**
// * @see net.sf.jame.service.swing.ServiceAdapter#clipUpdated(net.sf.jame.service.clip.RenderClipDataRow)
// */
// @Override
// public void clipUpdated(final RenderClipDataRow clip) {
// }
//
// /**
// * @see net.sf.jame.service.swing.ServiceAdapter#profileCreated(net.sf.jame.service.profile.RenderProfileDataRow)
// */
// @Override
// public void profileCreated(final RenderProfileDataRow profile) {
// }
//
// /**
// * @see net.sf.jame.service.swing.ServiceAdapter#profileDeleted(net.sf.jame.service.profile.RenderProfileDataRow)
// */
// @Override
// public void profileDeleted(final RenderProfileDataRow profile) {
// }
//
// /**
// * @see net.sf.jame.service.swing.ServiceAdapter#profileUpdated(net.sf.jame.service.profile.RenderProfileDataRow)
// */
// @Override
// public void profileUpdated(final RenderProfileDataRow profile) {
// }
// }
private class TableListener implements TableModelListener {
private final String jobLabelText = TwisterSwingResources.getInstance().getString("label.jobPanel");
private final String clipLabelText = TwisterSwingResources.getInstance().getString("label.clipPanel");
private final String profileLabelText = TwisterSwingResources.getInstance().getString("label.profilePanel");
private final String elementText = TwisterSwingResources.getInstance().getString("label.element");
private final String elementsText = TwisterSwingResources.getInstance().getString("label.elements");
/**
* @see javax.swing.event.TableModelListener#tableChanged(javax.swing.event.TableModelEvent)
*/
public void tableChanged(final TableModelEvent e) {
jobLabel.setText(jobLabelText + " (" + jobTable.getRowCount() + " " + (jobTable.getRowCount() == 1 ? elementText : elementsText) + ")");
clipLabel.setText(clipLabelText + " (" + clipTable.getRowCount() + " " + (clipTable.getRowCount() == 1 ? elementText : elementsText) + ")");
profileLabel.setText(profileLabelText + " (" + profileTable.getRowCount() + " " + (profileTable.getRowCount() == 1 ? elementText : elementsText) + ")");
updateButtons();
}
}
private class ImageRenderer extends JComponent implements TableCellRenderer {
private static final long serialVersionUID = 1L;
private Image image;
/**
*
*/
public ImageRenderer() {
setPreferredSize(new Dimension(20, 20));
setMinimumSize(new Dimension(20, 20));
setMaximumSize(new Dimension(40, 40));
}
/**
* @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
*/
public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
// if (row % 2 == 0) {
// if (isSelected) {
// setBackground(table.getSelectionBackground().darker());
// }
// else {
// setBackground(table.getBackground().darker());
// }
// }
// else {
// if (isSelected) {
// setBackground(table.getSelectionBackground());
// }
// else {
// setBackground(table.getBackground());
// }
// }
if (isSelected) {
setBackground(table.getSelectionBackground());
}
else {
setBackground(table.getBackground());
}
if (value instanceof Image) {
image = (Image) value;
}
else {
image = null;
}
return this;
}
/**
* @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
*/
@Override
protected void paintComponent(final Graphics g) {
final int x = getWidth() / 2 - 10;
final int y = getHeight() / 2 - 10;
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
if (image != null) {
g.drawImage(image, x, y, null);
}
g.setColor(Color.DARK_GRAY);
g.drawRect(x, y, 19, 19);
}
}
}
}