Home | History | Annotate | Download | only in flame
      1 /*******************************************************************************
      2  * Copyright 2011 See AUTHORS file.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  ******************************************************************************/
     16 package com.badlogic.gdx.tools.flame;
     17 import java.awt.Dimension;
     18 import java.awt.GridBagConstraints;
     19 import java.awt.GridBagLayout;
     20 import java.awt.Insets;
     21 import java.awt.event.ActionEvent;
     22 import java.awt.event.ActionListener;
     23 import java.io.File;
     24 
     25 import javax.swing.DefaultComboBoxModel;
     26 import javax.swing.JButton;
     27 import javax.swing.JComboBox;
     28 import javax.swing.JPanel;
     29 import javax.swing.JScrollPane;
     30 import javax.swing.JSeparator;
     31 import javax.swing.JTable;
     32 import javax.swing.ListSelectionModel;
     33 import javax.swing.event.ListSelectionEvent;
     34 import javax.swing.event.ListSelectionListener;
     35 import javax.swing.event.TableModelEvent;
     36 import javax.swing.event.TableModelListener;
     37 import javax.swing.table.DefaultTableModel;
     38 
     39 import com.badlogic.gdx.graphics.Texture;
     40 import com.badlogic.gdx.graphics.g3d.Model;
     41 import com.badlogic.gdx.graphics.g3d.particles.ParticleController;
     42 import com.badlogic.gdx.graphics.g3d.particles.ParticleEffect;
     43 import com.badlogic.gdx.graphics.g3d.particles.emitters.RegularEmitter;
     44 import com.badlogic.gdx.graphics.g3d.particles.influencers.ColorInfluencer;
     45 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsInfluencer;
     46 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsModifier;
     47 import com.badlogic.gdx.graphics.g3d.particles.influencers.ModelInfluencer;
     48 import com.badlogic.gdx.graphics.g3d.particles.influencers.ParticleControllerFinalizerInfluencer;
     49 import com.badlogic.gdx.graphics.g3d.particles.influencers.ParticleControllerInfluencer;
     50 import com.badlogic.gdx.graphics.g3d.particles.influencers.RegionInfluencer;
     51 import com.badlogic.gdx.graphics.g3d.particles.influencers.ScaleInfluencer;
     52 import com.badlogic.gdx.graphics.g3d.particles.influencers.SpawnInfluencer;
     53 import com.badlogic.gdx.graphics.g3d.particles.renderers.BillboardRenderer;
     54 import com.badlogic.gdx.graphics.g3d.particles.renderers.ModelInstanceRenderer;
     55 import com.badlogic.gdx.graphics.g3d.particles.renderers.ParticleControllerControllerRenderer;
     56 import com.badlogic.gdx.graphics.g3d.particles.renderers.PointSpriteRenderer;
     57 import com.badlogic.gdx.graphics.g3d.particles.values.EllipseSpawnShapeValue;
     58 import com.badlogic.gdx.graphics.g3d.particles.values.PointSpawnShapeValue;
     59 import com.badlogic.gdx.graphics.g3d.particles.values.PrimitiveSpawnShapeValue.SpawnSide;
     60 import com.badlogic.gdx.tools.flame.FlameMain.ControllerData;
     61 import com.badlogic.gdx.tools.flame.FlameMain.ControllerType;
     62 
     63 /** @author Inferno */
     64 class EffectPanel extends JPanel {
     65 	FlameMain editor;
     66 	JTable emitterTable;
     67 	DefaultTableModel emitterTableModel;
     68 	int editIndex = -1;
     69 	String lastDir;
     70 	JComboBox controllerTypeCombo;
     71 
     72 
     73 	public EffectPanel (FlameMain editor) {
     74 		this.editor = editor;
     75 		initializeComponents();
     76 	}
     77 
     78 	public <T extends ParticleController> T createDefaultEmitter (ControllerType type, boolean select, boolean add) {
     79 
     80 		T controller = null;
     81 		if(type == ControllerType.Billboard){
     82 			controller = (T)createDefaultBillboardController();
     83 		}
     84 		else if(type == ControllerType.ModelInstance){
     85 			controller = (T) createDefaultModelInstanceController();
     86 		}
     87 		else if(type == ControllerType.PointSprite){
     88 			controller = (T) createDefaultPointController();
     89 		}
     90 		else if(type == ControllerType.ParticleController){
     91 			controller = (T) createDefaultParticleController();
     92 		}
     93 
     94 		if(add){
     95 			controller.init();
     96 			addEmitter(controller, select);
     97 		}
     98 		return controller;
     99 	}
    100 
    101 	private ParticleController createDefaultModelInstanceController () {
    102 		//Emission
    103 		RegularEmitter emitter = new RegularEmitter();
    104 		emitter.getDuration().setLow(3000);
    105 		emitter.getEmission().setHigh(80);
    106 		emitter.getLife().setHigh(500, 1000);
    107 		emitter.getLife().setTimeline(new float[] {0, 0.66f, 1});
    108 		emitter.getLife().setScaling(new float[] {1, 1, 0.3f});
    109 		emitter.setMaxParticleCount(100);
    110 
    111 		//Color
    112 		ColorInfluencer.Random colorInfluencer = new ColorInfluencer.Random();
    113 
    114 		//Spawn
    115 		EllipseSpawnShapeValue spawnShapeValue = new EllipseSpawnShapeValue();
    116 		spawnShapeValue.setDimensions(1, 1, 1);
    117 		SpawnInfluencer spawnSource = new SpawnInfluencer(spawnShapeValue);
    118 
    119 		//Velocity
    120 		DynamicsInfluencer velocityInfluencer = new DynamicsInfluencer();
    121 
    122 		//Directional
    123 		DynamicsModifier.CentripetalAcceleration velocityValue = new DynamicsModifier.CentripetalAcceleration();
    124 		velocityValue.strengthValue.setHigh(5, 11);
    125 		velocityValue.strengthValue.setActive(true);
    126 		//velocityValue.setActive(true);
    127 		velocityInfluencer.velocities.add(velocityValue);
    128 		//VelocityModifier.FaceDirection faceVelocityValue = new VelocityModifier.FaceDirection();
    129 		//velocityInfluencer.velocities.add(faceVelocityValue);
    130 
    131 		return new ParticleController("ModelInstance Controller", emitter, new ModelInstanceRenderer(editor.getModelInstanceParticleBatch()),
    132 			new ModelInfluencer.Single((Model) editor.assetManager.get(FlameMain.DEFAULT_MODEL_PARTICLE) ),
    133 			spawnSource,
    134 			colorInfluencer,
    135 			velocityInfluencer
    136 			);
    137 	}
    138 
    139 	private ParticleController createDefaultBillboardController () {
    140 		//Emission
    141 		RegularEmitter emitter = new RegularEmitter();
    142 		emitter.getDuration().setLow(3000);
    143 		emitter.getEmission().setHigh(250);
    144 		emitter.getLife().setHigh(500, 1000);
    145 		emitter.getLife().setTimeline(new float[] {0, 0.66f, 1});
    146 		emitter.getLife().setScaling(new float[] {1, 1, 0.3f});
    147 		emitter.setMaxParticleCount(200);
    148 
    149 		//Spawn
    150 		PointSpawnShapeValue pointSpawnShapeValue = new PointSpawnShapeValue();
    151 		SpawnInfluencer spawnSource = new SpawnInfluencer(pointSpawnShapeValue);
    152 
    153 		//Color
    154 		ColorInfluencer.Single colorInfluencer = new ColorInfluencer.Single();
    155 		colorInfluencer.colorValue.setColors(new float[] {1, 0.12156863f, 0.047058824f, 0,0,0});
    156 		colorInfluencer.colorValue.setTimeline(new float[] {0, 1});
    157 		colorInfluencer.alphaValue.setHigh(1);
    158 		colorInfluencer.alphaValue.setTimeline(new float[] {0, 0.5f, 0.8f, 1});
    159 		colorInfluencer.alphaValue.setScaling(new float[] {0, 0.15f, 0.5f, 0});
    160 
    161 		//Velocity
    162 		DynamicsInfluencer velocityInfluencer = new DynamicsInfluencer();
    163 
    164 		//Directional
    165 		DynamicsModifier.PolarAcceleration velocityValue = new DynamicsModifier.PolarAcceleration();
    166 		velocityValue.phiValue.setHigh(-35, 35);
    167 		velocityValue.phiValue.setActive(true);
    168 		velocityValue.phiValue.setTimeline(new float[] {0, 0.5f, 1});
    169 		velocityValue.phiValue.setScaling(new float[] {1, 0, 0});
    170 		velocityValue.thetaValue.setHigh(0, 360);
    171 		velocityValue.strengthValue.setHigh(5, 10);
    172 		velocityInfluencer.velocities.add(velocityValue);
    173 
    174 		return new ParticleController("Billboard Controller", emitter, new BillboardRenderer(editor.getBillboardBatch()),
    175 			new RegionInfluencer.Single(editor.getTexture()),
    176 			spawnSource,
    177 			colorInfluencer,
    178 			velocityInfluencer
    179 			);
    180 	}
    181 
    182 	private ParticleController createDefaultPointController () {
    183 		//Emission
    184 		RegularEmitter emitter = new RegularEmitter();
    185 		emitter.getDuration().setLow(3000);
    186 		emitter.getEmission().setHigh(250);
    187 		emitter.getLife().setHigh(500, 1000);
    188 		emitter.getLife().setTimeline(new float[] {0, 0.66f, 1});
    189 		emitter.getLife().setScaling(new float[] {1, 1, 0.3f});
    190 		emitter.setMaxParticleCount(200);
    191 
    192 		//Scale
    193 		ScaleInfluencer scaleInfluencer = new ScaleInfluencer();
    194 		scaleInfluencer.value.setHigh(1);
    195 
    196 		//Color
    197 		ColorInfluencer.Single colorInfluencer = new ColorInfluencer.Single();
    198 		colorInfluencer.colorValue.setColors(new float[] {0.12156863f, 0.047058824f, 1, 0,0,0});
    199 		colorInfluencer.colorValue.setTimeline(new float[] {0, 1});
    200 		colorInfluencer.alphaValue.setHigh(1);
    201 		colorInfluencer.alphaValue.setTimeline(new float[] {0, 0.5f, 0.8f, 1});
    202 		colorInfluencer.alphaValue.setScaling(new float[] {0, 0.15f, 0.5f, 0});
    203 
    204 		//Spawn
    205 		PointSpawnShapeValue pointSpawnShapeValue = new PointSpawnShapeValue();
    206 		SpawnInfluencer spawnSource = new SpawnInfluencer(pointSpawnShapeValue);
    207 
    208 		//Velocity
    209 		DynamicsInfluencer velocityInfluencer = new DynamicsInfluencer();
    210 
    211 		//Directional
    212 		DynamicsModifier.PolarAcceleration velocityValue = new DynamicsModifier.PolarAcceleration();
    213 		velocityValue.phiValue.setHigh(-35, 35);
    214 		velocityValue.phiValue.setActive(true);
    215 		velocityValue.phiValue.setTimeline(new float[] {0, 0.5f, 1});
    216 		velocityValue.phiValue.setScaling(new float[] {1, 0, 0});
    217 		velocityValue.thetaValue.setHigh(0, 360);
    218 		velocityValue.strengthValue.setHigh(5, 10);
    219 
    220 		return new ParticleController("PointSprite Controller", emitter, new PointSpriteRenderer(editor.getPointSpriteBatch()),
    221 			new RegionInfluencer.Single((Texture) editor.assetManager.get(FlameMain.DEFAULT_BILLBOARD_PARTICLE) ),
    222 			spawnSource,
    223 			scaleInfluencer,
    224 			colorInfluencer,
    225 			velocityInfluencer
    226 			);
    227 	}
    228 
    229 	private ParticleController createDefaultParticleController () {
    230 		//Emission
    231 		RegularEmitter emitter = new RegularEmitter();
    232 		emitter.getDuration().setLow(3000);
    233 		emitter.getEmission().setHigh(90);
    234 		emitter.getLife().setHigh(3000);
    235 		emitter.setMaxParticleCount(100);
    236 
    237 		//Spawn
    238 		EllipseSpawnShapeValue pointSpawnShapeValue = new EllipseSpawnShapeValue();
    239 		pointSpawnShapeValue.setDimensions(1, 1, 1);
    240 		pointSpawnShapeValue.setSide(SpawnSide.top);
    241 		SpawnInfluencer spawnSource = new SpawnInfluencer(pointSpawnShapeValue);
    242 
    243 		//Scale
    244 		ScaleInfluencer scaleInfluencer = new ScaleInfluencer();
    245 		scaleInfluencer.value.setHigh(1);
    246 		scaleInfluencer.value.setLow(0);
    247 		scaleInfluencer.value.setTimeline(new float[]{0,1});
    248 		scaleInfluencer.value.setScaling(new float[]{1, 0});
    249 
    250 		//Velocity
    251 		DynamicsInfluencer velocityInfluencer = new DynamicsInfluencer();
    252 
    253 		//Directional
    254 		DynamicsModifier.CentripetalAcceleration velocityValue = new DynamicsModifier.CentripetalAcceleration();
    255 		velocityValue.strengthValue.setHigh(5, 10);
    256 		velocityValue.strengthValue.setActive(true);
    257 		velocityInfluencer.velocities.add(velocityValue);
    258 
    259 		return new ParticleController("ParticleController Controller", emitter, new ParticleControllerControllerRenderer(),
    260 			new ParticleControllerInfluencer.Single(editor.assetManager.get(FlameMain.DEFAULT_TEMPLATE_PFX, ParticleEffect.class).getControllers().get(0)),
    261 			spawnSource,
    262 			scaleInfluencer,
    263 			velocityInfluencer,
    264 			new ParticleControllerFinalizerInfluencer()
    265 			);
    266 	}
    267 
    268 	public ParticleController createDefaultTemplateController(){
    269 		//Emission
    270 		RegularEmitter emitter = new RegularEmitter();
    271 		emitter.getDuration().setLow(3000);
    272 		emitter.getEmission().setHigh(90);
    273 		emitter.getLife().setHigh(1000);
    274 		emitter.getLife().setTimeline(new float[] {0, 0.66f, 1});
    275 		emitter.getLife().setScaling(new float[] {1, 1, 0.3f});
    276 		emitter.setMaxParticleCount(100);
    277 
    278 		//Spawn
    279 		PointSpawnShapeValue pointSpawnShapeValue = new PointSpawnShapeValue();
    280 		pointSpawnShapeValue.xOffsetValue.setLow(0, 1f);
    281 		pointSpawnShapeValue.xOffsetValue.setActive(true);
    282 		pointSpawnShapeValue.yOffsetValue.setLow(0, 1f);
    283 		pointSpawnShapeValue.yOffsetValue.setActive(true);
    284 		pointSpawnShapeValue.zOffsetValue.setLow(0, 1f);
    285 		pointSpawnShapeValue.zOffsetValue.setActive(true);
    286 		SpawnInfluencer spawnSource = new SpawnInfluencer(pointSpawnShapeValue);
    287 
    288 		ScaleInfluencer scaleInfluencer = new ScaleInfluencer();
    289 		scaleInfluencer.value.setHigh(1f);
    290 
    291 		//Color
    292 		ColorInfluencer.Single colorInfluencer = new ColorInfluencer.Single();
    293 		colorInfluencer.colorValue.setColors(new float[] {1, 0.12156863f, 0.047058824f, 0,0,0});
    294 		colorInfluencer.colorValue.setTimeline(new float[] {0, 1});
    295 		colorInfluencer.alphaValue.setHigh(1);
    296 		colorInfluencer.alphaValue.setTimeline(new float[] {0, 0.5f, 0.8f, 1});
    297 		colorInfluencer.alphaValue.setScaling(new float[] {0, 0.15f, 0.5f, 0});
    298 
    299 		return new ParticleController("Billboard Controller", emitter, new BillboardRenderer(editor.getBillboardBatch()),
    300 			new RegionInfluencer.Single(editor.getTexture()),
    301 			spawnSource,
    302 			scaleInfluencer,
    303 			colorInfluencer
    304 			);
    305 	}
    306 
    307 	private void addEmitter (final ParticleController emitter, boolean select) {
    308 		editor.addEmitter(emitter);
    309 		emitterTableModel.addRow(new Object[] {emitter.name, true});
    310 
    311 		int row = emitterTableModel.getRowCount() - 1;
    312 		emitterChecked (row, true);
    313 
    314 		if (select) {
    315 			emitterTable.getSelectionModel().setSelectionInterval(row, row);
    316 		}
    317 	}
    318 
    319 	void emitterSelected () {
    320 		int row = emitterTable.getSelectedRow();
    321 		if (row == editIndex)
    322 			return;
    323 
    324 		editIndex = row;
    325 		editor.reloadRows();
    326 	}
    327 
    328 	void emitterChecked (int index, boolean checked) {
    329 		editor.setEnabled(index, checked);
    330 	}
    331 
    332 	void openEffect () {
    333 		File file = editor.showFileLoadDialog();
    334 		if(file != null){
    335 			if(editor.openEffect(file, true) != null){
    336 				emitterTableModel.getDataVector().removeAllElements();
    337 				for (ControllerData data : editor.controllersData) {
    338 					emitterTableModel.addRow(new Object[] {data.controller.name, true});
    339 				}
    340 				editIndex = 0;
    341 				emitterTable.getSelectionModel().setSelectionInterval(editIndex, editIndex);
    342 			}
    343 		}
    344 	}
    345 
    346 	protected void importEffect () {
    347 		File file = editor.showFileLoadDialog();
    348 		if(file != null){
    349 			ParticleEffect effect;
    350 			if( (effect = editor.openEffect(file, false)) != null){
    351 				for(ParticleController controller : effect.getControllers())
    352 					addEmitter(controller, false);
    353 				editIndex = 0;
    354 				emitterTable.getSelectionModel().setSelectionInterval(editIndex, editIndex);
    355 			}
    356 		}
    357 	}
    358 
    359 	void saveEffect () {
    360 		File file = editor.showFileSaveDialog();
    361 		if(file != null){
    362 			int index = 0;
    363 			for (ControllerData data : editor.controllersData)
    364 				data.controller.name = ((String)emitterTableModel.getValueAt(index++, 0));
    365 			editor.saveEffect(file);
    366 		}
    367 	}
    368 
    369 	void deleteEmitter () {
    370 		int row = emitterTable.getSelectedRow();
    371 		if (row == -1) return;
    372 
    373 		int newIndex = Math.min(editIndex, emitterTableModel.getRowCount()-2);
    374 
    375 		editor.removeEmitter(row);
    376 		emitterTableModel.removeRow(row);
    377 
    378 		//Reload data check
    379 		emitterTable.getSelectionModel().setSelectionInterval(newIndex, newIndex);
    380 	}
    381 
    382 	protected void cloneEmitter () {
    383 		int row = emitterTable.getSelectedRow();
    384 		if (row == -1) return;
    385 		ParticleController controller = editor.controllersData.get(row).controller.copy();
    386 		controller.init();
    387 		controller.name +=" Clone";
    388 		addEmitter(controller, true);
    389 	}
    390 
    391 	void move (int direction) {
    392 		/*
    393 		Array<ParticleController> emitters = editor.effect.getControllers();
    394 		if ( (direction < 0 && editIndex == 0) || (direction > 0 && editIndex == emitters.size - 1)) return;
    395 		int insertIndex = editIndex + direction;
    396 		Object name = emitterTableModel.getValueAt(editIndex, 0);
    397 		boolean isEnabled = editor.isEnabled(editIndex);
    398 		ParticleController emitter = emitters.removeIndex(editIndex);
    399 		emitterTableModel.removeRow(editIndex);
    400 		emitterTableModel.insertRow(insertIndex, new Object[] {name, isEnabled});
    401 		emitters.insert(insertIndex, emitter);
    402 		editIndex = insertIndex;
    403 		emitterTable.getSelectionModel().setSelectionInterval(editIndex, editIndex);
    404 		*/
    405 	}
    406 
    407 	private void initializeComponents () {
    408 		setLayout(new GridBagLayout());
    409 		{
    410 			JScrollPane scroll = new JScrollPane();
    411 			add(scroll, new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,
    412 				0, 0, 6), 0, 0));
    413 			{
    414 				emitterTable = new JTable() {
    415 					public Class getColumnClass (int column) {
    416 						return column == 1 ? Boolean.class : super.getColumnClass(column);
    417 					}
    418 					@Override
    419 					public Dimension getPreferredScrollableViewportSize () {
    420 						Dimension dim = super.getPreferredScrollableViewportSize();
    421 						dim.height = getPreferredSize().height;
    422 						return dim;
    423 					}
    424 				};
    425 				emitterTable.getTableHeader().setReorderingAllowed(false);
    426 				emitterTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    427 				scroll.setViewportView(emitterTable);
    428 				emitterTableModel = new DefaultTableModel(new String[0][0], new String[] {"Emitter", ""});
    429 				emitterTable.setModel(emitterTableModel);
    430 				emitterTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
    431 					public void valueChanged (ListSelectionEvent event) {
    432 						if (event.getValueIsAdjusting()) return;
    433 						emitterSelected();
    434 					}
    435 				});
    436 				emitterTableModel.addTableModelListener(new TableModelListener() {
    437 					public void tableChanged (TableModelEvent event) {
    438 						if (event.getColumn() != 1) return;
    439 						emitterChecked(event.getFirstRow(), (Boolean)emitterTable.getValueAt(event.getFirstRow(), 1));
    440 					}
    441 				});
    442 			}
    443 		}
    444 		{
    445 			JPanel sideButtons = new JPanel(new GridBagLayout());
    446 			add(sideButtons, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
    447 				new Insets(0, 0, 0, 0), 0, 0));
    448 			{
    449 				controllerTypeCombo = new JComboBox();
    450 				controllerTypeCombo.setModel(new DefaultComboBoxModel(ControllerType.values()));
    451 				sideButtons.add(controllerTypeCombo, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
    452 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
    453 			}
    454 			{
    455 				JButton newButton = new JButton("New");
    456 				sideButtons.add(newButton, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
    457 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
    458 				newButton.addActionListener(new ActionListener() {
    459 					public void actionPerformed (ActionEvent event) {
    460 						ControllerType item = (ControllerType)controllerTypeCombo.getSelectedItem();
    461 						createDefaultEmitter(item, true, true);
    462 					}
    463 				});
    464 			}
    465 			{
    466 				JButton deleteButton = new JButton("Delete");
    467 				sideButtons.add(deleteButton, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
    468 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
    469 				deleteButton.addActionListener(new ActionListener() {
    470 					public void actionPerformed (ActionEvent event) {
    471 						deleteEmitter();
    472 					}
    473 				});
    474 			}
    475 			{
    476 				JButton cloneButton = new JButton("Clone");
    477 				sideButtons.add(cloneButton, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
    478 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
    479 				cloneButton.addActionListener(new ActionListener() {
    480 					public void actionPerformed (ActionEvent event) {
    481 						cloneEmitter();
    482 					}
    483 				});
    484 			}
    485 			{
    486 				sideButtons.add(new JSeparator(JSeparator.HORIZONTAL), new GridBagConstraints(0, -1, 1, 1, 0, 0,
    487 					GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
    488 			}
    489 			{
    490 				JButton saveButton = new JButton("Save");
    491 				sideButtons.add(saveButton, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
    492 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
    493 				saveButton.addActionListener(new ActionListener() {
    494 					public void actionPerformed (ActionEvent event) {
    495 						saveEffect();
    496 					}
    497 				});
    498 			}
    499 			{
    500 				JButton openButton = new JButton("Open");
    501 				sideButtons.add(openButton, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
    502 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
    503 				openButton.addActionListener(new ActionListener() {
    504 					public void actionPerformed (ActionEvent event) {
    505 						openEffect();
    506 					}
    507 				});
    508 			}
    509 			{
    510 				JButton importButton = new JButton("Import");
    511 				sideButtons.add(importButton, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
    512 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
    513 				importButton.addActionListener(new ActionListener() {
    514 					public void actionPerformed (ActionEvent event) {
    515 						importEffect();
    516 					}
    517 				});
    518 			}
    519 			/*
    520 			{
    521 				JButton importButton = new JButton("Export");
    522 				sideButtons.add(importButton, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
    523 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
    524 				importButton.addActionListener(new ActionListener() {
    525 					public void actionPerformed (ActionEvent event) {
    526 						exportEffect();
    527 					}
    528 				});
    529 			}
    530 			*/
    531 		}
    532 	}
    533 
    534 }
    535