BlinkenArea - GitList
Repositories
Blog
Wiki
Blimp
Code
Commits
Branches
Tags
Search
Tree:
a053c99
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.0 (2005-03-24)
Christian Heimke
commited
a053c99
at 2011-07-15 09:17:14
Blimp.java
Blame
History
Raw
/* BlinkenLightsInteractiveMovieProgram * version 1.0 date 2005-03-24 * 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, menuPlay, menuHelp; //menus JMenuItem menuFileNew, menuFileLoad, menuFileSave, menuFileSaveAs, menuFileQuit; JMenuItem menuInfoShow, menuInfoAdd, menuInfoDelete; JMenuItem menuEditResize, menuEditScale; JMenuItem menuEditInsertFrame, menuEditDuplicateFrame, menuEditDeleteFrame; JMenuItem menuEditImportFrame; 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, labelFrameInfo, labelDuration; JScrollBar scrollFrames; JSlider sliderFrameZoom; BlinkenFrameEditor frameEditor; JScrollPane scrollpaneFrame; JTextField textDuration; JPanel panelOuterTools, panelMiddleTools, panelTools, panelActions; 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; 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 //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.0 date 2005-03-24)" ); 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 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( ); //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 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 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 Frame..." was chosen from menu private void actionEditImportFrame( ) { JFileChooser fileChooser; ImageIcon icon; Image image; BufferedImage bufferedImage; BlinkenFrame frame; int width, height, x, y, frameCnt, frameNo; //show file select dialog fileChooser = new JFileChooser( ); fileChooser.setDialogTitle( "Blimp - Import Frame..." ); if( curDir != null ) fileChooser.setCurrentDirectory( curDir ); if( fileChooser.showOpenDialog( dialogParent ) != JFileChooser.APPROVE_OPTION ) //not successful return; //save current directory curDir = fileChooser.getCurrentDirectory( ); //load image icon = new ImageIcon( fileChooser.getSelectedFile( ).getPath( ) ); if( icon == null ) { labelStatus.setText( "could not import frame from \"" + fileChooser.getSelectedFile( ).getPath( ) + "\"..." ); return; } width = icon.getIconWidth( ); height = icon.getIconHeight( ); image = icon.getImage( ); if( width <= 0 || height <= 0 || image == null ) { labelStatus.setText( "could not import frame from \"" + fileChooser.getSelectedFile( ).getPath( ) + "\"..." ); return; } //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( ); //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( "frame was sucessfully imported from \"" + fileChooser.getSelectedFile( ).getPath( ) + "\"..." ); //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.0 date 2005-03-24\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, frameInc; //update frames scrollbar range frameCnt = curMovie.getFrameCnt( ); if( frameCnt <= 0 ) { scrollFrames.setValues( 0, 0, 0, 0 ); scrollFrames.setBlockIncrement( 1 ); } else { if( frameNo < 0 ) frameNo = 0; if( frameNo >= frameCnt ) frameNo = frameCnt - 1; scrollFrames.setValues( frameNo, 1, 0, frameCnt ); frameInc = (int)Math.sqrt( frameCnt ); if( frameInc < 1 ) frameInc = 1; scrollFrames.setBlockIncrement( frameInc ); } //simulate frames scrollbar change to propagate update stateFrames( ); //enable disable some menu commands which need a current frame menuEditDuplicateFrame.setEnabled( frameCnt > 0 ); menuEditDeleteFrame.setEnabled( frameCnt > 0 ); } //frames scrollbar changed private void stateFrames( ) { int frameCnt, frameNo; //update frames scrollbar label //get current frame frameCnt = curMovie.getFrameCnt( ); if( frameCnt <= 0 ) { labelFrames.setText( "frame: -/0" ); curFrame = null; } else { frameNo = scrollFrames.getValue( ); labelFrames.setText( "frame: " + (frameNo + 1) + "/" + frameCnt ); curFrame = curMovie.getFrame( frameNo ); } //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 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( ) == menuEditImportFrame ) actionEditImportFrame( ); 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( ) == 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.0 date 2005-03-24)" ); 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" ); menubar.add( menuFile ); menuFileNew = new JMenuItem( "New" ); menuFileNew.addActionListener( this ); menuFile.add( menuFileNew ); menuFileLoad = new JMenuItem( "Load..." ); menuFileLoad.addActionListener( this ); menuFile.add( menuFileLoad ); menuFileSave = new JMenuItem( "Save" ); menuFileSave.addActionListener( this ); menuFile.add( menuFileSave ); menuFileSaveAs = new JMenuItem( "Save as..." ); menuFileSaveAs.addActionListener( this ); menuFile.add( menuFileSaveAs ); if( isFullApp ) menuFile.addSeparator( ); menuFileQuit = new JMenuItem( "Quit" ); menuFileQuit.addActionListener( this ); if( isFullApp ) menuFile.add( menuFileQuit ); //information menu menuInfo = new JMenu( "Information" ); menubar.add( menuInfo ); menuInfoShow = new JMenuItem( "Show..." ); menuInfoShow.addActionListener( this ); menuInfo.add( menuInfoShow ); menuInfoAdd = new JMenuItem( "Add..." ); menuInfoAdd.addActionListener( this ); menuInfo.add( menuInfoAdd ); menuInfoDelete = new JMenuItem( "Delete..." ); menuInfoDelete.addActionListener( this ); menuInfo.add( menuInfoDelete ); //edit menu menuEdit = new JMenu( "Edit" ); menubar.add( menuEdit ); menuEditResize = new JMenuItem( "Resize Movie..." ); menuEditResize.addActionListener( this ); menuEdit.add( menuEditResize ); menuEditScale = new JMenuItem( "Scale Movie..." ); menuEditScale.addActionListener( this ); menuEdit.add( menuEditScale ); menuEdit.addSeparator( ); menuEditInsertFrame = new JMenuItem( "Insert Frame" ); menuEditInsertFrame.addActionListener( this ); menuEdit.add( menuEditInsertFrame ); menuEditDuplicateFrame = new JMenuItem( "Duplicate Frame" ); menuEditDuplicateFrame.setEnabled( false ); menuEditDuplicateFrame.addActionListener( this ); menuEdit.add( menuEditDuplicateFrame ); menuEditDeleteFrame = new JMenuItem( "Delete Frame" ); menuEditDeleteFrame.setEnabled( false ); menuEditDeleteFrame.addActionListener( this ); menuEdit.add( menuEditDeleteFrame ); menuEdit.addSeparator( ); menuEditImportFrame = new JMenuItem( "Import Frame..." ); menuEditImportFrame.addActionListener( this ); menuEdit.add( menuEditImportFrame ); //play menu menuPlay = new JMenu( "Play" ); menubar.add( menuPlay ); menuPlayStart = new JMenuItem( "Start" ); menuPlayStart.addActionListener( this ); menuPlay.add( menuPlayStart ); menuPlayStop = new JMenuItem( "Stop" ); menuPlayStop.setEnabled( false ); menuPlayStop.addActionListener( this ); menuPlay.add( menuPlayStop ); menuPlay.addSeparator( ); menuPlayBegin = new JCheckBoxMenuItem( "From Begin", false ); menuPlayBegin.addActionListener( this ); menuPlay.add( menuPlayBegin ); menuPlayLoop = new JCheckBoxMenuItem( "Looped", false ); menuPlayLoop.addActionListener( this ); menuPlay.add( menuPlayLoop ); //help menu menuHelp = new JMenu( "Help" ); menubar.add( menuHelp ); menuHelpAbout = new JMenuItem( "About..." ); 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.setBlockIncrement( 1 ); scrollFrames.addAdjustmentListener( this ); panelFrames.add( scrollFrames, BorderLayout.CENTER ); labelFrames = new JLabel( "frame: -/0" ); labelFrames.setLabelFor( scrollFrames ); panelFrames.add( labelFrames, BorderLayout.WEST ); //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 and action panels panelOuterTools = new JPanel( new GridLayout( 2, 1, 5, 5 ) ); panelOuterFrame.add( panelOuterTools, BorderLayout.WEST ); 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 ); //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 ); //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.0 date 2005-03-24\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.0 date 2005-03-24)" ); 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