A complete 3D game development suite written purely in Java.
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.
 
 
 
 
 
jmonkeyengine/engine/src/test/jme3test/blender/config/AbstractConfigDialog.java

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;
}
}
}