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