package net.sf.jeters.components.DefaultGUI;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import net.sf.jeters.componentInterface.Component;
import net.sf.jeters.componentInterface.ComponentManager;
import net.sf.jeters.configuration.Configuration;
class ConfigurationFrame extends JFrame {
private final ComponentManager componentManager;
private final JTable table;
private final List<Field> fields;
private final Class<? extends Component> configuredClass;
public ConfigurationFrame(final DefaultGUI gui,
final ComponentManagementFrame componentMF,
ComponentManager componentManager,
Configuration initialConfiguration) {
super(gui.str("titleConfigurationFrame", initialConfiguration.getConfiguredClass().getSimpleName()));
componentMF.setEnabled(false);
this.componentManager = componentManager;
this.configuredClass = (Class<? extends Component>) initialConfiguration.getConfiguredClass();
this.fields = new ArrayList<Field>(initialConfiguration.getConfigurableFields());
this.setLayout(new BorderLayout());
{
table = new JTable(fields.size(), 2);
for (int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex ++) {
Field field = fields.get(fieldIndex);
Object value = initialConfiguration.getValue(field);
table.setValueAt(field.getName(), fieldIndex, 0);
table.setValueAt(getStringForValue(field, value), fieldIndex, 1);
}
makeColumnNotEditable(table, 0);
table.getColumnModel().getColumn(0).setHeaderValue(gui.str("optionColumn"));
table.getColumnModel().getColumn(1).setHeaderValue(gui.str("valueColumn"));
JScrollPane tableScrollPane = new JScrollPane(table);
this.add(tableScrollPane, BorderLayout.CENTER);
} {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
buttonPanel.add(Box.createGlue());
JButton okButton = new JButton(gui.str("buttonOK"));
okButton.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
setChangedConfiguration();
ConfigurationFrame.this.dispose();
}
});
buttonPanel.add(okButton);
JButton cancelButton = new JButton(gui.str("buttonCancel"));
cancelButton.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
ConfigurationFrame.this.dispose();
}
});
buttonPanel.add(cancelButton);
buttonPanel.add(Box.createGlue());
this.add(buttonPanel, BorderLayout.SOUTH);
}
this.pack();
this.setSize(400, Math.min(800, this.getHeight()));
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
componentMF.setEnabled(true);
}
public void windowClosed(WindowEvent e) {
super.windowClosed(e);
componentMF.setEnabled(true);
}
});
}
private void setChangedConfiguration() {
Configuration configuration = new Configuration(configuredClass);
for (int row = 0; row < table.getRowCount(); row++) {
String fieldName = (String)table.getValueAt(row, 0);
String valueString = (String)table.getValueAt(row, 1);
Field field = null;
for (Field f : configuration.getConfigurableFields()) {
if (f.getName().equals(fieldName)) {
field = f;
break;
}
}
if (field != null) {
Object value = getValueForString(field, valueString);
configuration.setValue(field, value);
} else {
throw new Error("unknown field in configuration table: " + fieldName);
}
componentManager.setComponentClassBaseConfiguration(configuredClass, configuration);
}
componentManager.setComponentClassBaseConfiguration(
configuredClass, configuration);
}
private String getStringForValue(Field field, Object value) {
assert field != null && value != null;
if (boolean.class.equals(field.getType())
|| int.class.equals(field.getType())
|| float.class.equals(field.getType())
|| String.class.equals(field.getType())) {
return value.toString();
} else if (boolean[].class.equals(field.getType())
|| int[].class.equals(field.getType())
|| float[].class.equals(field.getType())
|| String[].class.equals(field.getType())) {
StringBuilder result = new StringBuilder();
Object[] array = (Object[])value;
for (Object object : array) {
result.append(object);
result.append(";");
}
return result.toString();
} else {
throw new IllegalArgumentException(field.getType().getSimpleName() + " is invalid type for config field");
}
}
private Object getValueForString(Field field, String valueString) {
assert field != null && valueString != null;
if (boolean.class.equals(field.getType())) {
return Boolean.parseBoolean(valueString);
} else if (int.class.equals(field.getType())) {
return Integer.parseInt(valueString);
} else if (float.class.equals(field.getType())) {
return Float.parseFloat(valueString);
} else if (String.class.equals(field.getType())) {
return valueString;
} else {
String[] strings = valueString.split(";");
if (boolean[].class.equals(field.getType())) {
boolean[] result = new boolean[strings.length];
for (int i=0; i < strings.length; i++) {
result[i] = Boolean.parseBoolean(strings[i]);
}
return result;
} else if (int[].class.equals(field.getType())) {
int[] result = new int[strings.length];
for (int i=0; i < strings.length; i++) {
result[i] = Integer.parseInt(strings[i]);
}
return result;
} else if (float[].class.equals(field.getType())) {
float[] result = new float[strings.length];
for (int i=0; i < strings.length; i++) {
result[i] = Float.parseFloat(strings[i]);
}
return result;
} else if (String[].class.equals(field.getType())) {
return strings;
} else {
throw new IllegalArgumentException(field.getType().getSimpleName() + " is invalid type for config field");
}
}
}
private static void makeColumnNotEditable(final JTable table, final int noEditColumnIndex) {
final TableModel oldModel = table.getModel();
final TableModel newModel = new TableModel() {
@Override public boolean isCellEditable(int rowIndex, int columnIndex) {
if (columnIndex == noEditColumnIndex) {
return false;
} else {
return oldModel.isCellEditable(rowIndex, columnIndex);
}
}
// the other methods simply use oldModel
@Override public void addTableModelListener(TableModelListener l) {
oldModel.addTableModelListener(l);
}
@Override public Class<?> getColumnClass(int columnIndex) {
return oldModel.getColumnClass(columnIndex);
}
@Override public int getColumnCount() {
return oldModel.getColumnCount();
}
@Override public String getColumnName(int columnIndex) {
return oldModel.getColumnName(columnIndex);
}
@Override public int getRowCount() {
return oldModel.getRowCount();
}
@Override public Object getValueAt(int rowIndex, int columnIndex) {
return oldModel.getValueAt(rowIndex, columnIndex);
}
@Override public void removeTableModelListener(TableModelListener l) {
oldModel.removeTableModelListener(l);
}
@Override public void setValueAt(Object value,
int rowIndex, int columnIndex) {
oldModel.setValueAt(value, rowIndex, columnIndex);
}
};
table.setModel(newModel);
}
}