You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
15 KiB
381 lines
15 KiB
package jme3test.blender.config;
|
|
|
|
import java.awt.BorderLayout;
|
|
import java.awt.Component;
|
|
import java.awt.FlowLayout;
|
|
import java.awt.Insets;
|
|
import java.awt.Label;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.io.File;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import javax.swing.AbstractCellEditor;
|
|
import javax.swing.Box;
|
|
import javax.swing.ButtonGroup;
|
|
import javax.swing.DefaultComboBoxModel;
|
|
import javax.swing.DefaultListModel;
|
|
import javax.swing.DefaultListSelectionModel;
|
|
import javax.swing.JButton;
|
|
import javax.swing.JCheckBox;
|
|
import javax.swing.JComboBox;
|
|
import javax.swing.JFrame;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JList;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.JRadioButton;
|
|
import javax.swing.JScrollPane;
|
|
import javax.swing.JTable;
|
|
import javax.swing.JTextField;
|
|
import javax.swing.ListSelectionModel;
|
|
import javax.swing.UIManager;
|
|
import javax.swing.UnsupportedLookAndFeelException;
|
|
import javax.swing.border.EmptyBorder;
|
|
import javax.swing.border.TitledBorder;
|
|
import javax.swing.table.DefaultTableModel;
|
|
import javax.swing.table.TableCellEditor;
|
|
|
|
/**
|
|
* A base class for defining the start configuration.
|
|
* This separates the gui window definition from its logic.
|
|
* It is made so to easier maintain the dialog window.
|
|
* @author Marcin Roguski (Kaelthas)
|
|
*/
|
|
public abstract class AbstractConfigDialog extends JFrame {
|
|
|
|
private static final long serialVersionUID = -3677493125861310310L;
|
|
private static final Logger LOGGER = Logger.getLogger(AbstractConfigDialog.class.getName());
|
|
protected JComboBox jComboBoxVersionSelection;
|
|
protected JList jListBlenderFiles;
|
|
protected JTable jTableProperties;
|
|
protected JTable jTableAnimations;
|
|
protected JButton jButtonAddAnimation;
|
|
protected JButton jButtonRemoveAnimation;
|
|
protected JCheckBox jCheckBoxUseModelKey;
|
|
protected JButton jButtonOK;
|
|
protected JButton jButtonCancel;
|
|
|
|
/**
|
|
* Cionstructor initializes the gui.
|
|
*/
|
|
public AbstractConfigDialog() {
|
|
this.init();
|
|
}
|
|
|
|
/**
|
|
* This method initializes the window.
|
|
*/
|
|
private void init() {
|
|
try {//setting the system Look And Feel
|
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
} catch (ClassNotFoundException e) {
|
|
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
|
} catch (InstantiationException e) {
|
|
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
|
} catch (IllegalAccessException e) {
|
|
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
|
} catch (UnsupportedLookAndFeelException e) {
|
|
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
|
}
|
|
this.setLayout(new BorderLayout());
|
|
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* This method prepares a swing panel containing the list of blender files
|
|
* and log level chooser.
|
|
* @return prepared swing panel
|
|
*/
|
|
private JPanel prepareBlenderFilesAndLogLevelPanel() {
|
|
JPanel jPanelBlenderFilesListAndLogLevel = new JPanel();
|
|
jPanelBlenderFilesListAndLogLevel.setBorder(new TitledBorder("Blender test files"));
|
|
jPanelBlenderFilesListAndLogLevel.setLayout(new BorderLayout());
|
|
|
|
//blender version selection combo box
|
|
jComboBoxVersionSelection = new JComboBox(new DefaultComboBoxModel());
|
|
jComboBoxVersionSelection.setEditable(false);
|
|
jPanelBlenderFilesListAndLogLevel.add(jComboBoxVersionSelection, BorderLayout.NORTH);
|
|
|
|
//blender list files
|
|
jListBlenderFiles = new JList(new DefaultListModel());
|
|
jListBlenderFiles.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
|
JScrollPane listScroller = new JScrollPane(jListBlenderFiles);
|
|
jPanelBlenderFilesListAndLogLevel.add(listScroller, BorderLayout.CENTER);
|
|
|
|
//Log Level list
|
|
Box box = Box.createVerticalBox();
|
|
box.add(new Label("Log level:"));
|
|
ButtonGroup buttonGroup = new ButtonGroup();
|
|
|
|
Level[] levels = new Level[]{Level.OFF, Level.SEVERE, Level.WARNING, Level.INFO,
|
|
Level.CONFIG, Level.FINE, Level.FINER, Level.FINEST, Level.ALL};
|
|
for (Level level : levels) {
|
|
JRadioButtonLevel jRadioButtonLevel = new JRadioButtonLevel(level);
|
|
buttonGroup.add(jRadioButtonLevel);
|
|
box.add(jRadioButtonLevel);
|
|
}
|
|
jPanelBlenderFilesListAndLogLevel.add(box, BorderLayout.SOUTH);
|
|
|
|
return jPanelBlenderFilesListAndLogLevel;
|
|
}
|
|
|
|
/**
|
|
* This method prepares a swing panel containing the file's animations.
|
|
* @return prepared swing panel
|
|
*/
|
|
protected JPanel prepareFilePropertiesPanel() {
|
|
//properties table
|
|
JPanel jPanelProperties = new JPanel();
|
|
jPanelProperties.setBorder(new EmptyBorder(new Insets(0, 5, 0, 5)));
|
|
jPanelProperties.setLayout(new BorderLayout());
|
|
jPanelProperties.add(new JLabel("Properties"), BorderLayout.NORTH);
|
|
|
|
jTableProperties = new JTable();
|
|
jTableProperties.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
|
|
jTableProperties.setModel(new BlenderTableModel(new Object[]{"Name", "Value"}));
|
|
jTableProperties.getColumnModel().getColumn(1).setCellEditor(new BlenderTableCellEditor());
|
|
JScrollPane jScrollPaneProperties = new JScrollPane(jTableProperties);
|
|
jTableProperties.setFillsViewportHeight(true);
|
|
|
|
jPanelProperties.add(jScrollPaneProperties, BorderLayout.CENTER);
|
|
|
|
//animations table
|
|
JPanel jPanelAnimations = new JPanel();
|
|
jPanelAnimations.setBorder(new EmptyBorder(new Insets(0, 5, 0, 5)));
|
|
jPanelAnimations.setLayout(new BorderLayout());
|
|
jPanelAnimations.add(new JLabel("Animations"), BorderLayout.NORTH);
|
|
|
|
jTableAnimations = new JTable();
|
|
jTableAnimations.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
|
|
jTableAnimations.setModel(new DefaultTableModel(new Object[]{"Object", "Name", "Start frame", "Stop frame"}, 0));
|
|
for (int i = 0; i < jTableAnimations.getColumnModel().getColumnCount(); ++i) {
|
|
jTableAnimations.getColumnModel().getColumn(i).setCellEditor(new BlenderTableCellEditor());
|
|
}
|
|
JScrollPane jScrollPaneAnimations = new JScrollPane(jTableAnimations);
|
|
jTableAnimations.setFillsViewportHeight(true);
|
|
|
|
JPanel jPanelTableButtons = new JPanel();
|
|
jPanelTableButtons.setLayout(new FlowLayout(FlowLayout.LEFT));
|
|
jButtonAddAnimation = new JButton("Add animation");
|
|
jButtonAddAnimation.setEnabled(false);
|
|
jButtonRemoveAnimation = new JButton("Remove animation");
|
|
jButtonRemoveAnimation.setEnabled(false);
|
|
jPanelTableButtons.add(jButtonAddAnimation);
|
|
jPanelTableButtons.add(jButtonRemoveAnimation);
|
|
|
|
jPanelAnimations.add(jScrollPaneAnimations, BorderLayout.CENTER);
|
|
jPanelAnimations.add(jPanelTableButtons, BorderLayout.SOUTH);
|
|
|
|
//model key check-box
|
|
jCheckBoxUseModelKey = new JCheckBox();
|
|
jCheckBoxUseModelKey.setText("Use ModelKey to start the test");
|
|
jCheckBoxUseModelKey.setToolTipText("All BlenderKey settings will remain here, but the application will be "
|
|
+ "started using a model key. So only the path to the file will be given!");
|
|
|
|
//building the result panel
|
|
JPanel jPanelResult = new JPanel();
|
|
jPanelResult.setBorder(new TitledBorder("Loading properties"));
|
|
jPanelResult.setLayout(new BorderLayout());
|
|
|
|
jPanelResult.add(jPanelProperties, BorderLayout.WEST);
|
|
jPanelResult.add(jPanelAnimations, BorderLayout.CENTER);
|
|
jPanelResult.add(jCheckBoxUseModelKey, BorderLayout.SOUTH);
|
|
return jPanelResult;
|
|
}
|
|
|
|
/**
|
|
* This method prepares a swing panel containing the buttons.
|
|
* @return prepared swing panel
|
|
*/
|
|
protected JPanel prepareButtonsPanel() {
|
|
JPanel jPanelButtons = new JPanel();
|
|
jButtonOK = new JButton("OK");
|
|
jButtonOK.setEnabled(false);
|
|
jPanelButtons.add(jButtonOK);
|
|
jButtonCancel = new JButton("Cancel");
|
|
jPanelButtons.add(jButtonCancel);
|
|
return jPanelButtons;
|
|
}
|
|
|
|
/**
|
|
* This class was made only to make the selection of a level radio button easier.
|
|
* @author Marcin Roguski
|
|
*/
|
|
protected static class JRadioButtonLevel extends JRadioButton {
|
|
|
|
private static final long serialVersionUID = 8874525909060993518L;
|
|
private static Level selectedLevel;
|
|
private static Map<Level, JRadioButtonLevel> radioButtons = new HashMap<Level, AbstractConfigDialog.JRadioButtonLevel>();
|
|
private Level level;
|
|
|
|
/**
|
|
* Constructor. Creates the radio button.
|
|
* Stores it inside the buttons map.
|
|
* @param level the level of log info
|
|
*/
|
|
public JRadioButtonLevel(Level level) {
|
|
super(level.getName());
|
|
this.level = level;
|
|
radioButtons.put(level, this);
|
|
this.addActionListener(new ActionListener() {
|
|
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
JRadioButtonLevel.selectedLevel = JRadioButtonLevel.this.level;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This method returns the currently selected info level.
|
|
* @return currently selected info level
|
|
*/
|
|
public static Level getSelectedLevel() {
|
|
return selectedLevel;
|
|
}
|
|
|
|
/**
|
|
* This method sets the current info level.
|
|
* @param level the current info level
|
|
*/
|
|
public static synchronized void setSelectedLevel(Level level) {
|
|
radioButtons.get(level).setSelected(true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This class is an item that should be stored in the files' list.
|
|
* @author Marcin Roguski (Kaelthas)
|
|
*/
|
|
protected static class FileListItem {
|
|
|
|
private File file; //the file to be stored
|
|
|
|
/**
|
|
* Constructore. Stores the given file.
|
|
* @param file the file to be stored
|
|
*/
|
|
public FileListItem(File file) {
|
|
this.file = file;
|
|
}
|
|
|
|
/**
|
|
* This method returns the stored file.
|
|
* @return the stored file
|
|
*/
|
|
public File getFile() {
|
|
return file;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return file.getName();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The model for properties table.
|
|
* It makes left column ineditable.
|
|
* @author Marcin Roguski (Kaelthas)
|
|
*/
|
|
protected static class BlenderTableModel extends DefaultTableModel {
|
|
|
|
private static final long serialVersionUID = -4211206550875326553L;
|
|
|
|
/**
|
|
* Constructor only calls super-constuctor.
|
|
* @param columnNames the names of table columns
|
|
*/
|
|
public BlenderTableModel(Object[] columnNames) {
|
|
super(columnNames, 0);
|
|
}
|
|
|
|
@Override
|
|
public void addRow(Object[] rowData) {
|
|
for (int i = 0; i < rowData.length; ++i) {
|
|
if (rowData[i] == null) {
|
|
rowData[i] = "";
|
|
}
|
|
}
|
|
super.addRow(rowData);
|
|
}
|
|
|
|
@Override
|
|
public boolean isCellEditable(int row, int column) {
|
|
return column > 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A cell editor tah improves data input to the table.
|
|
* @author Marcin Roguski (Kaelthas)
|
|
*/
|
|
protected static class BlenderTableCellEditor extends AbstractCellEditor implements TableCellEditor {
|
|
|
|
private static final long serialVersionUID = -8601975203921608519L;
|
|
private JCheckBox jCheckBox = new JCheckBox();
|
|
private JTextField jTextField = new JTextField();
|
|
private JComboBox jComboBox = new JComboBox();
|
|
private Object lastValue;
|
|
|
|
@Override
|
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
|
|
this.lastValue = value;
|
|
if (value instanceof Boolean) {
|
|
jCheckBox.setSelected(((Boolean) value).booleanValue());
|
|
return jCheckBox;
|
|
} else if (value instanceof String || value instanceof Number || value instanceof Character) {
|
|
jTextField.setText(value.toString());
|
|
return jTextField;
|
|
} else if (value instanceof Enum<?>) {
|
|
DefaultComboBoxModel defaultComboBoxModel = (DefaultComboBoxModel) jComboBox.getModel();
|
|
defaultComboBoxModel.removeAllElements();
|
|
for (Object object : value.getClass().getEnumConstants()) {
|
|
defaultComboBoxModel.addElement(object);
|
|
}
|
|
return jComboBox;
|
|
} else {
|
|
jTextField.setText(value == null ? "" : value.toString());
|
|
return jTextField;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Object getCellEditorValue() {
|
|
if (lastValue instanceof Boolean) {
|
|
return Boolean.valueOf(jCheckBox.isSelected());
|
|
} else if (lastValue instanceof String) {
|
|
return jTextField.getText();
|
|
} else if (lastValue instanceof Character) {
|
|
return Character.valueOf(jTextField.getText().charAt(0));
|
|
} else if (lastValue instanceof Byte) {
|
|
return Byte.valueOf(jTextField.getText());
|
|
} else if (lastValue instanceof Short) {
|
|
return Short.valueOf(jTextField.getText());
|
|
} else if (lastValue instanceof Integer) {
|
|
return Integer.valueOf(jTextField.getText());
|
|
} else if (lastValue instanceof Long) {
|
|
return Long.valueOf(jTextField.getText());
|
|
} else if (lastValue instanceof Float) {
|
|
return Float.valueOf(jTextField.getText());
|
|
} else if (lastValue instanceof Double) {
|
|
return Double.valueOf(jTextField.getText());
|
|
} else if (lastValue instanceof Enum<?>) {
|
|
return jComboBox.getSelectedItem();
|
|
}
|
|
//TODO: savable objects
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|