diff --git a/engine/src/test/jme3test/blender/ManualBlenderTester.java b/engine/src/test/jme3test/blender/ManualBlenderTester.java index fe8762a22..776d26688 100644 --- a/engine/src/test/jme3test/blender/ManualBlenderTester.java +++ b/engine/src/test/jme3test/blender/ManualBlenderTester.java @@ -41,7 +41,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import jme3test.blender.config.ConfigDialog; -import jme3test.blender.config.ConfigExecutable; +import jme3test.blender.config.ConfigDialog.BlenderKeyConfiguration; import jme3test.blender.scene.Pivot; import com.jme3.animation.AnimControl; @@ -90,13 +90,9 @@ public class ManualBlenderTester extends SimpleApplication { } final boolean debugMode = debug; //running the application - new ConfigDialog("./src/test-data/Blender", new ConfigExecutable() { - - @Override - public void execute(ModelKey modelKey, Level logLevel) { - new ManualBlenderTester(modelKey, logLevel, debugMode).start(); - } - }); + ConfigDialog configDialog = new ConfigDialog("./src/test-data/Blender"); + BlenderKeyConfiguration bkk = configDialog.getBlenderKeyConfiguration(); + new ManualBlenderTester(bkk, debugMode).start(); } /** @@ -106,10 +102,10 @@ public class ManualBlenderTester extends SimpleApplication { * @param debug variable that indicates if the application runs in debug mode * (this is required on linux to show release the mouse to be used in debug mode) */ - public ManualBlenderTester(ModelKey modelKey, Level logLevel, boolean debug) { + public ManualBlenderTester(BlenderKeyConfiguration bkc, boolean debug) { this.debug = debug; - Logger.getLogger("com.jme3").setLevel(logLevel); - this.modelKey = modelKey; + Logger.getLogger("com.jme3").setLevel(bkc.getLogLevel()); + this.modelKey = bkc.getKeyToUse(); this.showSettings = false; } @@ -141,15 +137,17 @@ public class ManualBlenderTester extends SimpleApplication { }; rootNode.attachChild(new Pivot(assetManager)); if (modelKey instanceof BlenderKey) { - Node blenderModel = this.testBlenderLoader(ai); + this.testBlenderLoader(ai); Map> animations = ((BlenderKey) modelKey).getAnimations(); //setting the first animation as active if (((BlenderKey) modelKey).getAnimations() != null) { for (Entry> animEntry : animations.entrySet()) { for (Entry anim : animEntry.getValue().entrySet()) { - Spatial animatedSpatial = this.findNode(blenderModel, animEntry.getKey()); - animatedSpatial.getControl(AnimControl.class).createChannel().setAnim(anim.getKey()); - break; + Spatial animatedSpatial = this.findNode(this.rootNode, animEntry.getKey()); + if(animatedSpatial != null) { + animatedSpatial.getControl(AnimControl.class).createChannel().setAnim(anim.getKey()); + break; + } } break; } diff --git a/engine/src/test/jme3test/blender/config/AbstractConfigDialog.java b/engine/src/test/jme3test/blender/config/AbstractConfigDialog.java index dfa5c53e2..27d7975aa 100644 --- a/engine/src/test/jme3test/blender/config/AbstractConfigDialog.java +++ b/engine/src/test/jme3test/blender/config/AbstractConfigDialog.java @@ -3,6 +3,7 @@ package jme3test.blender.config; import java.awt.BorderLayout; import java.awt.Component; import java.awt.FlowLayout; +import java.awt.Frame; import java.awt.Insets; import java.awt.Label; import java.awt.event.ActionEvent; @@ -22,7 +23,7 @@ import javax.swing.DefaultListSelectionModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; -import javax.swing.JFrame; +import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; @@ -44,7 +45,7 @@ import javax.swing.table.TableCellEditor; * It is made so to easier maintain the dialog window. * @author Marcin Roguski (Kaelthas) */ -public abstract class AbstractConfigDialog extends JFrame { +public abstract class AbstractConfigDialog extends JDialog { private static final long serialVersionUID = -3677493125861310310L; private static final Logger LOGGER = Logger.getLogger(AbstractConfigDialog.class.getName()); @@ -62,6 +63,7 @@ public abstract class AbstractConfigDialog extends JFrame { * Cionstructor initializes the gui. */ public AbstractConfigDialog() { + super((Frame)null, true); this.init(); } @@ -81,15 +83,14 @@ public abstract class AbstractConfigDialog extends JFrame { LOGGER.log(Level.SEVERE, e.getMessage(), e); } this.setLayout(new BorderLayout()); + this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + this.setLocationRelativeTo(null); this.add(this.prepareBlenderFilesAndLogLevelPanel(), BorderLayout.WEST); this.add(this.prepareFilePropertiesPanel(), BorderLayout.CENTER); this.add(this.prepareButtonsPanel(), BorderLayout.SOUTH); this.pack(); - this.setLocationRelativeTo(null); - this.setVisible(true); - this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } /** @@ -251,6 +252,7 @@ public abstract class AbstractConfigDialog extends JFrame { */ public static synchronized void setSelectedLevel(Level level) { radioButtons.get(level).setSelected(true); + selectedLevel = level; } } diff --git a/engine/src/test/jme3test/blender/config/ConfigDialog.java b/engine/src/test/jme3test/blender/config/ConfigDialog.java index e6373f108..5aa2a705a 100644 --- a/engine/src/test/jme3test/blender/config/ConfigDialog.java +++ b/engine/src/test/jme3test/blender/config/ConfigDialog.java @@ -19,7 +19,6 @@ import java.util.logging.Logger; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListModel; import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TableModelEvent; @@ -45,25 +44,17 @@ public class ConfigDialog extends AbstractConfigDialog { private static final long serialVersionUID = 2863364888664674247L; private static final Logger LOGGER = Logger.getLogger(ConfigDialog.class.getName()); private String baseFolderName; - private File configFile; //the config file - private Map configMap; //the blender key configuration map private BlenderKeyConfiguration blenderKeyConfiguration;//the configuration for the files - private ConfigExecutable configExecutable; //this is called after clicking the 'OK' button /** * Constructor. Builds the whole window and stores its data. - * @param testAssetsFolderName the path to test files folder + * @param baseFolderName base folder for test assets */ - public ConfigDialog(String baseFolderName, ConfigExecutable configExecutable) { + public ConfigDialog(String baseFolderName) { if (baseFolderName == null) { throw new IllegalArgumentException("No test asset folder given!"); } - if (configExecutable == null) { - throw new IllegalArgumentException("No config executable given!"); - } this.baseFolderName = baseFolderName; - this.configExecutable = configExecutable; - this.configMap = new HashMap(); //setting up version selection (as a folder list in a compo box) File baseFolder = new File(baseFolderName); @@ -71,7 +62,6 @@ public class ConfigDialog extends AbstractConfigDialog { throw new IllegalArgumentException("The given base folder path either does not exists or does not point to a directory!"); } File[] folders = baseFolder.listFiles(new FileFilter() { - @Override public boolean accept(File file) { return file.isDirectory() && file.getName().charAt(0) != '.'; @@ -79,65 +69,56 @@ public class ConfigDialog extends AbstractConfigDialog { }); for (File folder : folders) { ((DefaultComboBoxModel) jComboBoxVersionSelection.getModel()).addElement(folder.getName()); - configMap.put(folder.getName(), null); } + this.loadConfiguration(); + this.applyConfiguration(); + this.initListeners(); - - jComboBoxVersionSelection.setSelectedIndex(0); + this.setVisible(true); } - + /** - * This method returns the selected blender key. - * @return the selected blender key + * This method returns the blender key configuration. + * @return the blender key configuration */ - public BlenderKey getSelectedBlenderKey() { - return blenderKeyConfiguration.lastUsedKey; - } + public BlenderKeyConfiguration getBlenderKeyConfiguration() { + return blenderKeyConfiguration; + } /** - * This method prepares the blender files' list. - * @param testAssetsFolderName the path to test files folder - * @return array of blender files + * This method loades the configuration. + * It stores the data into swing gui elements and enlists the proper blender files. */ - private File[] prepareFilesList(String testAssetsFolderName) { - File testAssetsFolder = new File(testAssetsFolderName); - - //loading blender files - File[] blenderFiles = testAssetsFolder.listFiles(new FileFilter() { - - @Override - public boolean accept(File file) { - return file.isFile() && file.canRead() && file.getName().endsWith(".blend"); - } - }); + private void loadConfiguration() { + File baseFolder = new File(baseFolderName); //loading the blender files configuration - File[] files = testAssetsFolder.listFiles(new FileFilter() { + File[] configFiles = baseFolder.listFiles(new FileFilter() { @Override public boolean accept(File file) { return file.isFile() && file.canRead() && file.getName().endsWith(".conf"); } }); - if (files == null || files.length == 0) { - blenderKeyConfiguration = new BlenderKeyConfiguration(blenderFiles.length); - + if (configFiles == null || configFiles.length == 0) { + blenderKeyConfiguration = new BlenderKeyConfiguration(); } else { BinaryImporter jmeImporter = new BinaryImporter(); - String instructionToUser = files.length == 1 + String instructionToUser = configFiles.length == 1 ? "No other config file to load! No configuration set!" : "Please choose different config file!"; do { - if (files.length > 1) { + File configFile; + if (configFiles.length > 1) { configFile = (File) JOptionPane.showInputDialog(null, "Choose the config file!", "Config file selection", - JOptionPane.INFORMATION_MESSAGE, null, files, files[0]); + JOptionPane.INFORMATION_MESSAGE, null, configFiles, configFiles[0]); } else { - configFile = files[0]; + configFile = configFiles[0]; } if (configFile == null) { JOptionPane.showMessageDialog(this, "No config file selected!\nEmpty configuration will be created!", "No configuration selected", JOptionPane.INFORMATION_MESSAGE); - blenderKeyConfiguration = new BlenderKeyConfiguration(blenderFiles.length); + blenderKeyConfiguration = new BlenderKeyConfiguration(); } else { try { Savable loadedData = jmeImporter.load(configFile); @@ -158,19 +139,54 @@ public class ConfigDialog extends AbstractConfigDialog { LOGGER.log(Level.SEVERE, "Unable to load configuration due to unpredicted error!", e); } } - } while (blenderKeyConfiguration == null && files.length > 1); + } while (blenderKeyConfiguration == null && configFiles.length > 1); } - configFile = new File(testAssetsFolder, "test.conf"); - - jCheckBoxUseModelKey.setSelected(blenderKeyConfiguration.useModelKey); - + } + + /** + * This method applies the loaded configuration. + */ + private void applyConfiguration() { + //applying configuration to gui components + jCheckBoxUseModelKey.setSelected(blenderKeyConfiguration.useModelKey); + if(blenderKeyConfiguration.lastVersionUsed != null) { + jComboBoxVersionSelection.setSelectedItem(blenderKeyConfiguration.lastVersionUsed); + } else { + jComboBoxVersionSelection.setSelectedIndex(0); + blenderKeyConfiguration.lastVersionUsed = (String)jComboBoxVersionSelection.getSelectedItem(); + } + JRadioButtonLevel.setSelectedLevel(blenderKeyConfiguration.logLevel); + //enlisting the files in the list + this.reloadFilesList(); + } + + /** + * This method prepares the blender files' list and selects the blender key that was last selected + * for this gorup of assets. + */ + private void reloadFilesList() { + File testAssetsFolder = new File(baseFolderName + '/' + blenderKeyConfiguration.lastVersionUsed); + File[] blenderFiles = testAssetsFolder.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + return file.isFile() && file.canRead() && file.getName().endsWith(".blend"); + } + }); + BlenderKey lastUsedKey = blenderKeyConfiguration.lastUsedKey.get(blenderKeyConfiguration.lastVersionUsed); + String lastFileUsed = null; + if(lastUsedKey!=null) { + lastFileUsed = lastUsedKey.getName().substring(lastUsedKey.getName().lastIndexOf('/') + 1); + } DefaultListModel defaultListModel = (DefaultListModel) jListBlenderFiles.getModel(); defaultListModel.removeAllElements(); for (int i = 0; i < blenderFiles.length; ++i) { defaultListModel.addElement(new FileListItem(blenderFiles[i])); + if(lastFileUsed != null && lastFileUsed.equals(blenderFiles[i].getName())) { + jListBlenderFiles.setSelectedIndex(i); + this.setBlenderKey(lastUsedKey); + } } - return blenderFiles; } /** @@ -227,10 +243,11 @@ public class ConfigDialog extends AbstractConfigDialog { * @param configuration the blender config to store */ private void storeConfig(BlenderKeyConfiguration configuration) { - if (configuration.lastUsedKey != null) {//reading animations + BlenderKey blenderKey = configuration.lastUsedKey.get(configuration.lastVersionUsed); + if (blenderKey != null) {//reading animations DefaultTableModel animationsTableModel = (DefaultTableModel) jTableAnimations.getModel(); - if (configuration.lastUsedKey.getAnimations() != null) { - configuration.lastUsedKey.getAnimations().clear(); + if (blenderKey.getAnimations() != null) { + blenderKey.getAnimations().clear(); } int animCounter = 0; for (int i = 0; i < animationsTableModel.getRowCount(); ++i) { @@ -239,7 +256,7 @@ public class ConfigDialog extends AbstractConfigDialog { Number startFrame = (Number) animationsTableModel.getValueAt(i, 2); Number stopFrame = (Number) animationsTableModel.getValueAt(i, 3); if (objectName != null && animName != null && startFrame.intValue() <= stopFrame.intValue()) { - configuration.lastUsedKey.addAnimation(objectName, animName, startFrame.intValue(), stopFrame.intValue()); + blenderKey.addAnimation(objectName, animName, startFrame.intValue(), stopFrame.intValue()); ++animCounter; } } @@ -255,7 +272,7 @@ public class ConfigDialog extends AbstractConfigDialog { //storing the config JmeExporter jmeExporter = new BinaryExporter(); try { - if (!jmeExporter.save(configuration, configFile)) { + if (!jmeExporter.save(configuration, new File(baseFolderName, "test.conf"))) { JOptionPane.showMessageDialog(ConfigDialog.this, "Unable to save the config data!", "Config save problem", JOptionPane.ERROR_MESSAGE); } } catch (IOException e) { @@ -273,26 +290,8 @@ public class ConfigDialog extends AbstractConfigDialog { @Override public void actionPerformed(ActionEvent evt) { - //save the previous congifuration - if (blenderKeyConfiguration != null) { - ConfigDialog.this.storeConfig(blenderKeyConfiguration); - blenderKeyConfiguration = null; - } - - //load new configuration - File[] blenderFiles = ConfigDialog.this.prepareFilesList(baseFolderName + '/' + jComboBoxVersionSelection.getSelectedItem().toString()); - if (blenderKeyConfiguration.lastUsedKey != null) { - for (int i = 0; i < blenderFiles.length; ++i) { - if (blenderFiles[i].getPath().equalsIgnoreCase(blenderKeyConfiguration.lastUsedKey.getName())) { - jListBlenderFiles.setSelectedIndex(i); - break; - } - } - } - if (blenderKeyConfiguration.logLevel == null) { - blenderKeyConfiguration.logLevel = Level.INFO; - } - JRadioButtonLevel.setSelectedLevel(blenderKeyConfiguration.logLevel); + blenderKeyConfiguration.lastVersionUsed = jComboBoxVersionSelection.getSelectedItem().toString(); + ConfigDialog.this.reloadFilesList(); } }); //selection of the file changes the config on the right @@ -302,16 +301,26 @@ public class ConfigDialog extends AbstractConfigDialog { public void valueChanged(ListSelectionEvent evt) { BlenderKeyConfiguration config = ConfigDialog.this.blenderKeyConfiguration; FileListItem selectedItem = (FileListItem) ConfigDialog.this.jListBlenderFiles.getSelectedValue(); + String blenderVersion = config.lastVersionUsed; if (selectedItem != null) { - String fileName = selectedItem.getFile().getName(); - config.lastUsedKey = config.blenderKeys.get(fileName); - if (config.lastUsedKey == null) { - config.lastUsedKey = new BlenderKey(selectedItem.getFile().getPath()); - config.blenderKeys.put(fileName, config.lastUsedKey); + String blenderFileName = selectedItem.getFile().getName(); + BlenderKey blenderKey = null; + Map blenderKeys = config.blenderKeys.get(blenderVersion); + if(blenderKeys != null) { + blenderKey = blenderKeys.get(blenderFileName); + if(blenderKey == null) { + blenderKey = new BlenderKey(ConfigDialog.this.baseFolderName+'/' + blenderVersion + '/' + blenderFileName); + } + } else { + blenderKeys = new HashMap(); + blenderKey = new BlenderKey(ConfigDialog.this.baseFolderName+'/' + blenderVersion + '/' + blenderFileName); + blenderKeys.put(blenderFileName, blenderKey); + config.blenderKeys.put(blenderVersion, blenderKeys); } - ConfigDialog.this.setBlenderKey(config.lastUsedKey); + config.lastUsedKey.put(blenderVersion, blenderKey); + ConfigDialog.this.setBlenderKey(config.lastUsedKey.get(blenderVersion)); } else { - config.lastUsedKey = null; + config.lastUsedKey.put(blenderVersion, null); } } }); @@ -324,10 +333,11 @@ public class ConfigDialog extends AbstractConfigDialog { int row = evt.getFirstRow(); String name = (String) jTableProperties.getModel().getValueAt(row, 0); Object value = jTableProperties.getModel().getValueAt(row, 1); + BlenderKey blenderKey = config.lastUsedKey.get(config.lastVersionUsed); try { - Field field = config.lastUsedKey.getClass().getDeclaredField(name); + Field field = blenderKey.getClass().getDeclaredField(name); field.setAccessible(true); - field.set(config.lastUsedKey, value); + field.set(blenderKey, value); } catch (IllegalArgumentException e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); } catch (SecurityException e) { @@ -368,23 +378,11 @@ public class ConfigDialog extends AbstractConfigDialog { } } }); - - //button listeners jButtonOK.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { ConfigDialog.this.storeConfig(blenderKeyConfiguration); - //running the test - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - configExecutable.execute(ConfigDialog.this.blenderKeyConfiguration.getKeyToUse(), - ConfigDialog.this.blenderKeyConfiguration.logLevel); - } - }); - //disposing the config window ConfigDialog.this.dispose(); } }); @@ -403,52 +401,84 @@ public class ConfigDialog extends AbstractConfigDialog { * @author Marcin Roguski (Kaelthas) */ public static class BlenderKeyConfiguration implements Savable { - - private Map blenderKeys; - private BlenderKey lastUsedKey; + /** + * The key is a directory of blender_version_folder. + * The value is the map between the blender file name and its blender key. + */ + private Map> blenderKeys; + /** The last version of blender opened. */ + private String lastVersionUsed; + /** The last used blender key for each blender version. */ + private Map lastUsedKey; + /** Last used log level. */ private Level logLevel; + /** This variable tells if the model or blender loader is used. */ private boolean useModelKey; - + /** - * Constructor for jme serialization. + * Constructor that creates new empty configuration for every blender file. + * Also used for jme serialization. */ public BlenderKeyConfiguration() { - } + blenderKeys = new HashMap>(); + lastUsedKey = new HashMap(); + logLevel = Level.INFO; + } /** - * Constructor that creates new empty configuration for every blender file. - * @param blenderFilesAmount the amount of blender files + * This method returns the name of the last used asset folder. + * @return the name of the last used asset folder */ - public BlenderKeyConfiguration(int blenderFilesAmount) { - blenderKeys = new HashMap(blenderFilesAmount); - } - + public String getLastVersionUsed() { + return lastVersionUsed; + } + + /** + * This method returns the log level of jme app. + * @return the log level of jme app + */ + public Level getLogLevel() { + return logLevel; + } + /** * This method returns the key that will be used during the test. * @return the key that will be used during the test */ public ModelKey getKeyToUse() { - return useModelKey ? new ModelKey(lastUsedKey.getName()) : lastUsedKey; + return useModelKey ? new ModelKey(lastUsedKey.get(lastVersionUsed).getName()) : lastUsedKey.get(lastVersionUsed); } @Override public void write(JmeExporter ex) throws IOException { OutputCapsule oc = ex.getCapsule(this); - oc.writeStringSavableMap(blenderKeys, "keys", null); - oc.write(lastUsedKey, "last-key", null); + oc.write(blenderKeys.size(), "versions-count", 0); + int i=0; + for(Entry> entry : blenderKeys.entrySet()) { + oc.write(entry.getKey(), "key" + i, null); + oc.writeStringSavableMap(entry.getValue(), "value" + i++, null); + } + oc.writeStringSavableMap(lastUsedKey, "last-key", null); oc.write(useModelKey, "use-model-key", false); oc.write(logLevel == null ? null : logLevel.getName(), "log-level", Level.INFO.getName()); + oc.write(lastVersionUsed, "versionUsed", null); } @Override @SuppressWarnings("unchecked") public void read(JmeImporter im) throws IOException { InputCapsule ic = im.getCapsule(this); - blenderKeys = (Map) ic.readStringSavableMap("keys", null); - lastUsedKey = (BlenderKey) ic.readSavable("last-key", null); + int versionsCount = ic.readInt("versions-count", 0); + for(int i=0;i versionBlenderFiles = (Map) ic.readStringSavableMap("value" + i, null); + blenderKeys.put(versionName, versionBlenderFiles); + } + lastUsedKey = (Map) ic.readStringSavableMap("last-key", null); useModelKey = ic.readBoolean("use-model-key", false); String logLevelName = ic.readString("log-level", Level.INFO.getName()); logLevel = logLevelName == null ? Level.INFO : Level.parse(logLevelName); + lastVersionUsed = ic.readString("versionUsed", null); } } } diff --git a/engine/src/test/jme3test/blender/config/ConfigExecutable.java b/engine/src/test/jme3test/blender/config/ConfigExecutable.java deleted file mode 100644 index 65ca0ca0d..000000000 --- a/engine/src/test/jme3test/blender/config/ConfigExecutable.java +++ /dev/null @@ -1,21 +0,0 @@ -package jme3test.blender.config; - -import java.util.logging.Level; - -import com.jme3.asset.ModelKey; - -/** - * This interface provides a method that allows to execute a method after the config has been properly set. It actually runs the test - * itself. - * @author Marcin Roguski (Kaelthas) - */ -public interface ConfigExecutable { - /** - * This method runs the test with the given blender key. - * @param modelKey - * the model key - * @param logLevel - * the jme3 logger log level - */ - void execute(ModelKey modelKey, Level logLevel); -}