/*
* 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.Dimension;
import java.awt.DisplayMode;
import java.awt.FlowLayout;
import java.awt.GraphicsDevice;
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.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.DefaultSingleSelectionModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.sf.jame.core.DefaultTree;
import net.sf.jame.core.config.DefaultConfigContext;
import net.sf.jame.core.extension.ExtensionException;
import net.sf.jame.core.scripting.DefaultJSContext;
import net.sf.jame.core.scripting.JSManager;
import net.sf.jame.core.swing.IconButton;
import net.sf.jame.core.swing.NavigatorFrame;
import net.sf.jame.core.swing.util.GUIFactory;
import net.sf.jame.core.swing.util.GUIUtil;
import net.sf.jame.core.swing.util.JSFileFilter;
import net.sf.jame.core.tree.DefaultNodeSession;
import net.sf.jame.core.tree.NodeAction;
import net.sf.jame.core.tree.NodeActionValue;
import net.sf.jame.queue.LibraryService;
import net.sf.jame.queue.RenderService;
import net.sf.jame.queue.RenderService.ServiceCallback;
import net.sf.jame.queue.clip.RenderClip;
import net.sf.jame.queue.clip.RenderClipDataRow;
import net.sf.jame.twister.TwisterBookmark;
import net.sf.jame.twister.TwisterClip;
import net.sf.jame.twister.TwisterClipController;
import net.sf.jame.twister.TwisterConfig;
import net.sf.jame.twister.TwisterConfigBuilder;
import net.sf.jame.twister.TwisterConfigNodeBuilder;
import net.sf.jame.twister.TwisterRuntime;
import net.sf.jame.twister.TwisterSequence;
import net.sf.jame.twister.TwisterSessionController;
import net.sf.jame.twister.renderer.DefaultTwisterRenderer;
import net.sf.jame.twister.renderer.TwisterRenderingHints;
/**
* @author Andrea Medeghini
*/
public class TwisterFrame extends JFrame {
private static final long serialVersionUID = 1L;
private static final String TWISTER_FRAME_TITLE = "twisterFrame.title";
private static final String TWISTER_FRAME_WIDTH = "twisterFrame.width";
private static final String TWISTER_FRAME_HEIGHT = "twisterFrame.height";
private static final String TWISTER_FRAME_ICON = "twisterFrame.icon";
private static final Logger logger = Logger.getLogger(TwisterFrame.class.getName());
private final Semaphore semaphore = new Semaphore(0, true);
private final TwisterSessionController sessionController;
private final DefaultSingleSelectionModel model;
private final DefaultTree twisterTree;
private final RenderService service;
private OutputFrame outputFrame;
private ConfigFrame configFrame;
private NavigatorFrame advancedConfigFrame;
private static ServiceFrame serviceFrame;
private final TwisterConfig config;
private final TwisterCanvas canvas;
private TwisterClip clip;
private TwisterClip tmpClip;
private TwisterClip playClip;
private DefaultTree tree;
private Thread scriptThread;
private long clipDuration;
private long sequenceStopTime;
private long sequenceStartTime;
private TwisterSequence sequence;
private final TwisterPanel panel;
private final TwisterContext context;
private final RenderProfileTableModel renderProfileTableModel;
private final RenderJobTableModel renderJobTableModel;
private final RenderClipTableModel renderClipTableModel;
private final DefaulServiceContext serviceContext;
/**
* @param context
* @param service
* @param config
* @param hcells
* @param vcells
* @throws HeadlessException
* @throws ExtensionException
*/
public TwisterFrame(final TwisterContext context, final RenderService service, final TwisterConfig config, final int hcells, final int vcells) throws HeadlessException, ExtensionException {
this.context = context;
final int defaultWidth = Integer.parseInt(TwisterSwingResources.getInstance().getString(TwisterFrame.TWISTER_FRAME_WIDTH));
final int defaultHeight = Integer.parseInt(TwisterSwingResources.getInstance().getString(TwisterFrame.TWISTER_FRAME_HEIGHT));
final int width = Integer.getInteger(TwisterFrame.TWISTER_FRAME_WIDTH, defaultWidth);
final int height = Integer.getInteger(TwisterFrame.TWISTER_FRAME_HEIGHT, defaultHeight);
model = new DefaultSingleSelectionModel();
canvas = new TwisterCanvas(hcells, vcells, model);
panel = new TwisterPanel(canvas);
getContentPane().add(panel);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setTitle(TwisterSwingResources.getInstance().getString(TwisterFrame.TWISTER_FRAME_TITLE));
final URL resource = TwisterFrame.class.getClassLoader().getResource(TwisterSwingResources.getInstance().getString(TwisterFrame.TWISTER_FRAME_ICON));
if (resource != null) {
setIconImage(getToolkit().createImage(resource));
}
this.setSize(new Dimension(width, height));
final Point p = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
p.x -= getWidth() / 2;
p.y -= getHeight() / 2;
this.setLocation(p);
this.service = service;
this.config = config;
sessionController = new TwisterSessionController("options", config);
sessionController.init();
sessionController.setRenderContext(canvas);
twisterTree = new DefaultTree();
final TwisterConfigNodeBuilder nodeBuilder = new TwisterConfigNodeBuilder(config);
twisterTree.getRootNode().setContext(config.getContext());
twisterTree.getRootNode().setSession(sessionController);
nodeBuilder.createNodes(twisterTree.getRootNode());
addWindowListener(new TwisterWindowListener(canvas));
setBackground(new Color(0x2f2f2f));
canvas.setShowBookmarkIcons(true);
canvas.addChangeListener(new ChangeListener() {
public void stateChanged(final ChangeEvent e) {
if (panel.isScriptState()) {
if (scriptThread != null) {
scriptThread.interrupt();
}
}
else if (panel.isEditState()) {
clip = canvas.getClip();
tmpClip = canvas.getClip();
sequence = null;
tree = null;
panel.updateButtons();
}
else if (panel.isPlayState()) {
clip = canvas.getClip();
tmpClip = canvas.getClip();
playClip = tmpClip;
sequence = null;
tree = null;
panel.updateButtons();
}
}
});
context.addFrame(this);
renderProfileTableModel = new RenderProfileTableModel(service);
renderJobTableModel = new RenderJobTableModel(service);
renderClipTableModel = new RenderClipTableModel(service);
serviceContext = new DefaulServiceContext(context, service, hcells, vcells);
}
/**
* @see java.lang.Object#finalize()
*/
@Override
protected void finalize() throws Throwable {
TwisterFrame.logger.fine("Frame finalized");
super.finalize();
}
/**
* @param clip
*/
public void loadClip(final TwisterClip clip) {
try {
if (clip != null) {
final TwisterClipController controller = new TwisterClipController(clip);
controller.init();
if (controller.getDuration() > 0) {
canvas.acquire();
canvas.stopRenderers();
canvas.stop();
this.clip = clip;
tmpClip = clip;
playClip = tmpClip;
sequence = null;
tree = null;
canvas.start(clip);
canvas.startRenderers();
canvas.release();
canvas.refresh();
}
else {
canvas.acquire();
canvas.stopRenderers();
sequence = null;
tree = null;
config.setFrameConfigElement(controller.getConfig().getFrameConfigElement().clone());
config.setEffectConfigElement(controller.getConfig().getEffectConfigElement().clone());
config.setBackground(controller.getConfig().getBackground());
canvas.startRenderers();
canvas.release();
canvas.refresh();
}
}
panel.updateButtons();
}
catch (final HeadlessException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private void openLogWindow() {
GUIUtil.executeTask(new Runnable() {
public void run() {
if (outputFrame == null) {
outputFrame = new OutputFrame();
outputFrame.addWindowListener(new WindowAdapter() {
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosing(final WindowEvent e) {
if (outputFrame != null) {
outputFrame.setVisible(false);
}
}
});
}
}
}, false);
}
private void showLogWindow() {
openLogWindow();
GUIUtil.executeTask(new Runnable() {
public void run() {
outputFrame.setVisible(true);
// outputFrame.toFront();
}
}, true);
}
private void openConfigWindow(final TwisterConfig config, final TwisterCanvas canvas) {
GUIUtil.executeTask(new Runnable() {
public void run() {
if (configFrame == null) {
configFrame = new ConfigFrame(new DefaultTwisterConfigContext(), config, canvas, sessionController);
configFrame.addWindowListener(new WindowAdapter() {
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosing(final WindowEvent e) {
if (configFrame != null) {
configFrame.dispose();
configFrame = null;
}
}
});
}
configFrame.setVisible(true);
configFrame.toFront();
}
}, true);
GUIUtil.executeTask(new Runnable() {
public void run() {
configFrame.setup();
}
}, true);
}
private void openAdvancedConfigWindow(final TwisterConfig config, final TwisterCanvas canvas) {
GUIUtil.executeTask(new Runnable() {
public void run() {
if (advancedConfigFrame == null) {
advancedConfigFrame = new NavigatorFrame(twisterTree, canvas, sessionController);
advancedConfigFrame.addWindowListener(new WindowAdapter() {
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosing(final WindowEvent e) {
if (advancedConfigFrame != null) {
advancedConfigFrame.dispose();
advancedConfigFrame = null;
}
}
});
}
advancedConfigFrame.setVisible(true);
advancedConfigFrame.toFront();
}
}, true);
}
private void openServiceWindow() {
GUIUtil.executeTask(new Runnable() {
public void run() {
if (TwisterFrame.serviceFrame == null) {
TwisterFrame.serviceFrame = new ServiceFrame(serviceContext, service, renderClipTableModel, renderProfileTableModel, renderJobTableModel);
TwisterFrame.serviceFrame.addWindowListener(new WindowAdapter() {
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosing(final WindowEvent e) {
context.removeFrame(TwisterFrame.serviceFrame);
TwisterFrame.serviceFrame = null;
if (context.getFrameCount() == 0) {
service.stop();
context.exit();
}
}
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowOpened(final WindowEvent e) {
context.addFrame(TwisterFrame.serviceFrame);
}
});
}
TwisterFrame.serviceFrame.setVisible(true);
TwisterFrame.serviceFrame.toFront();
}
}, true);
}
private TwisterBookmark createBookmark() throws Exception {
final TwisterBookmark bookmark = new TwisterBookmark();
bookmark.setConfig(config.clone());
final TwisterRuntime runtime = new TwisterRuntime(bookmark.getConfig());
final DefaultTwisterRenderer renderer = new DefaultTwisterRenderer(runtime);
final Map<Object, Object> hints = new HashMap<Object, Object>();
hints.put(TwisterRenderingHints.KEY_MEMORY, TwisterRenderingHints.MEMORY_LOW);
renderer.setRenderingHints(hints);
bookmark.setRenderer(renderer);
return bookmark;
}
private class TwisterWindowListener extends WindowAdapter {
private final TwisterCanvas canvas;
/**
* @param canvas
*/
public TwisterWindowListener(final TwisterCanvas canvas) {
this.canvas = canvas;
}
/**
* @see java.awt.event.WindowAdapter#windowActivated(java.awt.event.WindowEvent)
*/
@Override
public void windowActivated(final WindowEvent e) {
canvas.requestFocus();
}
/**
* @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 (canvas != null) {
if (!canvas.isStarted()) {
try {
canvas.acquire();
canvas.start(config);
canvas.startRenderers();
canvas.release();
canvas.refresh();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
panel.updateButtons();
}
}
}
}, true);
}
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosing(final WindowEvent e) {
if (canvas != null) {
if (canvas.isStarted()) {
try {
canvas.acquire();
canvas.stopRenderers();
canvas.stop();
canvas.release();
canvas.refresh();
}
catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
panel.updateButtons();
}
}
dispose();
if (outputFrame != null) {
outputFrame.dispose();
outputFrame = null;
}
if (configFrame != null) {
configFrame.dispose();
configFrame = null;
}
if (advancedConfigFrame != null) {
advancedConfigFrame.dispose();
advancedConfigFrame = null;
}
context.removeFrame(TwisterFrame.this);
if (context.getFrameCount() == 0) {
service.stop();
context.exit();
}
}
/**
* @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 (canvas != null) {
if (!canvas.isStarted()) {
try {
canvas.acquire();
canvas.start(config);
canvas.startRenderers();
canvas.release();
canvas.refresh();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
panel.updateButtons();
}
}
}
}, true);
}
/**
* @see java.awt.event.WindowAdapter#windowIconified(java.awt.event.WindowEvent)
*/
@Override
public void windowIconified(final WindowEvent e) {
if (canvas != null) {
if (canvas.isStarted()) {
try {
canvas.acquire();
canvas.stopRenderers();
canvas.stop();
canvas.release();
canvas.refresh();
}
catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
panel.updateButtons();
}
}
}
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosed(final WindowEvent e) {
}
}
private RenderClipDataRow createDefaultRenderClip(final long duration) {
final RenderClipDataRow clip = new RenderClipDataRow(new RenderClip());
clip.setClipName("New Clip");
clip.setDescription("");
clip.setDuration(duration);
return clip;
}
public class TwisterPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JButton editConfigButton = GUIFactory.createButton(new EditConfigAction(), TwisterSwingResources.getInstance().getString("tooltip.editConfiguration"));
private JButton showServiceButton = GUIFactory.createButton(new ShowServiceAction(), TwisterSwingResources.getInstance().getString("tooltip.showService"));
private JButton playSessionButton = GUIFactory.createButton(new PlaySessionAction(), TwisterSwingResources.getInstance().getString("tooltip.playSession"));
private JButton startSessionButton = GUIFactory.createButton(new StartSessionAction(), TwisterSwingResources.getInstance().getString("tooltip.startSession"));
private JButton stopSessionButton = GUIFactory.createButton(new StopSessionAction(), TwisterSwingResources.getInstance().getString("tooltip.stopSession"));
private JButton suspendSessionButton = GUIFactory.createButton(new SuspendSessionAction(), TwisterSwingResources.getInstance().getString("tooltip.suspendSession"));
private JButton resumeSessionButton = GUIFactory.createButton(new ResumeSessionAction(), TwisterSwingResources.getInstance().getString("tooltip.resumeSession"));
private JButton storePhotoButton = GUIFactory.createButton(new StorePhotoAction(), TwisterSwingResources.getInstance().getString("tooltip.storePhoto"));
private JButton storeMovieButton = GUIFactory.createButton(new StoreMovieAction(), TwisterSwingResources.getInstance().getString("tooltip.storeMovie"));
private JButton undoButton = GUIFactory.createButton(new UndoAction(), TwisterSwingResources.getInstance().getString("tooltip.undo"));
private JButton redoButton = GUIFactory.createButton(new RedoAction(), TwisterSwingResources.getInstance().getString("tooltip.redo"));
private JButton addBookmarkButton = GUIFactory.createButton(new AddBookmarkAction(), TwisterSwingResources.getInstance().getString("tooltip.addBookmark"));
private JButton fullScreenButton = GUIFactory.createButton(new FullScreenAction(), TwisterSwingResources.getInstance().getString("tooltip.fullScreen"));
private JButton executeScriptButton = GUIFactory.createButton(new ExecuteScriptAction(), TwisterSwingResources.getInstance().getString("tooltip.executeScript"));
/**
* @param canvas
*/
public TwisterPanel(final TwisterCanvas canvas) {
setLayout(new BorderLayout());
final JPanel panelButtons = new JPanel(new FlowLayout(FlowLayout.CENTER));
final JPanel panelCanvas = new JPanel(new BorderLayout());
panelButtons.setFocusable(false);
panelButtons.setOpaque(false);
panelCanvas.setOpaque(false);
setFocusable(false);
setBackground(new Color(0x2f2f2f));
setOpaque(true);
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/options-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/options-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/options-pressed-button.png"));
editConfigButton = new IconButton(normalImage, pressedImage, focusedImage, new EditConfigAction());
editConfigButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.editConfiguration"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/clips-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/clips-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/clips-pressed-button.png"));
showServiceButton = new IconButton(normalImage, pressedImage, focusedImage, new ShowServiceAction());
showServiceButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.showService"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/record-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/record-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/record-pressed-button.png"));
startSessionButton = new IconButton(normalImage, pressedImage, focusedImage, new StartSessionAction());
startSessionButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.startSession"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/stop-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/stop-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/stop-pressed-button.png"));
stopSessionButton = new IconButton(normalImage, pressedImage, focusedImage, new StopSessionAction());
stopSessionButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.stopSession"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/pause-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/pause-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/pause-pressed-button.png"));
suspendSessionButton = new IconButton(normalImage, pressedImage, focusedImage, new SuspendSessionAction());
suspendSessionButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.suspendSession"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/play-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/play-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/play-pressed-button.png"));
playSessionButton = new IconButton(normalImage, pressedImage, focusedImage, new PlaySessionAction());
playSessionButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.playSession"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/record-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/record-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/record-pressed-button.png"));
resumeSessionButton = new IconButton(normalImage, pressedImage, focusedImage, new ResumeSessionAction());
resumeSessionButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.resumeSession"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/photo-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/photo-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/photo-pressed-button.png"));
storePhotoButton = new IconButton(normalImage, pressedImage, focusedImage, new StorePhotoAction());
storePhotoButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.storePhoto"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/movie-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/movie-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/movie-pressed-button.png"));
storeMovieButton = new IconButton(normalImage, pressedImage, focusedImage, new StoreMovieAction());
storeMovieButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.storeMovie"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/add-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/add-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/add-pressed-button.png"));
addBookmarkButton = new IconButton(normalImage, pressedImage, focusedImage, new AddBookmarkAction());
addBookmarkButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.addBookmark"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/left-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/left-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/left-pressed-button.png"));
undoButton = new IconButton(normalImage, pressedImage, focusedImage, new UndoAction());
undoButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.undo"));
((IconButton) undoButton).setRepeatTime(50);
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/right-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/right-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/right-pressed-button.png"));
redoButton = new IconButton(normalImage, pressedImage, focusedImage, new RedoAction());
redoButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.redo"));
((IconButton) redoButton).setRepeatTime(50);
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/up-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/up-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/up-pressed-button.png"));
fullScreenButton = new IconButton(normalImage, pressedImage, focusedImage, new FullScreenAction());
fullScreenButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.fullScreen"));
}
catch (final IOException e) {
e.printStackTrace();
}
try {
final Image normalImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/script-normal-button.png"));
final Image focusedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/script-focused-button.png"));
final Image pressedImage = ImageIO.read(TwisterFrame.class.getResourceAsStream("/icons/script-pressed-button.png"));
executeScriptButton = new IconButton(normalImage, pressedImage, focusedImage, new ExecuteScriptAction());
executeScriptButton.setToolTipText(TwisterSwingResources.getInstance().getString("tooltip.executeScript"));
}
catch (final IOException e) {
e.printStackTrace();
}
panelButtons.add(editConfigButton);
panelButtons.add(showServiceButton);
panelButtons.add(startSessionButton);
panelButtons.add(stopSessionButton);
panelButtons.add(suspendSessionButton);
panelButtons.add(resumeSessionButton);
panelButtons.add(playSessionButton);
panelButtons.add(storePhotoButton);
panelButtons.add(storeMovieButton);
panelButtons.add(undoButton);
panelButtons.add(redoButton);
panelButtons.add(addBookmarkButton);
// panelButtons.add(fullScreenButton);
panelButtons.add(executeScriptButton);
panelCanvas.add(canvas);
panelCanvas.setBorder(new LineBorder(Color.BLACK));
this.add(panelButtons, BorderLayout.SOUTH);
this.add(panelCanvas, BorderLayout.CENTER);
model.addChangeListener(new BookmarkSelectionListener());
updateButtons();
}
public void updateButtons() {
startSessionButton.setEnabled(canStartSession());
startSessionButton.setVisible(canStartSession());
stopSessionButton.setEnabled(canStopSession());
stopSessionButton.setVisible(canStopSession());
resumeSessionButton.setEnabled(canResumeSession());
resumeSessionButton.setVisible(canResumeSession());
suspendSessionButton.setEnabled(canSuspendSession());
suspendSessionButton.setVisible(canSuspendSession());
playSessionButton.setEnabled(canPlaySession());
playSessionButton.setVisible(canPlaySession());
storeMovieButton.setEnabled(canStoreMovie());
storeMovieButton.setVisible(canStoreMovie());
storePhotoButton.setEnabled(canStorePhoto());
storePhotoButton.setVisible(canStorePhoto());
undoButton.setEnabled(canUndo());
undoButton.setVisible(canUndo());
redoButton.setEnabled(canRedo());
redoButton.setVisible(canRedo());
addBookmarkButton.setEnabled(canAddBookmark());
addBookmarkButton.setVisible(canAddBookmark());
editConfigButton.setEnabled(canEditConfig());
editConfigButton.setVisible(canEditConfig());
executeScriptButton.setEnabled(canExecuteScript());
executeScriptButton.setVisible(canExecuteScript());
}
/**
* @return
*/
private boolean isPlayState() {
return canvas.getState() == TwisterCanvas.STATE_PLAY;
}
/**
* @return
*/
private boolean isEditState() {
return canvas.getState() == TwisterCanvas.STATE_EDIT;
}
/**
* @return
*/
private boolean isScriptState() {
return canvas.getState() == TwisterCanvas.STATE_SCRIPT;
}
/**
* @return
*/
private boolean canStorePhoto() {
return isEditState() || isPlayState() || isScriptState();
}
/**
* @return
*/
private boolean canStoreMovie() {
return (tmpClip != null) && isEditState();
}
/**
* @return
*/
private boolean canPlaySession() {
return ((clip == null) && (tmpClip != null) && isEditState()) || (((playClip == null) && isPlayState()) && !isScriptState());
}
/**
* @return
*/
private boolean canSuspendSession() {
return ((clip != null) && (sequence != null) && isEditState()) || (((playClip != null) && isPlayState()) && !isScriptState());
}
/**
* @return
*/
private boolean canResumeSession() {
return (clip != null) && (sequence == null) && isEditState() && !isScriptState();
}
/**
* @return
*/
private boolean canStopSession() {
return ((clip != null) && isEditState()) || (isPlayState() && !isScriptState());
}
/**
* @return
*/
private boolean canStartSession() {
return (clip == null) && isEditState() && !isScriptState();
}
/**
* @return
*/
private boolean canUndo() {
return isEditState() && !isScriptState();
}
/**
* @return
*/
private boolean canRedo() {
return isEditState() && !isScriptState();
}
/**
* @return
*/
private boolean canAddBookmark() {
return isEditState();
}
/**
* @return
*/
private boolean canEditConfig() {
return isEditState() && !isScriptState();
}
/**
* @return
*/
private boolean canExecuteScript() {
return isEditState() && !isScriptState();
}
protected class EditConfigAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public EditConfigAction() {
super(TwisterSwingResources.getInstance().getString("action.editConfig"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
openConfigWindow(config, canvas);
}
}
protected class ShowServiceAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public ShowServiceAction() {
super(TwisterSwingResources.getInstance().getString("action.showService"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
openServiceWindow();
}
}
protected class StartSessionAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public StartSessionAction() {
super(TwisterSwingResources.getInstance().getString("action.startSession"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (canStartSession()) {
tree = new DefaultTree();
clip = new TwisterClip();
sequence = new TwisterSequence();
sequence.setInitialConfig(config.clone());
final TwisterConfigNodeBuilder builder = new TwisterConfigNodeBuilder(config);
builder.createNodes(tree.getRootNode());
tree.getRootNode().setContext(config.getContext());
tree.getRootNode().setSession(new DefaultNodeSession("clip " + clip.getSequenceCount()));
canvas.setSymbol(TwisterCanvas.SYMBOL_RECORD);
sequenceStartTime = System.currentTimeMillis();
clipDuration = 0;
}
updateButtons();
}
}
protected class StopSessionAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public StopSessionAction() {
super(TwisterSwingResources.getInstance().getString("action.stopSession"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (isPlayState()) {
try {
canvas.acquire();
canvas.stopRenderers();
canvas.stop();
playClip = null;
sequence = null;
clip = null;
tree = null;
config.getContext().updateTimestamp();
config.setFrameConfigElement(canvas.getConfig().getFrameConfigElement().clone());
config.setEffectConfigElement(canvas.getConfig().getEffectConfigElement().clone());
config.setBackground(canvas.getConfig().getBackground());
canvas.start(config);
canvas.startRenderers();
canvas.release();
canvas.refresh();
}
catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
else if (canStopSession()) {
if (sequence != null) {
sequenceStopTime = System.currentTimeMillis();
final List<NodeAction> nodeActions = tree.getRootNode().getSession().getActions();
sequence.setFinalConfig(config.clone());
for (final NodeAction nodeAction : nodeActions) {
final NodeActionValue value = nodeAction.toActionValue();
value.setTimestamp(value.getTimestamp() - sequenceStartTime);
final NodeAction action = new NodeAction(value);
sequence.addAction(action);
}
sequence.setDuration(sequenceStopTime - sequenceStartTime);
clipDuration += sequence.getDuration();
clip.addSequence(sequence);
}
tmpClip = clip;
sequence = null;
clip = null;
tree = null;
canvas.setSymbol(TwisterCanvas.SYMBOL_NONE);
}
updateButtons();
}
}
protected class SuspendSessionAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public SuspendSessionAction() {
super(TwisterSwingResources.getInstance().getString("action.suspendSession"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (canSuspendSession()) {
if (isEditState()) {
sequenceStopTime = System.currentTimeMillis();
final List<NodeAction> nodeActions = tree.getRootNode().getSession().getActions();
sequence.setFinalConfig(config.clone());
for (final NodeAction nodeAction : nodeActions) {
final NodeActionValue value = nodeAction.toActionValue();
value.setTimestamp(value.getTimestamp() - sequenceStartTime);
sequence.addAction(new NodeAction(value));
}
sequence.setDuration(sequenceStopTime - sequenceStartTime);
clipDuration += sequence.getDuration();
clip.addSequence(sequence);
sequence = null;
tree = null;
canvas.setSymbol(TwisterCanvas.SYMBOL_PAUSE);
}
else if (isPlayState()) {
canvas.setSymbol(TwisterCanvas.SYMBOL_PAUSE);
canvas.suspend();
playClip = null;
}
}
updateButtons();
}
}
protected class ResumeSessionAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public ResumeSessionAction() {
super(TwisterSwingResources.getInstance().getString("action.resumeSession"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (canResumeSession()) {
sequence = new TwisterSequence();
sequence.setInitialConfig(config.clone());
tree = new DefaultTree();
final TwisterConfigNodeBuilder builder = new TwisterConfigNodeBuilder(config);
builder.createNodes(tree.getRootNode());
tree.getRootNode().setContext(config.getContext());
tree.getRootNode().setSession(new DefaultNodeSession("clip " + clip.getSequenceCount()));
canvas.setSymbol(TwisterCanvas.SYMBOL_RECORD);
sequenceStartTime = System.currentTimeMillis();
}
updateButtons();
}
}
protected class PlaySessionAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public PlaySessionAction() {
super(TwisterSwingResources.getInstance().getString("action.playSession"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (canPlaySession()) {
if (configFrame != null) {
configFrame.dispose();
configFrame = null;
}
if (advancedConfigFrame != null) {
advancedConfigFrame.dispose();
advancedConfigFrame = null;
}
try {
canvas.acquire();
if (canvas.isSuspended()) {
playClip = tmpClip;
canvas.setSymbol(TwisterCanvas.SYMBOL_PLAY);
canvas.resume();
}
else {
canvas.stopRenderers();
canvas.stop();
playClip = tmpClip;
canvas.start(playClip);
canvas.startRenderers();
}
canvas.release();
canvas.refresh();
}
catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
updateButtons();
}
}
protected class StorePhotoAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public StorePhotoAction() {
super(TwisterSwingResources.getInstance().getString("action.storePhoto"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (canStorePhoto()) {
if (isEditState()) {
if (JOptionPane.showConfirmDialog(TwisterPanel.this, TwisterSwingResources.getInstance().getString("message.confirmSavePhoto"), TwisterSwingResources.getInstance().getString("label.savePhoto"), JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION) {
final RenderClipDataRow clip = createDefaultRenderClip(0);
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
TwisterFrame.logger.log(Level.WARNING, "Can't create the clip", throwable);
semaphore.release();
}
public Object execute(final LibraryService service) throws Exception {
final TwisterSequence sequence = new TwisterSequence();
sequence.setInitialConfig(config.clone());
sequence.setFinalConfig(config.clone());
final TwisterClip twisterClip = new TwisterClip();
twisterClip.addSequence(sequence);
service.createClip(clip, twisterClip);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
x.printStackTrace();
}
}
}
else if (isPlayState() || isScriptState()) {
final RenderClipDataRow clip = createDefaultRenderClip(0);
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
TwisterFrame.logger.log(Level.WARNING, "Can't create the clip", throwable);
semaphore.release();
}
public Object execute(final LibraryService service) throws Exception {
final TwisterSequence sequence = new TwisterSequence();
canvas.acquire();
final TwisterConfig config = canvas.getConfig();
sequence.setInitialConfig(config);
sequence.setFinalConfig(config);
final TwisterClip twisterClip = new TwisterClip();
twisterClip.addSequence(sequence);
service.createClip(clip, twisterClip);
canvas.release();
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
}
}
protected class StoreMovieAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public StoreMovieAction() {
super(TwisterSwingResources.getInstance().getString("action.storeMovie"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (canStoreMovie()) {
if (JOptionPane.showConfirmDialog(TwisterPanel.this, TwisterSwingResources.getInstance().getString("message.confirmSaveMovie"), TwisterSwingResources.getInstance().getString("label.saveMovie"), JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION) {
final TwisterClipController controller = new TwisterClipController(tmpClip);
controller.init();
logger.fine("Clip duration = " + clipDuration + ", controller duration = " + controller.getDuration());
final RenderClipDataRow clip = createDefaultRenderClip(controller.getDuration());
service.execute(new ServiceCallback<Object>() {
public void executed(final Object value) {
semaphore.release();
}
public void failed(final Throwable throwable) {
TwisterFrame.logger.log(Level.WARNING, "Can't create the clip", throwable);
semaphore.release();
}
public Object execute(final LibraryService service) throws Exception {
service.createClip(clip, tmpClip);
return null;
}
});
try {
semaphore.acquire();
}
catch (final InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
}
}
protected class UndoAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public UndoAction() {
super(TwisterSwingResources.getInstance().getString("action.undo"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
canvas.submitCommand(new Runnable() {
/**
* @see java.lang.Runnable#run()
*/
public void run() {
if (sessionController != null) {
sessionController.undoAction(true);
}
}
});
}
}
protected class RedoAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public RedoAction() {
super(TwisterSwingResources.getInstance().getString("action.redo"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
canvas.submitCommand(new Runnable() {
/**
* @see java.lang.Runnable#run()
*/
public void run() {
if (sessionController != null) {
sessionController.redoAction(true);
}
}
});
}
}
protected class AddBookmarkAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public AddBookmarkAction() {
super(TwisterSwingResources.getInstance().getString("action.addBookmark"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
try {
canvas.addBookmark(createBookmark());
}
catch (final Exception x) {
x.printStackTrace();
}
}
}
protected class FullScreenAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private boolean isFullScreen;
public FullScreenAction() {
super(TwisterSwingResources.getInstance().getString("action.fullScreen"));
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
final GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (!GraphicsEnvironment.isHeadless()) {
final GraphicsDevice device = environment.getDefaultScreenDevice();
if (device.getType() == GraphicsDevice.TYPE_RASTER_SCREEN) {
if (device.isFullScreenSupported()) {
try {
canvas.acquire();
canvas.stopRenderers();
canvas.stop();
if (!isFullScreen) {
device.setFullScreenWindow(TwisterFrame.this);
isFullScreen = true;
if (device.isDisplayChangeSupported()) {
device.setDisplayMode(new DisplayMode(1024, 768, 32, DisplayMode.REFRESH_RATE_UNKNOWN));
}
}
else {
device.setFullScreenWindow(null);
isFullScreen = false;
}
canvas.start(config);
canvas.startRenderers();
canvas.release();
}
catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
}
}
}
protected class ExecuteScriptAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private JFileChooser fileChooser = new JFileChooser();
public ExecuteScriptAction() {
super(TwisterSwingResources.getInstance().getString("action.executeScript"));
fileChooser.setDialogTitle(TwisterSwingResources.getInstance().getString("label.selectScript"));
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setMultiSelectionEnabled(false);
fileChooser.setFileFilter(new JSFileFilter());
}
/**
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(final ActionEvent e) {
if (scriptThread == null) {
File file = selectFile();
if (file != null) {
scriptThread = new Thread(new ScriptRunnable(file), "Script Thread");
scriptThread.setPriority(Thread.MAX_PRIORITY);
scriptThread.setDaemon(true);
scriptThread.start();
}
}
}
private File selectFile() {
File file = null;
final int returnVal = fileChooser.showOpenDialog(new JFrame());
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = fileChooser.getSelectedFile().getAbsoluteFile().getAbsoluteFile();
}
else {
file = null;
}
return file;
}
private class ScriptRunnable implements Runnable {
private File file;
/**
* @param file
*/
public ScriptRunnable(File file) {
this.file = file;
}
public void run() {
GUIUtil.executeTask(new Runnable() {
public void run() {
try {
if (configFrame != null) {
configFrame.dispose();
configFrame = null;
}
if (advancedConfigFrame != null) {
advancedConfigFrame.dispose();
advancedConfigFrame = null;
}
canvas.acquire();
canvas.stopRenderers();
canvas.startScript();
canvas.startRenderers();
canvas.release();
canvas.refresh();
updateButtons();
openLogWindow();
outputFrame.clear();
canvas.showMessage(TwisterSwingResources.getInstance().getString("message.clickToInterrupt"), 2.5f, 5, 95, 2000, true);
}
catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}, false);
try {
JSManager.execute(canvas, new TwisterJSContext(), twisterTree.getRootNode(), file.getParentFile(), file);
}
catch (final Exception x) {
x.printStackTrace();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
x.printStackTrace(ps);
ps.close();
GUIUtil.executeTask(new Runnable() {
public void run() {
showLogWindow();
outputFrame.append(baos.toString());
// JOptionPane.showMessageDialog(new JFrame(), x.toString(), TwisterSwingResources.getInstance().getString("error.scriptFailed"), JOptionPane.ERROR_MESSAGE);
}
}, false);
}
finally {
GUIUtil.executeTask(new Runnable() {
public void run() {
try {
canvas.acquire();
canvas.stopRenderers();
canvas.stopScript();
canvas.startRenderers();
canvas.release();
canvas.refresh();
updateButtons();
scriptThread = null;
}
catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}, false);
}
}
}
private class TwisterJSContext extends DefaultJSContext {
/**
* @see net.sf.jame.core.scripting.DefaultJSContext#println(java.lang.String)
*/
@Override
public void println(final String s) {
GUIUtil.executeTask(new Runnable() {
public void run() {
showLogWindow();
outputFrame.append(s);
logger.info(s);
}
}, true);
}
/**
* @see net.sf.jame.core.scripting.DefaultJSContext#showMessage(java.lang.String, float, float, float, long, boolean)
*/
@Override
public void showMessage(final String message, final float size, final float x, final float y, final long time, final boolean hasBackground) {
GUIUtil.executeTask(new Runnable() {
public void run() {
// TwisterFrame.this.toFront();
canvas.showMessage(message, size, x, y, time, hasBackground);
}
}, true);
}
/**
* @see net.sf.jame.core.scripting.JSContext#loadDefaultConfig()
*/
public void loadDefaultConfig() {
try {
final TwisterConfigBuilder configBuilder = new TwisterConfigBuilder();
final TwisterConfig tmpConfig = configBuilder.createDefaultConfig();
canvas.acquire();
canvas.stopRenderers();
config.getContext().updateTimestamp();
config.setFrameConfigElement(tmpConfig.getFrameConfigElement().clone());
config.setEffectConfigElement(tmpConfig.getEffectConfigElement().clone());
config.setBackground(tmpConfig.getBackground());
canvas.startRenderers();
canvas.release();
canvas.refresh();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
private class BookmarkSelectionListener implements ChangeListener {
/**
* @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
*/
public void stateChanged(final ChangeEvent e) {
try {
final TwisterBookmark bookmark = canvas.getSelectedBookmark();
if (bookmark != null) {
canvas.acquire();
canvas.stopRenderers();
config.getContext().updateTimestamp();
config.setFrameConfigElement(bookmark.getConfig().getFrameConfigElement().clone());
config.setEffectConfigElement(bookmark.getConfig().getEffectConfigElement().clone());
canvas.startRenderers();
canvas.release();
canvas.refresh();
}
updateButtons();
}
catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
}
private class DefaulServiceContext implements ServiceContext {
private final TwisterContext context;
private final RenderService service;
private final int vcells;
private final int hcells;
/**
* @param context
* @param service
* @param vcells
* @param hcells
*/
public DefaulServiceContext(final TwisterContext context, final RenderService service, final int vcells, final int hcells) {
this.context = context;
this.service = service;
this.vcells = vcells;
this.hcells = hcells;
}
/**
* @see net.sf.jame.service.swing.ServiceContext#openClip(net.sf.jame.twister.TwisterClip)
*/
public void openClip(final TwisterClip clip) {
if (clip != null) {
try {
final TwisterConfigBuilder configBuilder = new TwisterConfigBuilder();
final TwisterConfig config = configBuilder.createDefaultConfig();
config.setContext(new DefaultConfigContext());
final TwisterFrame frame = new TwisterFrame(context, service, config, hcells, vcells);
frame.setVisible(true);
GUIUtil.executeTask(new Runnable() {
public void run() {
frame.loadClip(clip);
}
}, true);
}
catch (final ExtensionException x) {
x.printStackTrace();
}
}
}
/**
* @see net.sf.jame.service.swing.ServiceContext#removeFrame(javax.swing.JFrame)
*/
public void removeFrame(final JFrame frame) {
context.removeFrame(frame);
}
/**
* @see net.sf.jame.service.swing.ServiceContext#addFrame(javax.swing.JFrame)
*/
public void addFrame(final JFrame frame) {
context.addFrame(frame);
}
/**
* @see net.sf.jame.service.swing.ServiceContext#getFrameCount()
*/
public int getFrameCount() {
return context.getFrameCount();
}
/**
* @see net.sf.jame.service.swing.ServiceContext#exit()
*/
public void exit() {
context.exit();
}
/**
* @see net.sf.jame.service.swing.ServiceContext#restart()
*/
public void restart() {
context.restart();
}
}
private class DefaultTwisterConfigContext implements TwisterConfigContext {
/**
* @see net.sf.jame.twister.swing.TwisterConfigContext#openAdvancedConfigWindow()
*/
public void openAdvancedConfigWindow() {
TwisterFrame.this.openAdvancedConfigWindow(config, canvas);
}
}
}