BlinkenArea - GitList
Repositories
Blog
Wiki
Blimp
Code
Commits
Branches
Tags
Search
Tree:
d0679a7
Branches
Tags
master
1.4.4
v.1.4.3
v0.2
v0.3
v0.4
v0.5
v0.6
v1.0
v1.1
v1.2
v1.2.1
v1.3
v1.3.1
v1.3.2
v1.3.3
v1.3.4
v1.3.5
v1.3.6
v1.3.7
v1.3.8
v1.4.0
v1.4.1
v1.4.2
v1.4.4
Blimp
Blimp.java
Blimp v.1.2 (2005-12-19)
Christian Heimke
commited
d0679a7
at 2011-07-15 09:18:13
Blimp.java
Blame
History
Raw
/* BlinkenLightsInteractiveMovieProgram * version 1.2 date 2005-12-19 * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info> * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html * a blinkenarea.org project * powered by eventphone.de */ import java.applet.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; import java.io.*; import java.util.*; import java.util.regex.*; import java.net.*; public class Blimp extends JApplet implements Runnable, WindowListener, ActionListener, AdjustmentListener, ChangeListener, FocusListener, DocumentListener, BlinkenFrameEditorListener { //configuration constants static final int constColorCntX = 2, constColorCntY = 4; static final int constColorCnt = constColorCntX * constColorCntY; static final int defHeight = 8, defWidth = 8, defChannels = 1, defMaxval = 127, defDuration = 100; //configuration variables boolean isFullApp = false; //if running as full application String initialFile = null; //GUI elements JFrame frame; //main window (if running as full application) Component dialogParent; //parent to use for dialogs JMenuBar menubar; //menubar in main window JMenu menuFile, menuInfo, menuEdit, menuFrameSel, menuPlay, menuHelp; //menus JMenuItem menuFileNew, menuFileLoad, menuFileSave, menuFileSaveAs, menuFileQuit; JMenuItem menuInfoShow, menuInfoAdd, menuInfoDelete; JMenuItem menuEditResize, menuEditScale; JMenuItem menuEditInsertFrame, menuEditDuplicateFrame, menuEditDeleteFrame; JMenuItem menuFrameSelNone, menuFrameSelSingle, menuFrameSelStart, menuFrameSelEnd; JMenuItem menuFrameSelCopy, menuFrameSelMove, menuFrameSelReverse, menuFrameSelDelete; JMenuItem menuEditImportImages, menuEditImportMovie; JMenuItem menuPlayStart, menuPlayStop; JCheckBoxMenuItem menuPlayBegin, menuPlayLoop; JMenuItem menuHelpAbout; JPanel panel, panelStatus, panelMain, panelFrames, panelOuterFrame; //panels of main window JPanel panelMiddleFrame, panelFrame, panelDuration, panelColors; JLabel labelStatus, labelFrames, labelSelFrames, labelFrameInfo, labelDuration; JScrollBar scrollFrames; JSlider sliderFrameZoom; BlinkenFrameEditor frameEditor; JScrollPane scrollpaneFrame; JTextField textDuration; JPanel panelOuterTools, panelMiddleTools, panelTools, panelActions; JPanel panelOuterEdit, panelMiddleEdit, panelEdit; JToggleButton buttonToolsNone, buttonToolsColorPicker, buttonToolsDot, buttonToolsLine; JToggleButton buttonToolsRect, buttonToolsFilledRect, buttonToolsCircle, buttonToolsFilledCircle; JToggleButton buttonToolsCopy, buttonToolsPaste; ButtonGroup groupTools; JButton buttonActionsInvert, buttonActionsRotate90, buttonActionsRotate180, buttonActionsRotate270; JButton buttonActionsMirrorHor, buttonActionsMirrorVer, buttonActionsMirrorDiag, buttonActionsMirrorDiag2; JButton buttonActionsRollLeft, buttonActionsRollRight, buttonActionsRollUp, buttonActionsRollDown; JButton buttonActionsUndo, buttonActionsRedo; JButton buttonEditInsertFrame, buttonEditDuplicateFrame, buttonEditDeleteFrame; JPanel panelColorsChoose, panelColorsSettings, panelColorsColor, panelColorsAlpha; JToggleButton buttonsColor[]; ButtonGroup groupColor; JLabel labelColorsColor, labelColorsAlpha; JButton buttonColorsColor; JSlider sliderColorsAlpha; JTextField textColorsColor, textColorsAlpha; //other variables int colorIdx; //index of selected color Color colors[]; //current colors ImageIcon iconsColor[], iconColorsColor; //color icons shown in color panel javax.swing.Timer timerPlay; //timer used for playing movies //file, movie, frame File curDir = null, curFile = null; //current directory and file BlinkenMovie curMovie = null; //current movie boolean curMovieChanged = false; //if changes have been made to current movie BlinkenFrame curFrame = null; //current frame int frameSelStart = -1, frameSelEnd = -1; //selected frames (none selected yet) //constructor for applet public Blimp( ) { isFullApp = false; } //constructor for full application - perhaps load an initial file (filename != null) public Blimp( String filename ) { isFullApp = true; initialFile = filename; } //load an image private ImageIcon loadImageIcon( String name ) { URL url = Blimp.class.getResource( "images/" + name ); if( url != null ) return new ImageIcon( url ); else return new ImageIcon( new BufferedImage( 1, 1, BufferedImage.TYPE_INT_RGB ) ); } //perhaps ask if to save changes and perhaps do it //return true on cancel private boolean askSaveChanges( ) { int retVal; //ask only when changes were made if( curMovieChanged ) { //ask if to save changes retVal = JOptionPane.showConfirmDialog( dialogParent, "Do You want to save the changes?", "Blimp - Save changes?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE ); //cancelled if( retVal == JOptionPane.CANCEL_OPTION ) return true; //save if( retVal == JOptionPane.YES_OPTION ) actionFileSave( ); } //not cancelled return false; } //"File New" was chosen from menu private void actionFileNew( ) { //ask if to save changes if( askSaveChanges( ) ) //returns true on cancel return; //create a new movie if( frame != null ) frame.setTitle( "Blimp" ); labelStatus.setText( "new movie..." ); curFile = null; curMovie = new BlinkenMovie( defHeight, defWidth, defChannels, defMaxval ); curMovie.insertInfo( 0, "creator", "Blimp (version 1.2 date 2005-12-19)" ); curMovie.insertFrame( 0, new BlinkenFrame( defHeight, defWidth, defChannels, defMaxval, defDuration ) ); curMovieChanged = false; //update controls updateFrames( 0 ); } //load file (filename is taken from curFile) private void fileLoad( ) { if( curMovie.load( curFile.getPath( ) ) ) { //success if( frame != null ) frame.setTitle( "Blimp - " + curFile.getPath( ) ); labelStatus.setText( "movie \"" + curFile.getPath( ) + "\" was loaded successfully..." ); curMovieChanged = false; } else { //some error if( frame != null ) frame.setTitle( "Blimp" ); labelStatus.setText( "movie \"" + curFile.getPath( ) + "\" could not be loaded..." ); curFile = null; curMovieChanged = false; } //update controls updateFrames( 0 ); } //"File Load" was chosen from menu private void actionFileLoad( ) { JFileChooser fileChooser; //ask if to save changes if( askSaveChanges( ) ) //returns true on cancel return; //show file select dialog fileChooser = new JFileChooser( ); fileChooser.setDialogTitle( "Blimp - Load..." ); fileChooser.setFileFilter( new BlinkenFileFilter( ) ); if( curDir != null ) fileChooser.setCurrentDirectory( curDir ); if( fileChooser.showOpenDialog( dialogParent ) == JFileChooser.APPROVE_OPTION ) { //save current directory and current file curDir = fileChooser.getCurrentDirectory( ); curFile = fileChooser.getSelectedFile( ); //load file fileLoad( ); } } //"File Save" was chosen from menu private void actionFileSave( ) { //just call "File Save as" if no current file if( curFile == null ) { actionFileSaveAs( ); return; } //save file if( curMovie.save( curFile.getPath( ) ) ) { //success labelStatus.setText( "movie \"" + curFile.getPath( ) + "\" was saved successfully..." ); curMovieChanged = false; } else { //some error labelStatus.setText( "movie \"" + curFile.getPath( ) + "\" could not be saved..." ); } } //"File Save as" was chosen from menu private void actionFileSaveAs( ) { JFileChooser fileChooser; //show file select dialog fileChooser = new JFileChooser( ); fileChooser.setDialogTitle( "Blimp - Save as..." ); fileChooser.setFileFilter( new BlinkenFileFilter( ) ); if( curDir != null ) fileChooser.setCurrentDirectory( curDir ); if( curFile != null ) fileChooser.setSelectedFile( curFile ); if( fileChooser.showSaveDialog( dialogParent ) == JFileChooser.APPROVE_OPTION ) { //save current directory and file curDir = fileChooser.getCurrentDirectory( ); curFile = fileChooser.getSelectedFile( ); if( frame != null ) frame.setTitle( "Blimp - " + curFile.getPath( ) ); //just call "File Save" to do the work actionFileSave( ); } } //"File Quit" was chosen from menu private void actionFileQuit( ) { //ask if to save changes if( askSaveChanges( ) ) //returns true on cancel return; //only end program if runnning as full application if( isFullApp ) System.exit( 0 ); } //"Information Show..." was chosen from menu private void actionInfoShow( ) { int i, cnt; String info; //get information about movie info = ""; cnt = curMovie.getInfoCnt( ); for( i = 0; i < cnt; i++ ) info += "\n" + curMovie.getInfoType( i ) + ": " + curMovie.getInfoData( i ); //show information JOptionPane.showMessageDialog( dialogParent, "Information about movie:\n" + info, "Blimp - Show Information...", JOptionPane.INFORMATION_MESSAGE ); } //"Information Add..." was chosen from menu private void actionInfoAdd( ) { Pattern infoPattern; Object info; Matcher infoMatcher; //initialize info pattern infoPattern = Pattern.compile( "^([A-Za-z0-9]+)(?: *= *|: *)(.*)$" ); //ask for information to add info = JOptionPane.showInputDialog( dialogParent, "Please enter the information to add:\n\n" + "The format is: <info-type>: <info-text>\n" + " title: <title of movie>\n" + " description: <short description of movie content>\n" + " creator: <program this movie was created with>\n" + " author: <name of author(s)>\n" + " email: <email address of author>\n" + " url: <homepage of author or of this movie>", "Blimp - Add Information...", JOptionPane.QUESTION_MESSAGE, null, null, "" ); //dialog was cancelled if( info == null ) return; //add info if( (infoMatcher = infoPattern.matcher( info.toString( ) )).find( ) ) curMovie.insertInfo( curMovie.getInfoCnt( ), infoMatcher.group( 1 ), infoMatcher.group( 2 ) ); else curMovie.insertInfo( curMovie.getInfoCnt( ), "description", info.toString( ) ); curMovieChanged = true; } //"Information Delete..." was chosen from menu private void actionInfoDelete( ) { int i, cnt; String info[]; Object selected; //get information about movie cnt = curMovie.getInfoCnt( ); info = new String[cnt]; for( i = 0; i < cnt; i++ ) info[i] = curMovie.getInfoType( i ) + ": " + curMovie.getInfoData( i ); //ask for new size selected = JOptionPane.showInputDialog( dialogParent, "Select information to delete:", "Blimp - Delete Information...", JOptionPane.QUESTION_MESSAGE, null, info, null ); //dialog was cancelled if( selected == null ) return; //delete sected information for( i = 0; i < cnt; i++ ) if( info[i] == selected ) break; if( i < cnt ) { curMovie.deleteInfo( i ); curMovieChanged = true; } } //"Edit Resize Movie..." was chosen from menu private void actionEditResize( ) { Pattern sizePattern; String curSize; Object size; Matcher sizeMatcher; //initialize size pattern sizePattern = Pattern.compile( "^([0-9]+)x([0-9]+)-([0-9]+)/([0-9]+)$" ); //get string with current movie size curSize = curMovie.getWidth( ) + "x" + curMovie.getHeight( ) + "-" + curMovie.getChannels( ) + "/" + (curMovie.getMaxval( ) + 1); //ask until cancel or answer is valid size = curSize; do { //ask for new size size = JOptionPane.showInputDialog( dialogParent, "Current movie size is: " + curSize + "\n\n" + "The format is: <width>x<height>-<channels>/<colors>\n" + " 18x8-1/2 (Blinkenlights)\n" + " 18x8-1/16 (Blinkenlights Reloaded)\n" + " 26x20-1/16 (Blinkenlights Arcade)\n" + " 104x32-1/128 (TROIA big walls)\n" + " 80x32-1/128 (TROIA small walls)\n" + " 104x80-1/128 (TROIA floor + ceiling)\n\n" + "Please enter the new movie size:", "Blimp - Resize Movie...", JOptionPane.QUESTION_MESSAGE, null, null, size ); //dialog was cancelled if( size == null ) return; } while( ! (sizeMatcher = sizePattern.matcher( size.toString( ) )).find( ) ); //repeat question if answer not valid //resize movie curMovie.resize( Integer.parseInt( sizeMatcher.group( 2 ) ), Integer.parseInt( sizeMatcher.group( 1 ) ), Integer.parseInt( sizeMatcher.group( 3 ) ), Integer.parseInt( sizeMatcher.group( 4 ) ) - 1 ); curMovieChanged = true; //update controls updateFrames( scrollFrames.getValue( ) ); //update status labelStatus.setText( "movie resized successfully to " + size.toString( ) + "..." ); } //"Edit Scale Movie..." was chosen from menu private void actionEditScale( ) { Pattern dimPattern; String curDim, curSize; Object dim; Matcher dimMatcher; //initialize dimension pattern dimPattern = Pattern.compile( "^([0-9]+)x([0-9]+)$" ); //get string with current movie size curDim = curMovie.getWidth( ) + "x" + curMovie.getHeight( ); curSize = curMovie.getWidth( ) + "x" + curMovie.getHeight( ) + "-" + curMovie.getChannels( ) + "/" + (curMovie.getMaxval( ) + 1); //ask until cancel or answer is valid dim = curDim; do { //ask for new size dim = JOptionPane.showInputDialog( dialogParent, "Current movie dimension is: " + curDim + " (" + curSize + ")\n\n" + "The format is: <width>x<height>\n" + " 18x8 (Blinkenlights, Blinkenlights Reloaded)\n" + " 26x20 (Blinkenlights Arcade)\n" + " 104x32 (TROIA big walls)\n" + " 80x32 (TROIA small walls)\n" + " 104x80 (TROIA floor + ceiling)\n\n" + "Please enter the new movie dimension:", "Blimp - Scale Movie...", JOptionPane.QUESTION_MESSAGE, null, null, dim ); //dialog was cancelled if( dim == null ) return; } while( ! (dimMatcher = dimPattern.matcher( dim.toString( ) )).find( ) ); //repeat question if answer not valid //scale movie curMovie.scale( Integer.parseInt( dimMatcher.group( 2 ) ), Integer.parseInt( dimMatcher.group( 1 ) ) ); curMovieChanged = true; //update controls updateFrames( scrollFrames.getValue( ) ); //update status labelStatus.setText( "movie scaled successfully to " + dim.toString( ) + "..." ); } //"Edit Insert Frame" was chosen from menu / Insert Frame button was pressed private void actionEditInsertFrame( ) { BlinkenFrame frame; int frameCnt, frameNo; //create new empty frame frame = new BlinkenFrame( curMovie.getHeight( ), curMovie.getWidth( ), curMovie.getChannels( ), curMovie.getMaxval( ), defDuration ); frame.clear( ); //copy duration if there is a current frame if( curFrame != null ) frame.setDuration( curFrame.getDuration( ) ); //insert frame behind current position frameCnt = curMovie.getFrameCnt( ); frameNo = scrollFrames.getValue( ) + 1; if( frameNo < 0 ) frameNo = 0; if( frameNo > frameCnt ) frameNo = frameCnt; curMovie.insertFrame( frameNo, frame ); curMovieChanged = true; //update controls updateFrames( frameNo ); } //"Edit Duplicate Frame" was chosen from menu / Duplicate Frame button was pressed private void actionEditDuplicateFrame( ) { BlinkenFrame frame; int frameCnt, frameNo; //do nothing if there is no current frame if( curFrame == null ) return; //duplicate current frame frame = new BlinkenFrame( curFrame ); //insert frame behind current position frameCnt = curMovie.getFrameCnt( ); frameNo = scrollFrames.getValue( ) + 1; if( frameNo < 0 ) frameNo = 0; if( frameNo > frameCnt ) frameNo = frameCnt; curMovie.insertFrame( frameNo, frame ); curMovieChanged = true; //update controls updateFrames( frameNo ); } //"Edit Delete Frame" was chosen from menu / Delete Frame button was pressed private void actionEditDeleteFrame( ) { int frameNo; //do nothing if there is no current frame if( curFrame == null ) return; //delete current frame frameNo = scrollFrames.getValue( ); curMovie.deleteFrame( frameNo ); frameNo--; curMovieChanged = true; //update controls updateFrames( frameNo ); } //"Edit Import Images..." was chosen from menu private void actionEditImportImages( ) { JFileChooser fileChooser; File files[]; ImageIcon icon; Image image; BufferedImage bufferedImage; BlinkenFrame frame; int width, height, x, y, i, frameCnt, frameNo; //show file select dialog fileChooser = new JFileChooser( ); fileChooser.setDialogTitle( "Blimp - Import Images..." ); fileChooser.setMultiSelectionEnabled( true ); if( curDir != null ) fileChooser.setCurrentDirectory( curDir ); if( fileChooser.showOpenDialog( dialogParent ) != JFileChooser.APPROVE_OPTION ) //not successful return; //save current directory curDir = fileChooser.getCurrentDirectory( ); //get selected files files = fileChooser.getSelectedFiles( ); for( i = 0; i < files.length; i++ ) { //load image icon = new ImageIcon( files[i].getPath( ) ); if( icon == null ) { labelStatus.setText( "could not import image \"" + files[i].getPath( ) + "\"..." ); break; } width = icon.getIconWidth( ); height = icon.getIconHeight( ); image = icon.getImage( ); if( width <= 0 || height <= 0 || image == null ) { labelStatus.setText( "could not import image \"" + files[i].getPath( ) + "\"..." ); break; } //convert image to a buffered one bufferedImage = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB ); bufferedImage.getGraphics( ).drawImage( image, 0, 0, width, height, null ); //create new empty frame frame = new BlinkenFrame( height, width, curMovie.getChannels( ), curMovie.getMaxval( ), defDuration ); height = frame.getHeight( ); //dimensions might have been invalid and thus been adapted width = frame.getWidth( ); frame.clear( ); //copy duration if there is a current frame if( curFrame != null ) frame.setDuration( curFrame.getDuration( ) ); //put pixels of image into frame for( y = 0; y < height; y++ ) for( x = 0; x < width; x++ ) frame.setColor( y, x, new Color( bufferedImage.getRGB( x, y ) ) ); //insert frame behind current position frameCnt = curMovie.getFrameCnt( ); frameNo = scrollFrames.getValue( ) + 1; if( frameNo < 0 ) frameNo = 0; if( frameNo > frameCnt ) frameNo = frameCnt; curMovie.insertFrame( frameNo, frame ); //this resizes the frame to fit the movie dimensions curMovieChanged = true; //show status message labelStatus.setText( "image \"" + files[i].getPath( ) + "\" was successfully imported..." ); //update controls updateFrames( frameNo ); } } //"Edit Import Movie..." was chosen from menu private void actionEditImportMovie( ) { JFileChooser fileChooser; BlinkenMovie movie; BlinkenFrame frame; int frameCnt, frameNo, cnt, i; //show file select dialog fileChooser = new JFileChooser( ); fileChooser.setDialogTitle( "Blimp - Import Movie..." ); fileChooser.setFileFilter( new BlinkenFileFilter( ) ); if( curDir != null ) fileChooser.setCurrentDirectory( curDir ); if( fileChooser.showOpenDialog( dialogParent ) != JFileChooser.APPROVE_OPTION ) //not successful return; //save current directory curDir = fileChooser.getCurrentDirectory( ); //load movie movie = new BlinkenMovie( 0, 0, 0, 0 ); if( ! movie.load( fileChooser.getSelectedFile( ).getPath( ) ) ) { //some error labelStatus.setText( "movie \"" + fileChooser.getSelectedFile( ).getPath( ) + "\" could not be imported..." ); } //insert frames of movie behind current position frameCnt = curMovie.getFrameCnt( ); frameNo = scrollFrames.getValue( ) + 1; if( frameNo < 0 ) frameNo = 0; if( frameNo > frameCnt ) frameNo = frameCnt; cnt = movie.getFrameCnt( ); for( i = 0; i < cnt; i++ ) { frame = new BlinkenFrame( movie.getFrame( i ) ); curMovie.insertFrame( frameNo + i, frame ); //this resizes the frame to fit the movie dimensions } curMovieChanged = true; //success labelStatus.setText( "movie \"" + fileChooser.getSelectedFile( ).getPath( ) + "\" was successfully imported..." ); //update controls updateFrames( frameNo ); } //"Frame-Selection Select None" was chosen from menu private void actionFrameSelNone( ) { //remove frame selection frameSelStart = -1; frameSelEnd = -1; stateFrameSel( ); } //"Frame-Selection Select Single Frame" was chosen from menu private void actionFrameSelSingle( ) { //do nothing if there is no current frame if( curFrame == null ) return; //select current frame frameSelStart = scrollFrames.getValue( ); frameSelEnd = frameSelStart; stateFrameSel( ); } //"Frame-Selection Start of Selection" was chosen from menu private void actionFrameSelStart( ) { //do nothing if there is no current frame if( curFrame == null ) return; //set start of frame selection to current frame frameSelStart = scrollFrames.getValue( ); if( frameSelEnd >= curMovie.getFrameCnt( ) || frameSelEnd < frameSelStart ) frameSelEnd = frameSelStart; stateFrameSel( ); } //"Frame-Selection End of Selection" was chosen from menu private void actionFrameSelEnd( ) { //do nothing if there is no current frame if( curFrame == null ) return; //set end of frame selection to current frame frameSelEnd = scrollFrames.getValue( ); if( frameSelStart < 0 || frameSelStart > frameSelEnd ) frameSelStart = frameSelEnd; stateFrameSel( ); } //"Frame-Selection Copy" was chosen from menu private void actionFrameSelCopy( ) { int frameCnt, frameNo, cnt, i; //do nothing if selection is invalid frameCnt = curMovie.getFrameCnt( ); if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt ) return; //get copies of selected frames cnt = frameSelEnd - frameSelStart + 1; BlinkenFrame frames[] = new BlinkenFrame[cnt]; for( i = 0; i < cnt; i++ ) frames[i] = new BlinkenFrame( curMovie.getFrame( frameSelStart + i ) ); //insert frames behind current position frameNo = scrollFrames.getValue( ) + 1; if( frameNo < 0 ) frameNo = 0; if( frameNo > frameCnt ) frameNo = frameCnt; for( i = 0; i < cnt; i++ ) curMovie.insertFrame( frameNo + i, frames[i] ); curMovieChanged = true; //update controls updateFrames( frameNo ); //select newly inserted frames frameSelStart = frameNo; frameSelEnd = frameSelStart + cnt - 1; stateFrameSel( ); } //"Frame-Selection Move" was chosen from menu private void actionFrameSelMove( ) { int frameCnt, frameNo, cnt, i; //do nothing if selection is invalid frameCnt = curMovie.getFrameCnt( ); if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt ) return; //get selected frames cnt = frameSelEnd - frameSelStart + 1; BlinkenFrame frames[] = new BlinkenFrame[cnt]; for( i = 0; i < cnt; i++ ) frames[i] = curMovie.getFrame( frameSelStart + i ); //delete selected frames for( i = 0; i < cnt; i++ ) curMovie.deleteFrame( frameSelStart ); //update number of frames and current position frameCnt -= cnt; //cnt frames were deleted frameNo = scrollFrames.getValue( ); //old position if( frameNo > frameSelEnd ) //was behind last frame of selection frameNo -= cnt; else if( frameNo >= frameSelStart) //was in selection frameNo = frameSelStart - 1; //insert frames behind current position frameNo++; if( frameNo < 0 ) frameNo = 0; if( frameNo > frameCnt ) frameNo = frameCnt; for( i = 0; i < cnt; i++ ) curMovie.insertFrame( frameNo + i, frames[i] ); curMovieChanged = true; //update controls updateFrames( frameNo ); //select moved frames frameSelStart = frameNo; frameSelEnd = frameSelStart + cnt - 1; stateFrameSel( ); } //"Frame-Selection Reverse" was chosen from menu private void actionFrameSelReverse( ) { int frameCnt, frameNo, cnt, i; //do nothing if selection is invalid frameCnt = curMovie.getFrameCnt( ); if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt ) return; //get selected frames cnt = frameSelEnd - frameSelStart + 1; BlinkenFrame frames[] = new BlinkenFrame[cnt]; for( i = 0; i < cnt; i++ ) frames[i] = curMovie.getFrame( frameSelStart + i ); //delete selected frames for( i = 0; i < cnt; i++ ) curMovie.deleteFrame( frameSelStart ); //insert selected frames in reverse order for( i = 0; i < cnt; i++ ) curMovie.insertFrame( frameSelStart, frames[i] ); curMovieChanged = true; //update controls - go to reversed frames frameNo = frameSelStart; updateFrames( frameNo ); //select reversed frames frameSelStart = frameNo; frameSelEnd = frameSelStart + cnt - 1; stateFrameSel( ); } //"Frame-Selection Delete" was chosen from menu private void actionFrameSelDelete( ) { int frameCnt, frameNo, cnt, i; //do nothing if selection is invalid frameCnt = curMovie.getFrameCnt( ); if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt ) return; //delete selected frames cnt = frameSelEnd - frameSelStart + 1; for( i = 0; i < cnt; i++ ) curMovie.deleteFrame( frameSelStart ); curMovieChanged = true; //update number of frames and current position frameCnt -= cnt; //cnt frames were deleted frameNo = scrollFrames.getValue( ); //old position if( frameNo > frameSelEnd ) //was behind last frame of selection frameNo -= cnt; else if( frameNo >= frameSelStart) //was in selection frameNo = frameSelStart - 1; //update controls updateFrames( frameNo ); } //"Play Start" was chosen from menu private void actionPlayStart( ) { //select no tool buttonToolsNone.setSelected( true ); frameEditor.setTool( BlinkenFrameEditor.toolNone ); //disable start, enable stop menuPlayStart.setEnabled( false ); menuPlayStop.setEnabled( true ); //stop old play timer timerPlay.stop( ); //if play shall start from beginning if( menuPlayBegin.getState( ) ) { //show first frame if( scrollFrames.getValue( ) != 0 ) //value changes scrollFrames.setValue( 0 ); //play timer will be started again when frame is being shown by scrollbar callback else //value does not change stateFrames( ); //value does not change, no event will be sent, execute callback by hand } //start play timer if( curFrame == null ) timerPlay.setInitialDelay( 100 ); //use 100ms as default else timerPlay.setInitialDelay( curFrame.getDuration( ) ); timerPlay.restart( ); } //"Play Stop" was chosen from menu private void actionPlayStop( ) { //stop play timer timerPlay.stop( ); //enable start, disable stop menuPlayStart.setEnabled( true ); menuPlayStop.setEnabled( false ); } //play timer elapsed private void actionPlayTimer( ) { int frameCnt, frameNoOld, frameNoNew; //stop play timer timerPlay.stop( ); //get number of next frame frameCnt = curMovie.getFrameCnt( ); frameNoOld = scrollFrames.getValue( ); frameNoNew = frameNoOld + 1; if( frameNoNew >= frameCnt ) { frameNoNew = 0; //stop playing if looping is not requested if( ! menuPlayLoop.getState( ) ) { //enable start, disable stop menuPlayStart.setEnabled( true ); menuPlayStop.setEnabled( false ); return; } } //show next frame if( frameNoNew != frameNoOld ) //value changes scrollFrames.setValue( frameNoNew ); //play timer will be started again when frame is being shown by scrollbar callback else //value does not change stateFrames( ); //value does not change, no event will be sent, execute callback by hand } //"Help About" was chosen from menu private void actionHelpAbout( ) { JOptionPane.showMessageDialog( dialogParent, "BlinkenLightsInteractiveMovieProgram\n" + "version 1.2 date 2005-12-19\n" + "Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>\n" + "Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html\n" + "a blinkenarea.org project\n" + "powered by eventphone.de", "Blimp - About...", JOptionPane.INFORMATION_MESSAGE ); } //update frames controls (and go to certaint frame) private void updateFrames( int frameNo ) { int frameCnt; //update frames scrollbar range frameCnt = curMovie.getFrameCnt( ); if( frameCnt <= 0 ) { frameNo = 0; scrollFrames.setValues( 0, 0, 0, 0 ); } else { if( frameNo < 0 ) frameNo = 0; if( frameNo >= frameCnt ) frameNo = frameCnt - 1; scrollFrames.setValues( frameNo, 1, 0, frameCnt ); } //select no frames frameSelStart = -1; frameSelEnd = -1; stateFrameSel( ); //enable/disable some menu commands and buttons which need a current frame menuEditDuplicateFrame.setEnabled( frameCnt > 0 ); menuEditDeleteFrame.setEnabled( frameCnt > 0 ); buttonEditDuplicateFrame.setEnabled( frameCnt > 0 ); buttonEditDeleteFrame.setEnabled( frameCnt > 0 ); menuFrameSelSingle.setEnabled( frameCnt > 0 ); menuFrameSelStart.setEnabled( frameCnt > 0 ); menuFrameSelEnd.setEnabled( frameCnt > 0 ); } //frames scrollbar changed private void stateFrames( ) { int frameCnt, frameNo; //update frames scrollbar label frameCnt = curMovie.getFrameCnt( ); if( frameCnt <= 0 ) { frameNo = 0; labelFrames.setText( "frame: -/0" ); curFrame = null; } else { frameNo = scrollFrames.getValue( ); labelFrames.setText( "frame: " + (frameNo + 1) + "/" + frameCnt ); curFrame = curMovie.getFrame( frameNo ); } //update selected frames label if( 0 > frameSelStart || frameSelStart > frameSelEnd || frameSelEnd >= frameCnt ) labelSelFrames.setText( "selected: -/-" ); else if( frameSelStart > frameNo ) labelSelFrames.setText( "selected: -/" + (frameSelEnd - frameSelStart + 1) ); else if( frameNo > frameSelEnd ) labelSelFrames.setText( "selected: +/" + (frameSelEnd - frameSelStart + 1) ); else labelSelFrames.setText( "selected: " + (frameNo - frameSelStart + 1) + "/" + (frameSelEnd - frameSelStart + 1) ); //update frame frameEditor.setFrame( curFrame ); //show duration showDuration( ); //if currently playing if( ! menuPlayStart.isEnabled( ) ) { //stop play timer timerPlay.stop( ); //start play timer if( curFrame == null ) timerPlay.setInitialDelay( 100 ); //use 100ms as default else timerPlay.setInitialDelay( curFrame.getDuration( ) ); timerPlay.restart( ); } } //frame selection changed private void stateFrameSel( ) { boolean valid; int frameCnt; //simulate frames scrollbar change to propagate update stateFrames( ); //check if selection is valid frameCnt = curMovie.getFrameCnt( ); valid = (0 <= frameSelStart && frameSelStart <= frameSelEnd && frameSelEnd < frameCnt); //enable/disable some menu commands which need a selection menuFrameSelCopy.setEnabled( valid ); menuFrameSelMove.setEnabled( valid ); menuFrameSelReverse.setEnabled( valid ); menuFrameSelDelete.setEnabled( valid ); } //frame zoom changed private void stateFrameZoom( ) { //update frame frameEditor.setZoom( sliderFrameZoom.getValue( ) ); } //show duration private void showDuration( ) { if( curFrame == null ) { textDuration.setEnabled( false ); textDuration.setText( "" ); } else { textDuration.setEnabled( true ); textDuration.setText( "" + curFrame.getDuration( ) ); } } //new frame duration is being entered private void changeDuration( ) { int duration; try { //get new frame duration duration = Integer.parseInt( textDuration.getText( ) ); //write new duration into frame (if it really changed) if( curFrame != null && curFrame.getDuration( ) != duration ) { curFrame.setDuration( duration ); curMovieChanged = true; } } catch( NumberFormatException e ) { } } //new frame duration was entered private void validateDuration( ) { //process changes made to duration changeDuration( ); //redisplay new duration showDuration( ); } //generate a color icon from a color private void iconFromColor( ImageIcon icon, Color color ) { int height, width, y, x; boolean yy, xx; Graphics graphics; //get size height = icon.getIconHeight( ); width = icon.getIconWidth( ); //get graphics context of icon's image graphics = icon.getImage( ).getGraphics( ); //draw background graphics.setColor( new Color( color.getRed( ), color.getGreen( ), color.getBlue( ) ) ); graphics.fillRect( 0, 0, width / 2, height ); for( y = 0, yy = false; y < height; y += height / 4, yy = ! yy ) { for( x = width / 2, xx = yy; x < width; x += width / 6, xx = ! xx ) { if( xx ) graphics.setColor( Color.white ); else graphics.setColor( Color.black ); graphics.fillRect( x, y, width / 6, height / 4 ); } } //draw foreground in specified color graphics.setColor( color ); graphics.fillRect( 0, 0, width, height ); } //a color was chosen private void actionColorIdx( int idx ) { //click on active color if( idx == colorIdx ) { //act as if color color select button was pressed actionColorsColor( ); return; } //set active color index colorIdx = idx; //update color settings showColorsColor( ); showColorsAlpha( ); //set color of frame editor to new color frameEditor.setColor( colors[colorIdx] ); } //show color private void showColorsColor( ) { int red, green, blue; String hex; //get color components red = colors[colorIdx].getRed( ); green = colors[colorIdx].getGreen( ); blue = colors[colorIdx].getBlue( ); //color button iconFromColor( iconColorsColor, new Color( red, green, blue ) ); buttonColorsColor.repaint( ); //color text if( red < 0x10 ) hex = "0" + Integer.toHexString( red ); else hex = Integer.toHexString( red ); if( green < 0x10 ) hex += "0" + Integer.toHexString( green ); else hex += Integer.toHexString( green ); if( blue < 0x10 ) hex += "0" + Integer.toHexString( blue ); else hex += Integer.toHexString( blue ); textColorsColor.setText( hex.toUpperCase( ) ); } //color select button was pressed private void actionColorsColor( ) { Color color; //get current color with full alpha color = new Color( colors[colorIdx].getRed( ), colors[colorIdx].getGreen( ), colors[colorIdx].getBlue( ) ); //show color select dialog color = JColorChooser.showDialog( dialogParent, "Blimp - Choose Color...", color ); if( color == null ) //dialog was cancelled return; //save new color colors[colorIdx] = new Color( color.getRed( ), color.getGreen( ), color.getBlue( ), colors[colorIdx].getAlpha( ) ); //redisplay new color showColorsColor( ); //update color icon of active color iconFromColor( iconsColor[colorIdx], colors[colorIdx] ); buttonsColor[colorIdx].repaint( ); //set color of frame editor to new color frameEditor.setColor( colors[colorIdx] ); } //new color text is being entered private void changeColorsColor( ) { String txt; int red, green, blue; //get color text txt = textColorsColor.getText( ); //standard color is black red = 0; green = 0; blue = 0; //get new color try { if( txt.length( ) >= 2 ) red = Integer.parseInt( txt.substring( 0, 2 ), 0x10 ); if( txt.length( ) >= 4 ) green = Integer.parseInt( txt.substring( 2, 4 ), 0x10 ); if( txt.length( ) >= 6 ) blue = Integer.parseInt( txt.substring( 4, 6 ), 0x10 ); } catch( NumberFormatException e ) { } //save new color colors[colorIdx] = new Color( red, green, blue, colors[colorIdx].getAlpha( ) ); //set color of frame editor to new color frameEditor.setColor( colors[colorIdx] ); } //new color text was entered private void validateColorsColor( ) { //process changes changeColorsColor( ); //redisplay new color showColorsColor( ); //update color icon of active color iconFromColor( iconsColor[colorIdx], colors[colorIdx] ); buttonsColor[colorIdx].repaint( ); } //show color's alpha value private void showColorsAlpha( ) { int alpha; String hex; //get alpha value alpha = colors[colorIdx].getAlpha( ); //alpha slider sliderColorsAlpha.setValue( alpha ); //alpha text if( alpha < 0x10 ) hex = "0" + Integer.toHexString( alpha ); else hex = Integer.toHexString( alpha ); textColorsAlpha.setText( hex.toUpperCase( ) ); } //color's alpha value changed private void stateColorsAlpha( ) { int alpha; String hex; //get new alpha value alpha = sliderColorsAlpha.getValue( ); //update active color colors[colorIdx] = new Color( colors[colorIdx].getRed( ), colors[colorIdx].getGreen( ), colors[colorIdx].getBlue( ), alpha ); //update alpha text if( alpha < 0x10 ) hex = "0" + Integer.toHexString( alpha ); else hex = Integer.toHexString( alpha ); textColorsAlpha.setText( hex.toUpperCase( ) ); //update color icon of active color iconFromColor( iconsColor[colorIdx], colors[colorIdx] ); buttonsColor[colorIdx].repaint( ); //set color of frame editor to new color frameEditor.setColor( colors[colorIdx] ); } //new alpha text is being entered private void changeColorsAlpha( ) { String txt; int alpha; //get alpha text txt = textColorsAlpha.getText( ); //standard alpha is full alpha = 255; //get new alpha try { if( txt.length( ) >= 2 ) alpha = Integer.parseInt( txt.substring( 0, 2 ), 0x10 ); } catch( NumberFormatException e ) { } //save new alpha colors[colorIdx] = new Color( colors[colorIdx].getRed( ), colors[colorIdx].getGreen( ), colors[colorIdx].getBlue( ), alpha ); //set color of frame editor to new color frameEditor.setColor( colors[colorIdx] ); } //new alpha text was entered private void validateColorsAlpha( ) { //process changes changeColorsAlpha( ); //redisplay new alpha value showColorsAlpha( ); //update color icon of active color iconFromColor( iconsColor[colorIdx], colors[colorIdx] ); buttonsColor[colorIdx].repaint( ); } public void windowActivated( WindowEvent e ) { } public void windowDeactivated( WindowEvent e ) { } public void windowOpened( WindowEvent e ) { } public void windowClosing( WindowEvent e ) { actionFileQuit( ); //act as "File Quit" } public void windowClosed( WindowEvent e ) { } public void windowIconified( WindowEvent e ) { } public void windowDeiconified( WindowEvent e ) { } //some GUI action was perfomed public void actionPerformed( ActionEvent e ) { int i; if( e.getSource( ) == menuFileNew ) actionFileNew( ); else if( e.getSource( ) == menuFileLoad ) actionFileLoad( ); else if( e.getSource( ) == menuFileSave ) actionFileSave( ); else if( e.getSource( ) == menuFileSaveAs ) actionFileSaveAs( ); else if( e.getSource( ) == menuFileQuit ) actionFileQuit( ); else if( e.getSource( ) == menuInfoShow ) actionInfoShow( ); else if( e.getSource( ) == menuInfoAdd ) actionInfoAdd( ); else if( e.getSource( ) == menuInfoDelete ) actionInfoDelete( ); else if( e.getSource( ) == menuEditResize ) actionEditResize( ); else if( e.getSource( ) == menuEditScale ) actionEditScale( ); else if( e.getSource( ) == menuEditInsertFrame ) actionEditInsertFrame( ); else if( e.getSource( ) == menuEditDuplicateFrame ) actionEditDuplicateFrame( ); else if( e.getSource( ) == menuEditDeleteFrame ) actionEditDeleteFrame( ); else if( e.getSource( ) == menuEditImportImages ) actionEditImportImages( ); else if( e.getSource( ) == menuEditImportMovie ) actionEditImportMovie( ); else if( e.getSource( ) == menuFrameSelNone ) actionFrameSelNone( ); else if( e.getSource( ) == menuFrameSelSingle ) actionFrameSelSingle( ); else if( e.getSource( ) == menuFrameSelStart ) actionFrameSelStart( ); else if( e.getSource( ) == menuFrameSelEnd ) actionFrameSelEnd( ); else if( e.getSource( ) == menuFrameSelCopy ) actionFrameSelCopy( ); else if( e.getSource( ) == menuFrameSelMove ) actionFrameSelMove( ); else if( e.getSource( ) == menuFrameSelReverse ) actionFrameSelReverse( ); else if( e.getSource( ) == menuFrameSelDelete ) actionFrameSelDelete( ); else if( e.getSource( ) == menuPlayStart ) actionPlayStart( ); else if( e.getSource( ) == menuPlayStop ) actionPlayStop( ); else if( e.getSource( ) == timerPlay ) actionPlayTimer( ); else if( e.getSource( ) == menuHelpAbout ) actionHelpAbout( ); else if( e.getSource( ) == textDuration ) validateDuration( ); else if( e.getSource( ) == buttonToolsNone ) frameEditor.setTool( BlinkenFrameEditor.toolNone ); else if( e.getSource( ) == buttonToolsColorPicker ) frameEditor.setTool( BlinkenFrameEditor.toolColorPicker ); else if( e.getSource( ) == buttonToolsDot ) frameEditor.setTool( BlinkenFrameEditor.toolDot ); else if( e.getSource( ) == buttonToolsLine ) frameEditor.setTool( BlinkenFrameEditor.toolLine ); else if( e.getSource( ) == buttonToolsRect ) frameEditor.setTool( BlinkenFrameEditor.toolRect ); else if( e.getSource( ) == buttonToolsFilledRect ) frameEditor.setTool( BlinkenFrameEditor.toolFilledRect ); else if( e.getSource( ) == buttonToolsCircle ) frameEditor.setTool( BlinkenFrameEditor.toolCircle ); else if( e.getSource( ) == buttonToolsFilledCircle ) frameEditor.setTool( BlinkenFrameEditor.toolFilledCircle ); else if( e.getSource( ) == buttonToolsCopy ) frameEditor.setTool( BlinkenFrameEditor.toolCopy ); else if( e.getSource( ) == buttonToolsPaste ) frameEditor.setTool( BlinkenFrameEditor.toolPaste ); else if( e.getSource( ) == buttonActionsInvert ) frameEditor.actionInvert( ); else if( e.getSource( ) == buttonActionsRotate90 ) frameEditor.actionRotate90( ); else if( e.getSource( ) == buttonActionsRotate180 ) frameEditor.actionRotate180( ); else if( e.getSource( ) == buttonActionsRotate270 ) frameEditor.actionRotate270( ); else if( e.getSource( ) == buttonActionsMirrorHor ) frameEditor.actionMirrorHor( ); else if( e.getSource( ) == buttonActionsMirrorVer ) frameEditor.actionMirrorVer( ); else if( e.getSource( ) == buttonActionsMirrorDiag ) frameEditor.actionMirrorDiag( ); else if( e.getSource( ) == buttonActionsMirrorDiag2 ) frameEditor.actionMirrorDiag2( ); else if( e.getSource( ) == buttonActionsRollLeft ) frameEditor.actionRollLeft( ); else if( e.getSource( ) == buttonActionsRollRight ) frameEditor.actionRollRight( ); else if( e.getSource( ) == buttonActionsRollUp ) frameEditor.actionRollUp( ); else if( e.getSource( ) == buttonActionsRollDown ) frameEditor.actionRollDown( ); else if( e.getSource( ) == buttonActionsUndo ) frameEditor.actionUndo( ); else if( e.getSource( ) == buttonActionsRedo ) frameEditor.actionRedo( ); else if( e.getSource( ) == buttonEditInsertFrame ) actionEditInsertFrame( ); else if( e.getSource( ) == buttonEditDuplicateFrame ) actionEditDuplicateFrame( ); else if( e.getSource( ) == buttonEditDeleteFrame ) actionEditDeleteFrame( ); else if( e.getSource( ) == buttonColorsColor ) actionColorsColor( ); else if( e.getSource( ) == textColorsColor ) validateColorsColor( ); else if( e.getSource( ) == textColorsAlpha ) validateColorsAlpha( ); else { for( i = 0; i < constColorCnt; i++ ) if( e.getSource( ) == buttonsColor[i] ) break; if( i < constColorCnt ) actionColorIdx( i ); } } //some GUI value was adjusted public void adjustmentValueChanged( AdjustmentEvent e ) { if( e.getSource( ) == scrollFrames ) stateFrames( ); } //some GUI state changed public void stateChanged( ChangeEvent e ) { if( e.getSource( ) == sliderFrameZoom ) stateFrameZoom( ); else if( e.getSource( ) == sliderColorsAlpha ) stateColorsAlpha( ); } //a control got the focus public void focusGained( FocusEvent e ) { } //a control lost the focus public void focusLost( FocusEvent e ) { if( e.getSource( ) == textDuration ) validateDuration( ); else if( e.getSource( ) == textColorsColor ) validateColorsColor( ); else if( e.getSource( ) == textColorsAlpha ) validateColorsAlpha( ); } //something was changed in a document public void changedUpdate( DocumentEvent e ) { if( e.getDocument( ) == textDuration.getDocument( ) ) changeDuration( ); else if( e.getDocument( ) == textColorsColor.getDocument( ) ) changeColorsColor( ); else if( e.getDocument( ) == textColorsAlpha.getDocument( ) ) changeColorsAlpha( ); } //something was inserted into a document public void insertUpdate( DocumentEvent e ) { if( e.getDocument( ) == textDuration.getDocument( ) ) changeDuration( ); } //something was removed from a document public void removeUpdate( DocumentEvent e ) { if( e.getDocument( ) == textDuration.getDocument( ) ) changeDuration( ); } //info text of frame editor changed public void blinkenFrameEditorInfo( String info ) { labelFrameInfo.setText( info ); } //a color was picked in the frame editor public void blinkenFrameEditorColorPicked( Color color ) { //save new color colors[colorIdx] = color; //redisplay new color (incl. alpha) showColorsColor( ); showColorsAlpha( ); //update color icon of active color iconFromColor( iconsColor[colorIdx], colors[colorIdx] ); buttonsColor[colorIdx].repaint( ); //set color of frame editor to new color frameEditor.setColor( colors[colorIdx] ); } //the current frame was changed in the frame editor public void blinkenFrameEditorFrameChanged( ) { curMovieChanged = true; } //the possibility to perfon an undo or redo operation changed public void blinkenFrameEditorCanUndoRedo( boolean canUndo, boolean canRedo ) { buttonActionsUndo.setEnabled( canUndo ); buttonActionsRedo.setEnabled( canRedo ); } //entry point of main thread public void run( ) { int i, val; Dimension size; Insets smallMargin; //initialize current movie, frame curDir = new File( "." ); curMovie = new BlinkenMovie( defHeight, defWidth, defChannels, defMaxval ); curMovie.insertInfo( 0, "creator", "Blimp (version 1.2 date 2005-12-19)" ); curMovie.insertFrame( 0, new BlinkenFrame( defHeight, defWidth, defChannels, defMaxval, defDuration ) ); curFrame = null; //runnning as full application if( isFullApp ) { //create main window JFrame.setDefaultLookAndFeelDecorated( true ); frame = new JFrame( "Blimp" ); frame.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE ); frame.addWindowListener( this ); //create menu bar menubar = new JMenuBar( ); frame.setJMenuBar( menubar ); //create main panel panel = new JPanel( new BorderLayout( 5, 5 ) ); frame.getContentPane( ).add( panel ); //use main window as parent for dialogs dialogParent = frame; } //runnning as applet else { //no main window - applet is main window frame = null; //create menu bar menubar = new JMenuBar( ); setJMenuBar( menubar ); //create main panel panel = new JPanel( new BorderLayout( 5, 5 ) ); getContentPane( ).add( panel ); //use applet as parent for dialogs dialogParent = this; } //create menus //file menu menuFile = new JMenu( "File" ); menuFile.setMnemonic( KeyEvent.VK_F ); menubar.add( menuFile ); menuFileNew = new JMenuItem( "New" ); menuFileNew.setMnemonic( KeyEvent.VK_N ); menuFileNew.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, KeyEvent.CTRL_MASK ) ); menuFileNew.addActionListener( this ); menuFile.add( menuFileNew ); menuFileLoad = new JMenuItem( "Load..." ); menuFileLoad.setMnemonic( KeyEvent.VK_L ); menuFileLoad.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_L, KeyEvent.CTRL_MASK ) ); menuFileLoad.addActionListener( this ); menuFile.add( menuFileLoad ); menuFileSave = new JMenuItem( "Save" ); menuFileSave.setMnemonic( KeyEvent.VK_S ); menuFileSave.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_S, KeyEvent.CTRL_MASK ) ); menuFileSave.addActionListener( this ); menuFile.add( menuFileSave ); menuFileSaveAs = new JMenuItem( "Save as..." ); menuFileSaveAs.setMnemonic( KeyEvent.VK_A ); menuFileSaveAs.setDisplayedMnemonicIndex( 5 ); menuFileSaveAs.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_A, KeyEvent.CTRL_MASK ) ); menuFileSaveAs.addActionListener( this ); menuFile.add( menuFileSaveAs ); if( isFullApp ) menuFile.addSeparator( ); menuFileQuit = new JMenuItem( "Quit" ); menuFileQuit.setMnemonic( KeyEvent.VK_Q ); menuFileQuit.addActionListener( this ); if( isFullApp ) menuFile.add( menuFileQuit ); //information menu menuInfo = new JMenu( "Information" ); menuInfo.setMnemonic( KeyEvent.VK_I ); menubar.add( menuInfo ); menuInfoShow = new JMenuItem( "Show..." ); menuInfoShow.setMnemonic( KeyEvent.VK_S ); menuInfoShow.addActionListener( this ); menuInfo.add( menuInfoShow ); menuInfoAdd = new JMenuItem( "Add..." ); menuInfoAdd.setMnemonic( KeyEvent.VK_A ); menuInfoAdd.addActionListener( this ); menuInfo.add( menuInfoAdd ); menuInfoDelete = new JMenuItem( "Delete..." ); menuInfoDelete.setMnemonic( KeyEvent.VK_D ); menuInfoDelete.addActionListener( this ); menuInfo.add( menuInfoDelete ); //edit menu menuEdit = new JMenu( "Edit" ); menuEdit.setMnemonic( KeyEvent.VK_E ); menubar.add( menuEdit ); menuEditResize = new JMenuItem( "Resize Movie..." ); menuEditResize.setMnemonic( KeyEvent.VK_R ); menuEditResize.addActionListener( this ); menuEdit.add( menuEditResize ); menuEditScale = new JMenuItem( "Scale Movie..." ); menuEditScale.setMnemonic( KeyEvent.VK_S ); menuEditScale.addActionListener( this ); menuEdit.add( menuEditScale ); menuEdit.addSeparator( ); menuEditInsertFrame = new JMenuItem( "Insert Frame" ); menuEditInsertFrame.setMnemonic( KeyEvent.VK_I ); menuEditInsertFrame.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_I, KeyEvent.CTRL_MASK ) ); menuEditInsertFrame.addActionListener( this ); menuEdit.add( menuEditInsertFrame ); menuEditDuplicateFrame = new JMenuItem( "Duplicate Frame" ); menuEditDuplicateFrame.setMnemonic( KeyEvent.VK_D ); menuEditDuplicateFrame.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_D, KeyEvent.CTRL_MASK ) ); menuEditDuplicateFrame.setEnabled( false ); menuEditDuplicateFrame.addActionListener( this ); menuEdit.add( menuEditDuplicateFrame ); menuEditDeleteFrame = new JMenuItem( "Delete Frame" ); menuEditDeleteFrame.setMnemonic( KeyEvent.VK_L ); menuEditDeleteFrame.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_X, KeyEvent.CTRL_MASK ) ); menuEditDeleteFrame.setEnabled( false ); menuEditDeleteFrame.addActionListener( this ); menuEdit.add( menuEditDeleteFrame ); menuEdit.addSeparator( ); menuEditImportImages = new JMenuItem( "Import Images..." ); menuEditImportImages.setMnemonic( KeyEvent.VK_P ); menuEditImportImages.setDisplayedMnemonicIndex( 7 ); menuEditImportImages.addActionListener( this ); menuEdit.add( menuEditImportImages ); menuEditImportMovie = new JMenuItem( "Import Movie..." ); menuEditImportMovie.setMnemonic( KeyEvent.VK_M ); menuEditImportMovie.setDisplayedMnemonicIndex( 7 ); menuEditImportMovie.addActionListener( this ); menuEdit.add( menuEditImportMovie ); //frame selection menu menuFrameSel = new JMenu( "Frame-Selection" ); menuFrameSel.setMnemonic( KeyEvent.VK_S ); menubar.add( menuFrameSel ); menuFrameSelNone = new JMenuItem( "Select None" ); menuFrameSelNone.setMnemonic( KeyEvent.VK_N ); menuFrameSelNone.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) ); menuFrameSelNone.addActionListener( this ); menuFrameSel.add( menuFrameSelNone ); menuFrameSelSingle = new JMenuItem( "Select Single Frame" ); menuFrameSelSingle.setMnemonic( KeyEvent.VK_F ); menuFrameSelSingle.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_F, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) ); menuFrameSelSingle.setEnabled( false ); menuFrameSelSingle.addActionListener( this ); menuFrameSel.add( menuFrameSelSingle ); menuFrameSelStart = new JMenuItem( "Start of Selection" ); menuFrameSelStart.setMnemonic( KeyEvent.VK_S ); menuFrameSelStart.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_S, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) ); menuFrameSelStart.setEnabled( false ); menuFrameSelStart.addActionListener( this ); menuFrameSel.add( menuFrameSelStart ); menuFrameSelEnd = new JMenuItem( "End of Selection" ); menuFrameSelEnd.setMnemonic( KeyEvent.VK_E ); menuFrameSelEnd.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_E, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) ); menuFrameSelEnd.setEnabled( false ); menuFrameSelEnd.addActionListener( this ); menuFrameSel.add( menuFrameSelEnd ); menuFrameSel.addSeparator( ); menuFrameSelCopy = new JMenuItem( "Copy" ); menuFrameSelCopy.setMnemonic( KeyEvent.VK_C ); menuFrameSelCopy.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_C, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) ); menuFrameSelCopy.setEnabled( false ); menuFrameSelCopy.addActionListener( this ); menuFrameSel.add( menuFrameSelCopy ); menuFrameSelMove = new JMenuItem( "Move" ); menuFrameSelMove.setMnemonic( KeyEvent.VK_M ); menuFrameSelMove.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_M, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) ); menuFrameSelMove.setEnabled( false ); menuFrameSelMove.addActionListener( this ); menuFrameSel.add( menuFrameSelMove ); menuFrameSelReverse = new JMenuItem( "Reverse" ); menuFrameSelReverse.setMnemonic( KeyEvent.VK_R ); menuFrameSelReverse.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_R, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) ); menuFrameSelReverse.setEnabled( false ); menuFrameSelReverse.addActionListener( this ); menuFrameSel.add( menuFrameSelReverse ); menuFrameSelDelete = new JMenuItem( "Delete" ); menuFrameSelDelete.setMnemonic( KeyEvent.VK_L ); menuFrameSelDelete.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_X, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK ) ); menuFrameSelDelete.setEnabled( false ); menuFrameSelDelete.addActionListener( this ); menuFrameSel.add( menuFrameSelDelete ); //play menu menuPlay = new JMenu( "Play" ); menuPlay.setMnemonic( KeyEvent.VK_P ); menubar.add( menuPlay ); menuPlayStart = new JMenuItem( "Start" ); menuPlayStart.setMnemonic( KeyEvent.VK_S ); menuPlayStart.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_F11, 0 ) ); menuPlayStart.addActionListener( this ); menuPlay.add( menuPlayStart ); menuPlayStop = new JMenuItem( "Stop" ); menuPlayStop.setMnemonic( KeyEvent.VK_P ); menuPlayStop.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_F12, 0 ) ); menuPlayStop.setEnabled( false ); menuPlayStop.addActionListener( this ); menuPlay.add( menuPlayStop ); menuPlay.addSeparator( ); menuPlayBegin = new JCheckBoxMenuItem( "From Begin", false ); menuPlayBegin.setMnemonic( KeyEvent.VK_B ); menuPlayBegin.addActionListener( this ); menuPlay.add( menuPlayBegin ); menuPlayLoop = new JCheckBoxMenuItem( "Looped", false ); menuPlayLoop.setMnemonic( KeyEvent.VK_L ); menuPlayLoop.addActionListener( this ); menuPlay.add( menuPlayLoop ); //help menu menuHelp = new JMenu( "Help" ); menuHelp.setMnemonic( KeyEvent.VK_H ); menubar.add( menuHelp ); menuHelpAbout = new JMenuItem( "About..." ); menuHelpAbout.setMnemonic( KeyEvent.VK_A ); menuHelpAbout.addActionListener( this ); menuHelp.add( menuHelpAbout ); //create controls smallMargin = new Insets( 1, 1, 1, 1 ); panel.setBorder( new EmptyBorder( 5, 5, 5, 5 ) ); //status bar panelStatus = new JPanel( new BorderLayout( 5, 5 ) ); panel.add( panelStatus, BorderLayout.SOUTH ); panelStatus.add( new JSeparator( JSeparator.HORIZONTAL ), BorderLayout.NORTH ); labelStatus = new JLabel( "ready..." ); panelStatus.add( labelStatus, BorderLayout.CENTER ); //main panel panelMain = new JPanel( new BorderLayout( 5, 5 ) ); panel.add( panelMain, BorderLayout.CENTER ); //frames panel panelFrames = new JPanel( new BorderLayout( 5, 5 ) ); panelMain.add( panelFrames, BorderLayout.SOUTH ); scrollFrames = new JScrollBar( SwingConstants.HORIZONTAL, 0, 0, 0, 0 ); scrollFrames.addAdjustmentListener( this ); panelFrames.add( scrollFrames, BorderLayout.CENTER ); labelFrames = new JLabel( "frame: -/0" ); labelFrames.setLabelFor( scrollFrames ); panelFrames.add( labelFrames, BorderLayout.WEST ); labelSelFrames = new JLabel( "selected: -/-" ); labelSelFrames.setLabelFor( scrollFrames ); panelFrames.add( labelSelFrames, BorderLayout.EAST ); //outer and middle frame panel panelOuterFrame = new JPanel( new BorderLayout( 5, 5 ) ); panelMain.add( panelOuterFrame, BorderLayout.CENTER ); panelOuterFrame.add( new JSeparator( JSeparator.HORIZONTAL ), BorderLayout.SOUTH ); panelMiddleFrame = new JPanel( new BorderLayout( 5, 5 ) ); panelOuterFrame.add( panelMiddleFrame, BorderLayout.CENTER ); panelMiddleFrame.add( new JSeparator( JSeparator.VERTICAL ), BorderLayout.WEST ); panelMiddleFrame.add( new JSeparator( JSeparator.VERTICAL ), BorderLayout.EAST ); //frame panel panelFrame = new JPanel( new BorderLayout( 5, 5 ) ); panelMiddleFrame.add( panelFrame, BorderLayout.CENTER ); sliderFrameZoom = new JSlider( JSlider.VERTICAL, 0, 6, 3 ); sliderFrameZoom.setSnapToTicks( true ); sliderFrameZoom.setInverted( true ); sliderFrameZoom.addChangeListener( this ); sliderFrameZoom.setToolTipText( "Zoom" ); panelFrame.add( sliderFrameZoom, BorderLayout.EAST ); frameEditor = new BlinkenFrameEditor( ); frameEditor.setZoom( sliderFrameZoom.getValue( ) ); scrollpaneFrame = new JScrollPane( frameEditor ); panelFrame.add( scrollpaneFrame, BorderLayout.CENTER ); labelFrameInfo = new JLabel( "", JLabel.CENTER ); labelFrameInfo.setLabelFor( frameEditor ); panelFrame.add( labelFrameInfo, BorderLayout.NORTH ); frameEditor.setEditorListener( this ); panelDuration = new JPanel( new FlowLayout( FlowLayout.CENTER, 5, 5 ) ); panelFrame.add( panelDuration, BorderLayout.SOUTH ); textDuration = new JTextField( 5 ); textDuration.setHorizontalAlignment( JTextField.CENTER ); textDuration.setEnabled( false ); textDuration.getDocument( ).addDocumentListener( this ); textDuration.addActionListener( this ); textDuration.addFocusListener( this ); labelDuration = new JLabel( "duration (ms): " ); labelDuration.setLabelFor( textDuration ); panelDuration.add( labelDuration ); panelDuration.add( textDuration ); //tool, action and edit panels panelOuterEdit = new JPanel( new BorderLayout( 5, 5 ) ); panelOuterFrame.add( panelOuterEdit, BorderLayout.WEST ); panelOuterTools = new JPanel( new GridLayout( 2, 1, 5, 5 ) ); panelOuterEdit.add( panelOuterTools, BorderLayout.CENTER ); panelMiddleTools = new JPanel( new BorderLayout( 5, 5 ) ); panelOuterTools.add( panelMiddleTools ); panelTools = new JPanel( new GridLayout( 4, 3, 5, 5 ) ); panelMiddleTools.add( panelTools, BorderLayout.CENTER ); panelMiddleTools.add( new JSeparator( JSeparator.HORIZONTAL ), BorderLayout.SOUTH ); panelActions = new JPanel( new GridLayout( 5, 3, 5, 5 ) ); panelOuterTools.add( panelActions ); panelMiddleEdit = new JPanel( new BorderLayout( 5, 5 ) ); panelOuterEdit.add( panelMiddleEdit, BorderLayout.SOUTH ); panelMiddleEdit.add( new JSeparator( JSeparator.HORIZONTAL ), BorderLayout.NORTH ); panelEdit = new JPanel( new GridLayout( 1, 3, 5, 5 ) ); panelMiddleEdit.add( panelEdit, BorderLayout.CENTER ); //tool buttons groupTools = new ButtonGroup( ); buttonToolsNone = new JToggleButton( ); buttonToolsNone.setMargin( smallMargin ); buttonToolsNone.setToolTipText( "no tool" ); buttonToolsNone.addActionListener( this ); groupTools.add( buttonToolsNone ); panelTools.add( buttonToolsNone ); buttonToolsColorPicker = new JToggleButton( loadImageIcon( "ColorPicker.png" ) ); buttonToolsColorPicker.setMargin( smallMargin ); buttonToolsColorPicker.setToolTipText( "Color Picker" ); buttonToolsColorPicker.addActionListener( this ); groupTools.add( buttonToolsColorPicker ); panelTools.add( buttonToolsColorPicker ); buttonToolsDot = new JToggleButton( loadImageIcon( "Dot.png" ) ); buttonToolsDot.setMargin( smallMargin ); buttonToolsDot.setToolTipText( "Dot" ); buttonToolsDot.addActionListener( this ); groupTools.add( buttonToolsDot ); panelTools.add( buttonToolsDot ); buttonToolsLine = new JToggleButton( loadImageIcon( "Line.png" ) ); buttonToolsLine.setMargin( smallMargin ); buttonToolsLine.setToolTipText( "Line" ); buttonToolsLine.addActionListener( this ); groupTools.add( buttonToolsLine ); panelTools.add( buttonToolsLine ); buttonToolsRect = new JToggleButton( loadImageIcon( "Rectangle.png" ) ); buttonToolsRect.setMargin( smallMargin ); buttonToolsRect.setToolTipText( "Rectangle" ); buttonToolsRect.addActionListener( this ); groupTools.add( buttonToolsRect ); panelTools.add( buttonToolsRect ); buttonToolsFilledRect = new JToggleButton( loadImageIcon( "FilledRectangle.png" ) ); buttonToolsFilledRect.setMargin( smallMargin ); buttonToolsFilledRect.setToolTipText( "Filled Rectangle" ); buttonToolsFilledRect.addActionListener( this ); groupTools.add( buttonToolsFilledRect ); panelTools.add( buttonToolsFilledRect ); panelTools.add( new JLabel( ) ); buttonToolsCircle = new JToggleButton( loadImageIcon( "Circle.png" ) ); buttonToolsCircle.setMargin( smallMargin ); buttonToolsCircle.setToolTipText( "Circle" ); buttonToolsCircle.addActionListener( this ); groupTools.add( buttonToolsCircle ); panelTools.add( buttonToolsCircle ); buttonToolsFilledCircle = new JToggleButton( loadImageIcon( "FilledCircle.png" ) ); buttonToolsFilledCircle.setMargin( smallMargin ); buttonToolsFilledCircle.setToolTipText( "Filled Circle" ); buttonToolsFilledCircle.addActionListener( this ); groupTools.add( buttonToolsFilledCircle ); panelTools.add( buttonToolsFilledCircle ); panelTools.add( new JLabel( ) ); buttonToolsCopy = new JToggleButton( loadImageIcon( "Copy.png" ) ); buttonToolsCopy.setMargin( smallMargin ); buttonToolsCopy.setToolTipText( "Copy" ); buttonToolsCopy.addActionListener( this ); groupTools.add( buttonToolsCopy ); panelTools.add( buttonToolsCopy ); buttonToolsPaste = new JToggleButton( loadImageIcon( "Paste.png" ) ); buttonToolsPaste.setMargin( smallMargin ); buttonToolsPaste.setToolTipText( "Paste" ); buttonToolsPaste.addActionListener( this ); groupTools.add( buttonToolsPaste ); panelTools.add( buttonToolsPaste ); buttonToolsNone.setSelected( true ); frameEditor.setTool( BlinkenFrameEditor.toolNone ); //action buttons buttonActionsInvert = new JButton( loadImageIcon( "Invert.png" ) ); buttonActionsInvert.setMargin( smallMargin ); buttonActionsInvert.setToolTipText( "Invert" ); buttonActionsInvert.addActionListener( this ); panelActions.add( buttonActionsInvert ); buttonActionsMirrorHor = new JButton( loadImageIcon( "MirrorHor.png" ) ); buttonActionsMirrorHor.setMargin( smallMargin ); buttonActionsMirrorHor.setToolTipText( "Mirror Horizontally" ); buttonActionsMirrorHor.addActionListener( this ); panelActions.add( buttonActionsMirrorHor ); buttonActionsRollLeft = new JButton( loadImageIcon( "RollLeft.png" ) ); buttonActionsRollLeft.setMargin( smallMargin ); buttonActionsRollLeft.setToolTipText( "Roll Left" ); buttonActionsRollLeft.addActionListener( this ); panelActions.add( buttonActionsRollLeft ); buttonActionsRotate90 = new JButton( loadImageIcon( "Rotate90.png" ) ); buttonActionsRotate90.setMargin( smallMargin ); buttonActionsRotate90.setToolTipText( "Rotate 90 Degrees" ); buttonActionsRotate90.addActionListener( this ); panelActions.add( buttonActionsRotate90 ); buttonActionsMirrorVer = new JButton( loadImageIcon( "MirrorVer.png" ) ); buttonActionsMirrorVer.setMargin( smallMargin ); buttonActionsMirrorVer.setToolTipText( "Mirror Vertically" ); buttonActionsMirrorVer.addActionListener( this ); panelActions.add( buttonActionsMirrorVer ); buttonActionsRollRight = new JButton( loadImageIcon( "RollRight.png" ) ); buttonActionsRollRight.setMargin( smallMargin ); buttonActionsRollRight.setToolTipText( "Roll Right" ); buttonActionsRollRight.addActionListener( this ); panelActions.add( buttonActionsRollRight ); buttonActionsRotate180 = new JButton( loadImageIcon( "Rotate180.png" ) ); buttonActionsRotate180.setMargin( smallMargin ); buttonActionsRotate180.setToolTipText( "Rotate 180 Degrees" ); buttonActionsRotate180.addActionListener( this ); panelActions.add( buttonActionsRotate180 ); buttonActionsMirrorDiag = new JButton( loadImageIcon( "MirrorDiag.png" ) ); buttonActionsMirrorDiag.setMargin( smallMargin ); buttonActionsMirrorDiag.setToolTipText( "Mirror Diagonally (\\)" ); buttonActionsMirrorDiag.addActionListener( this ); panelActions.add( buttonActionsMirrorDiag ); buttonActionsRollUp = new JButton( loadImageIcon( "RollUp.png" ) ); buttonActionsRollUp.setMargin( smallMargin ); buttonActionsRollUp.setToolTipText( "Roll Up" ); buttonActionsRollUp.addActionListener( this ); panelActions.add( buttonActionsRollUp ); buttonActionsRotate270 = new JButton( loadImageIcon( "Rotate270.png" ) ); buttonActionsRotate270.setMargin( smallMargin ); buttonActionsRotate270.setToolTipText( "Rotate 270 Degrees" ); buttonActionsRotate270.addActionListener( this ); panelActions.add( buttonActionsRotate270 ); buttonActionsMirrorDiag2 = new JButton( loadImageIcon( "MirrorDiag2.png" ) ); buttonActionsMirrorDiag2.setMargin( smallMargin ); buttonActionsMirrorDiag2.setToolTipText( "Mirror Diagonally (/)" ); buttonActionsMirrorDiag2.addActionListener( this ); panelActions.add( buttonActionsMirrorDiag2 ); buttonActionsRollDown = new JButton( loadImageIcon( "RollDown.png" ) ); buttonActionsRollDown.setMargin( smallMargin ); buttonActionsRollDown.setToolTipText( "Roll Down" ); buttonActionsRollDown.addActionListener( this ); panelActions.add( buttonActionsRollDown ); panelActions.add( new JLabel( ) ); buttonActionsUndo = new JButton( loadImageIcon( "Undo.png" ) ); buttonActionsUndo.setMargin( smallMargin ); buttonActionsUndo.setToolTipText( "Undo" ); buttonActionsUndo.setEnabled( false ); buttonActionsUndo.addActionListener( this ); panelActions.add( buttonActionsUndo ); buttonActionsRedo = new JButton( loadImageIcon( "Redo.png" ) ); buttonActionsRedo.setMargin( smallMargin ); buttonActionsRedo.setToolTipText( "Redo" ); buttonActionsRedo.setEnabled( false ); buttonActionsRedo.addActionListener( this ); panelActions.add( buttonActionsRedo ); //edit buttons buttonEditInsertFrame = new JButton( loadImageIcon( "InsertFrame.png" ) ); buttonEditInsertFrame.setMargin( smallMargin ); buttonEditInsertFrame.setToolTipText( "Insert Frame" ); buttonEditInsertFrame.addActionListener( this ); panelEdit.add( buttonEditInsertFrame ); buttonEditDuplicateFrame = new JButton( loadImageIcon( "DuplicateFrame.png" ) ); buttonEditDuplicateFrame.setMargin( smallMargin ); buttonEditDuplicateFrame.setToolTipText( "Duplicate Frame" ); buttonEditDuplicateFrame.addActionListener( this ); panelEdit.add( buttonEditDuplicateFrame ); buttonEditDeleteFrame = new JButton( loadImageIcon( "DeleteFrame.png" ) ); buttonEditDeleteFrame.setMargin( smallMargin ); buttonEditDeleteFrame.setToolTipText( "Delete Frame" ); buttonEditDeleteFrame.addActionListener( this ); panelEdit.add( buttonEditDeleteFrame ); //color panel panelColors = new JPanel( new GridLayout( 2, 1, 5, 5 ) ); panelOuterFrame.add( panelColors, BorderLayout.EAST ); panelColorsChoose = new JPanel( new GridLayout( constColorCntY, constColorCntX, 5, 5 ) ); panelColors.add( panelColorsChoose ); buttonsColor = new JToggleButton[constColorCnt]; groupColor = new ButtonGroup( ); for( i = 0; i < constColorCnt; i++ ) { buttonsColor[i] = new JToggleButton( ); buttonsColor[i].setMargin( smallMargin ); buttonsColor[i].addActionListener( this ); groupColor.add( buttonsColor[i] ); panelColorsChoose.add( buttonsColor[i] ); } //color panel - settings panelColorsSettings = new JPanel( new GridLayout( 4, 1, 5, 0 ) ); panelColors.add( panelColorsSettings ); labelColorsColor = new JLabel( "color:" ); labelColorsColor.setVerticalAlignment( JLabel.BOTTOM ); panelColorsSettings.add( labelColorsColor ); panelColorsColor = new JPanel( new FlowLayout( FlowLayout.CENTER, 5, 3 ) ); panelColorsSettings.add( panelColorsColor ); buttonColorsColor = new JButton( ); buttonColorsColor.setMargin( smallMargin ); buttonColorsColor.addActionListener( this ); panelColorsColor.add( buttonColorsColor ); textColorsColor = new JTextField( "FFFFFF", 6 ); textColorsColor.setHorizontalAlignment( JTextField.CENTER ); textColorsColor.addActionListener( this ); textColorsColor.addFocusListener( this ); panelColorsColor.add( textColorsColor ); labelColorsColor.setLabelFor( panelColorsColor ); labelColorsAlpha = new JLabel( "alpha:" ); labelColorsAlpha.setVerticalAlignment( JLabel.BOTTOM ); panelColorsSettings.add( labelColorsAlpha ); panelColorsAlpha = new JPanel( new FlowLayout( FlowLayout.CENTER, 5, 3 ) ); panelColorsSettings.add( panelColorsAlpha ); sliderColorsAlpha = new JSlider( JSlider.HORIZONTAL, 0, 255, 255 ); size = sliderColorsAlpha.getPreferredSize( ); size.width = size.width * 2 / 5; sliderColorsAlpha.setPreferredSize( size ); sliderColorsAlpha.setSnapToTicks( true ); sliderColorsAlpha.addChangeListener( this ); panelColorsAlpha.add( sliderColorsAlpha ); textColorsAlpha = new JTextField( "FF", 2 ); textColorsAlpha.setHorizontalAlignment( JTextField.CENTER ); textColorsAlpha.addActionListener( this ); textColorsAlpha.addFocusListener( this ); panelColorsAlpha.add( textColorsAlpha ); labelColorsAlpha.setLabelFor( panelColorsAlpha ); //color panel - color icons colorIdx = 0; colors = new Color[constColorCnt]; size = textColorsAlpha.getPreferredSize( ); iconsColor = new ImageIcon[constColorCnt]; for( i = 0; i < constColorCnt; i++ ) { iconsColor[i] = new ImageIcon( new BufferedImage( size.width, size.height, BufferedImage.TYPE_INT_RGB ) ); val = (constColorCnt - 1 - i) * 255 / (constColorCnt - 1); colors[i] = new Color( val, val, val ); iconFromColor( iconsColor[i], colors[i] ); buttonsColor[i].setIcon( iconsColor[i] ); } iconColorsColor = new ImageIcon( new BufferedImage( size.width, size.height, BufferedImage.TYPE_INT_RGB ) ); iconFromColor( iconColorsColor, colors[colorIdx] ); buttonColorsColor.setIcon( iconColorsColor ); buttonsColor[colorIdx].setSelected( true ); frameEditor.setColor( colors[colorIdx] ); //create play timer timerPlay = new javax.swing.Timer( 100, this ); timerPlay.setRepeats( false ); timerPlay.stop( ); //update controls updateFrames( 0 ); //running as full application if( isFullApp ) { //calculate size for main window, menus and controls frame.pack( ); //show main window frame.setVisible( true ); } //running as applet else { //arrange menus and controls size = getSize( ); resize( 1, 1 ); resize( size ); } //load initial file if( initialFile != null ) { //set current file and current directory curFile = (new File( initialFile )).getAbsoluteFile( ); curDir = curFile.getParentFile( ); //load file fileLoad( ); } } //entry point for applet public void init( ) { javax.swing.SwingUtilities.invokeLater( this ); } //entry point for full application public static void main( String[] args ) { int i; BlinkenMovie movie; Pattern sizePattern, dimPattern; Matcher sizeMatcher, dimMatcher; String txtOld, txtNew; //running interactively - without arguments if( args.length <= 0 ) { javax.swing.SwingUtilities.invokeLater( new Blimp( null ) ); return; } //running interactively - load initial file if( args.length == 1 && ! args[0].substring( 0, 1 ).equals( "-" ) ) { javax.swing.SwingUtilities.invokeLater( new Blimp( args[0] ) ); return; } //running as command line tool System.out.println( "BlinkenLightsInteractiveMovieProgram\n" + "version 1.2 date 2005-12-19\n" + "Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>\n" + "Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html\n" + "a blinkenarea.org project\n" + "powered by eventphone.de\n" ); //initialize patterns sizePattern = Pattern.compile( "^([0-9]+)x([0-9]+)-([0-9]+)/([0-9]+)$" ); dimPattern = Pattern.compile( "^([0-9]+)x([0-9]+)$" ); //get initial movie movie = new BlinkenMovie( defHeight, defWidth, defChannels, defMaxval ); movie.insertInfo( 0, "creator", "Blimp (version 1.2 date 2005-12-19)" ); movie.insertFrame( 0, new BlinkenFrame( defHeight, defWidth, defChannels, defMaxval, defDuration ) ); //process parameters for( i = 0; i < args.length; i++ ) { if( args[i].equals( "-h" ) || args[i].equals( "--help" ) ) { System.out.println( "interactive movie editor:\n" + " java Blimp [<initial-file>]\n" + "\n" + "command line tool:\n" + " java Blimp <parameter> [<parameter> [...]]\n" + "parameters:\n" + " -i / --input <file> load movie\n" + " -r / --resize <width>x<height>-<channels>/<colors> resize movie\n" + " -s / --scale <width>x<height> scale movie\n" + " -o / --output <file> save movie\n" + "\n" ); } else if( args[i].equals( "-i" ) || args[i].equals( "--input" ) ) { if( i + 1 >= args.length ) { System.out.println( "parameter \"-i\" / \"--input\" requires an argument" ); break; } i++; if( ! movie.load( args[i] ) ) { System.out.println( "movie \"" + args[i] + "\" could not be loaded..." ); break; } System.out.println( "movie \"" + args[i] + "\" was loaded successfully..." ); } else if( args[i].equals( "-r" ) || args[i].equals( "--resize" ) ) { if( i + 1 >= args.length ) { System.out.println( "parameter \"-r\" / \"--resize\" requires an argument" ); break; } i++; txtOld = movie.getWidth( ) + "x" + movie.getHeight( ) + "-" + movie.getChannels( ) + "/" + (movie.getMaxval( ) + 1); if( ! (sizeMatcher = sizePattern.matcher( args[i] )).find( ) ) { System.out.println( "invalid format \"" + args[i] + "\"of size (<width>x<height>-<channles>/<colors>)" ); break; } movie.resize( Integer.parseInt( sizeMatcher.group( 2 ) ), Integer.parseInt( sizeMatcher.group( 1 ) ), Integer.parseInt( sizeMatcher.group( 3 ) ), Integer.parseInt( sizeMatcher.group( 4 ) ) - 1 ); txtNew = movie.getWidth( ) + "x" + movie.getHeight( ) + "-" + movie.getChannels( ) + "/" + (movie.getMaxval( ) + 1); System.out.println( "resized movie from \"" + txtOld + "\" to \"" + txtNew + "\"..." ); } else if( args[i].equals( "-s" ) || args[i].equals( "--scale" ) ) { if( i + 1 >= args.length ) { System.out.println( "parameter \"-s\" / \"--scale\" requires an argument" ); break; } i++; txtOld = movie.getWidth( ) + "x" + movie.getHeight( ); if( ! (dimMatcher = dimPattern.matcher( args[i] )).find( ) ) { System.out.println( "invalid format \"" + args[i] + "\" of dimension (<width>x<height>)" ); break; } movie.scale( Integer.parseInt( dimMatcher.group( 2 ) ), Integer.parseInt( dimMatcher.group( 1 ) ) ); txtNew = movie.getWidth( ) + "x" + movie.getHeight( ); System.out.println( "scaled movie from \"" + txtOld + "\" to \"" + txtNew + "\"..." ); } else if( args[i].equals( "-o" ) || args[i].equals( "--output" ) ) { if( i + 1 >= args.length ) { System.out.println( "parameter \"-o\" / \"--output\" requires an argument" ); break; } i++; if( ! movie.save( args[i] ) ) { System.out.println( "movie \"" + args[i] + "\" could not be saved..." ); break; } System.out.println( "movie \"" + args[i] + "\" was saved successfully..." ); } else System.out.println( "unknown parameter \"" + args[i] + "\" - use \"-h\" or \"--help\" to get help" ); } //for( i... } } //public class Blimp