git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7886 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
06264e69bf
commit
e911e3299e
@ -0,0 +1,185 @@ |
|||||||
|
package jme3test.blender.config; |
||||||
|
|
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Random; |
||||||
|
import java.util.Vector; |
||||||
|
|
||||||
|
import javax.swing.DefaultCellEditor; |
||||||
|
import javax.swing.DefaultListSelectionModel; |
||||||
|
import javax.swing.JFrame; |
||||||
|
import javax.swing.JRadioButton; |
||||||
|
import javax.swing.JScrollPane; |
||||||
|
import javax.swing.JTable; |
||||||
|
import javax.swing.JTextField; |
||||||
|
import javax.swing.event.TableModelEvent; |
||||||
|
import javax.swing.event.TableModelListener; |
||||||
|
import javax.swing.table.DefaultTableCellRenderer; |
||||||
|
import javax.swing.table.DefaultTableModel; |
||||||
|
|
||||||
|
/** |
||||||
|
* Table for displaying and managing animations to import. |
||||||
|
* @author Marcin Roguski (Kaelthas) |
||||||
|
*/ |
||||||
|
public class AnimationsTable extends JTable { |
||||||
|
private static final long serialVersionUID = 1978778634957586330L; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. Creates default model. Applies basic settings. |
||||||
|
*/ |
||||||
|
public AnimationsTable() { |
||||||
|
super(new AnimationsTableModel(new Object[] {null, "Object name", "Animation name", "Start", "Stop"})); |
||||||
|
this.getTableHeader().setReorderingAllowed(false); |
||||||
|
this.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION); |
||||||
|
CellRenderer cellRenderer = new CellRenderer(); |
||||||
|
this.setDefaultRenderer(Object.class, cellRenderer); |
||||||
|
this.getModel().addTableModelListener(cellRenderer); |
||||||
|
this.getColumnModel().getColumn(0).setCellEditor(new RadioButtonCellEditor()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This class represents the model where all cells are editable and animations are always grouped |
||||||
|
* by object. |
||||||
|
* @author Marcin Roguski (Kaelthas) |
||||||
|
*/ |
||||||
|
private static final class AnimationsTableModel extends DefaultTableModel { |
||||||
|
private static final long serialVersionUID = 8285912542455513806L; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. Creates table with given columns and no rows. |
||||||
|
* @param columnNames the names of the columns |
||||||
|
*/ |
||||||
|
public AnimationsTableModel(Object[] columnNames) { |
||||||
|
super(columnNames, 0); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isCellEditable(int row, int column) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
@SuppressWarnings("rawtypes") |
||||||
|
public void addRow(Vector rowData) { |
||||||
|
String objectName = (String) rowData.get(1); |
||||||
|
int index = 0; |
||||||
|
boolean objectFound = false; |
||||||
|
for(int i=0;i<this.getRowCount();++i) { |
||||||
|
String name = (String)this.getValueAt(i, 1); |
||||||
|
if(name.equals(objectName)) { |
||||||
|
index = i; |
||||||
|
objectFound = true; |
||||||
|
} |
||||||
|
} |
||||||
|
if(objectFound) { |
||||||
|
this.insertRow(index + 1, rowData); |
||||||
|
} else { |
||||||
|
super.addRow(rowData); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This class renders each group (specified by object) to one of the colors so that they are |
||||||
|
* easily recognizable. It also renderes selected row with JRadioButton. |
||||||
|
* @author Marcin Roguski (Kaelthas) |
||||||
|
*/ |
||||||
|
private static final class CellRenderer extends DefaultTableCellRenderer implements TableModelListener { |
||||||
|
private static final long serialVersionUID = 3759759133199203533L; |
||||||
|
|
||||||
|
/** Index of the object (specifies the object's group color. */ |
||||||
|
private Map<String, Integer> objectIndex = new HashMap<String, Integer>(); |
||||||
|
/** The other color for the group (the first one is WHITE. */ |
||||||
|
private Color color = new Color(240, 240, 240); |
||||||
|
/** Radio button to display row selection. */ |
||||||
|
private JRadioButton jRadioButton = new JRadioButton(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, |
||||||
|
int column) { |
||||||
|
Object objectName = table.getModel().getValueAt(row, 1); |
||||||
|
Component component; |
||||||
|
if(column == 0) { |
||||||
|
jRadioButton.setSelected((Boolean)value); |
||||||
|
component = jRadioButton; |
||||||
|
} else { |
||||||
|
component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); |
||||||
|
} |
||||||
|
|
||||||
|
Integer index = objectIndex.get(objectName); |
||||||
|
if(index != null) { |
||||||
|
if(index.intValue() % 2 == 1) { |
||||||
|
component.setBackground(color); |
||||||
|
} else { |
||||||
|
component.setBackground(Color.WHITE); |
||||||
|
} |
||||||
|
} |
||||||
|
return component; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void tableChanged(TableModelEvent evt) { |
||||||
|
if(evt.getType() == TableModelEvent.INSERT) { |
||||||
|
DefaultTableModel model = (DefaultTableModel)evt.getSource(); |
||||||
|
for(int i=evt.getFirstRow();i<=evt.getLastRow();++i) { |
||||||
|
String objectName = (String) model.getValueAt(i, 1); |
||||||
|
if(!objectIndex.containsKey(objectName)) { |
||||||
|
objectIndex.put(objectName, Integer.valueOf(objectIndex.size())); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This editor is used for the first column to allow the edition of row selection. |
||||||
|
* @author Marcin Roguski (Kaelthas) |
||||||
|
*/ |
||||||
|
private static final class RadioButtonCellEditor extends DefaultCellEditor { |
||||||
|
private static final long serialVersionUID = 7697027333456874718L; |
||||||
|
/** Component that allows editing. */ |
||||||
|
private JRadioButton jRadioButton = new JRadioButton(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
*/ |
||||||
|
public RadioButtonCellEditor() { |
||||||
|
super(new JTextField()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||||
|
jRadioButton.setSelected((Boolean)value); |
||||||
|
return jRadioButton; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getCellEditorValue() { |
||||||
|
return Boolean.valueOf(jRadioButton.isSelected()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
JFrame frame = new JFrame(); |
||||||
|
frame.setLayout(new BorderLayout()); |
||||||
|
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); |
||||||
|
|
||||||
|
Random random = new Random(System.currentTimeMillis()); |
||||||
|
AnimationsTable table = new AnimationsTable(); |
||||||
|
int objectsCount = random.nextInt(5) + 1; |
||||||
|
for(int i=1;i<=objectsCount;++i) { |
||||||
|
int animsCount = random.nextInt(7) + 1; |
||||||
|
for(int j=1;j<=animsCount;++j) { |
||||||
|
((DefaultTableModel)table.getModel()).addRow(new Object[] {Boolean.FALSE, "Obiekt" + i, "Animacja" + j, "Start" + j, "Stop" + j}); |
||||||
|
} |
||||||
|
} |
||||||
|
((DefaultTableModel)table.getModel()).addRow(new Object[] {Boolean.FALSE, "Obiekt1", "xxx", "xxx", "xxx"}); |
||||||
|
JScrollPane jScrollPane = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); |
||||||
|
frame.add(jScrollPane, BorderLayout.CENTER); |
||||||
|
frame.pack(); |
||||||
|
frame.setVisible(true); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,127 @@ |
|||||||
|
package jme3test.blender.config; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Map.Entry; |
||||||
|
import java.util.logging.Level; |
||||||
|
|
||||||
|
import com.jme3.asset.BlenderKey; |
||||||
|
import com.jme3.asset.ModelKey; |
||||||
|
import com.jme3.export.InputCapsule; |
||||||
|
import com.jme3.export.JmeExporter; |
||||||
|
import com.jme3.export.JmeImporter; |
||||||
|
import com.jme3.export.OutputCapsule; |
||||||
|
import com.jme3.export.Savable; |
||||||
|
|
||||||
|
/** |
||||||
|
* This class holds the configuration for all the files. |
||||||
|
* It can be saved and loaded using jme mechanisms. |
||||||
|
* @author Marcin Roguski (Kaelthas) |
||||||
|
*/ |
||||||
|
public class BlenderKeyConfiguration implements Savable { |
||||||
|
/** |
||||||
|
* The key is a directory of blender_version_folder. |
||||||
|
* The value is the map between the blender file name and its blender key. |
||||||
|
*/ |
||||||
|
/*package*/ Map<String, Map<String, BlenderKey>> blenderKeys; |
||||||
|
/** List of selected animations for each object. An object can have one active animations.*/ |
||||||
|
/*package*/ Map<String, List<String[]>> selectedAnimations; |
||||||
|
/** The last version of blender opened. */ |
||||||
|
/*package*/ String lastVersionUsed; |
||||||
|
/** The last used blender key for each blender version. */ |
||||||
|
/*package*/ Map<String, BlenderKey> lastUsedKey; |
||||||
|
/** Last used log level. */ |
||||||
|
/*package*/ Level logLevel; |
||||||
|
/** This variable tells if the model or blender loader is used. */ |
||||||
|
/*package*/ boolean useModelKey; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor that creates new empty configuration for every blender file. |
||||||
|
* Also used for jme serialization. |
||||||
|
*/ |
||||||
|
public BlenderKeyConfiguration() { |
||||||
|
blenderKeys = new HashMap<String, Map<String, BlenderKey>>(); |
||||||
|
selectedAnimations = new HashMap<String, List<String[]>>(); |
||||||
|
lastUsedKey = new HashMap<String, BlenderKey>(); |
||||||
|
logLevel = Level.INFO; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This method returns the name of the last used asset folder. |
||||||
|
* @return the name of the last used asset folder |
||||||
|
*/ |
||||||
|
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.get(lastVersionUsed).getName()) : lastUsedKey.get(lastVersionUsed); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void write(JmeExporter ex) throws IOException { |
||||||
|
OutputCapsule oc = ex.getCapsule(this); |
||||||
|
oc.write(blenderKeys.size(), "versions-count", 0); |
||||||
|
int i=0; |
||||||
|
for(Entry<String, Map<String, BlenderKey>> entry : blenderKeys.entrySet()) { |
||||||
|
oc.write(entry.getKey(), "key" + i, null); |
||||||
|
oc.writeStringSavableMap(entry.getValue(), "value" + i++, null); |
||||||
|
} |
||||||
|
oc.writeStringSavableMap(lastUsedKey, "last-key", null); |
||||||
|
if(selectedAnimations==null) { |
||||||
|
oc.write(0, "selected-animations-count", 0); |
||||||
|
} else { |
||||||
|
i = 0; |
||||||
|
oc.write(selectedAnimations.size(), "selected-animations-count", 0); |
||||||
|
for(Entry<String, List<String[]>> entry : selectedAnimations.entrySet()) { |
||||||
|
oc.write(entry.getKey(), "animKey" + i, null); |
||||||
|
oc.write(entry.getValue().toArray(new String[selectedAnimations.size()][]), "animVal" + i++, 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); |
||||||
|
int versionsCount = ic.readInt("versions-count", 0); |
||||||
|
for(int i=0;i<versionsCount;++i) { |
||||||
|
String versionName = ic.readString("key" + i, null); |
||||||
|
Map<String, BlenderKey> versionBlenderFiles = (Map<String, BlenderKey>) ic.readStringSavableMap("value" + i, null); |
||||||
|
blenderKeys.put(versionName, versionBlenderFiles); |
||||||
|
} |
||||||
|
|
||||||
|
int selectedAnimCount = ic.readInt("selected-animations-count", 0); |
||||||
|
if(selectedAnimCount > 0) { |
||||||
|
for(int i=0;i<selectedAnimCount;++i) { |
||||||
|
String blenderKeyName = ic.readString("animKey" + i, null); |
||||||
|
String[][] selectedAnimations = ic.readStringArray2D("animVal" + i, null); |
||||||
|
List<String[]> anims = Arrays.asList(selectedAnimations); |
||||||
|
this.selectedAnimations.put(blenderKeyName, anims); |
||||||
|
} |
||||||
|
} |
||||||
|
lastUsedKey = (Map<String, BlenderKey>) 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); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue