618 lines
19 KiB
Java
618 lines
19 KiB
Java
package net.sf.openrocket.gui.simulation;
|
|
|
|
import java.awt.Window;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.ItemEvent;
|
|
import java.awt.event.ItemListener;
|
|
import java.util.Arrays;
|
|
import java.util.EnumSet;
|
|
|
|
import javax.swing.BorderFactory;
|
|
import javax.swing.ButtonGroup;
|
|
import javax.swing.JButton;
|
|
import javax.swing.JComboBox;
|
|
import javax.swing.JComponent;
|
|
import javax.swing.JDialog;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JOptionPane;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.JRadioButton;
|
|
import javax.swing.JScrollPane;
|
|
import javax.swing.JTable;
|
|
import javax.swing.table.AbstractTableModel;
|
|
import javax.swing.table.TableColumn;
|
|
import javax.swing.table.TableColumnModel;
|
|
|
|
import net.miginfocom.swing.MigLayout;
|
|
import net.sf.openrocket.document.Simulation;
|
|
import net.sf.openrocket.gui.components.DescriptionArea;
|
|
import net.sf.openrocket.gui.components.UnitSelector;
|
|
import net.sf.openrocket.gui.plot.PlotConfiguration;
|
|
import net.sf.openrocket.gui.plot.SimulationPlotDialog;
|
|
import net.sf.openrocket.gui.util.GUIUtil;
|
|
import net.sf.openrocket.gui.util.Icons;
|
|
import net.sf.openrocket.gui.util.SwingPreferences;
|
|
import net.sf.openrocket.l10n.Translator;
|
|
import net.sf.openrocket.simulation.FlightDataBranch;
|
|
import net.sf.openrocket.simulation.FlightDataType;
|
|
import net.sf.openrocket.simulation.FlightEvent;
|
|
import net.sf.openrocket.startup.Application;
|
|
import net.sf.openrocket.startup.Preferences;
|
|
import net.sf.openrocket.unit.Unit;
|
|
import net.sf.openrocket.util.Utils;
|
|
import net.sf.openrocket.gui.widgets.SelectColorButton;
|
|
|
|
/**
|
|
* Panel that displays the simulation plot options to the user.
|
|
*
|
|
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
|
*/
|
|
public class SimulationPlotPanel extends JPanel {
|
|
private static final long serialVersionUID = -2227129713185477998L;
|
|
|
|
private static final Translator trans = Application.getTranslator();
|
|
private static final SwingPreferences preferences = (SwingPreferences) Application.getPreferences();
|
|
|
|
// TODO: LOW: Should these be somewhere else?
|
|
public static final int AUTO = -1;
|
|
public static final int LEFT = 0;
|
|
public static final int RIGHT = 1;
|
|
|
|
//// Auto
|
|
public static final String AUTO_NAME = trans.get("simplotpanel.AUTO_NAME");
|
|
//// Left
|
|
public static final String LEFT_NAME = trans.get("simplotpanel.LEFT_NAME");
|
|
//// Right
|
|
public static final String RIGHT_NAME = trans.get("simplotpanel.RIGHT_NAME");
|
|
|
|
//// Custom
|
|
private static final String CUSTOM = trans.get("simplotpanel.CUSTOM");
|
|
|
|
/** The "Custom" configuration - not to be used for anything other than the title. */
|
|
private static final PlotConfiguration CUSTOM_CONFIGURATION;
|
|
static {
|
|
CUSTOM_CONFIGURATION = new PlotConfiguration(CUSTOM);
|
|
}
|
|
|
|
/** The array of presets for the combo box. */
|
|
private static final PlotConfiguration[] PRESET_ARRAY;
|
|
static {
|
|
PRESET_ARRAY = Arrays.copyOf(PlotConfiguration.DEFAULT_CONFIGURATIONS,
|
|
PlotConfiguration.DEFAULT_CONFIGURATIONS.length + 1);
|
|
PRESET_ARRAY[PRESET_ARRAY.length - 1] = CUSTOM_CONFIGURATION;
|
|
}
|
|
|
|
|
|
|
|
/** The current default configuration, set each time a plot is made. */
|
|
private static PlotConfiguration defaultConfiguration =
|
|
PlotConfiguration.DEFAULT_CONFIGURATIONS[0].resetUnits();
|
|
|
|
|
|
private final Simulation simulation;
|
|
private final FlightDataType[] types;
|
|
private PlotConfiguration configuration;
|
|
|
|
|
|
private JComboBox<PlotConfiguration> configurationSelector;
|
|
|
|
private JComboBox<FlightDataType> domainTypeSelector;
|
|
private UnitSelector domainUnitSelector;
|
|
|
|
private JPanel typeSelectorPanel;
|
|
private FlightEventTableModel eventTableModel;
|
|
|
|
|
|
private int modifying = 0;
|
|
|
|
|
|
public SimulationPlotPanel(final Simulation simulation) {
|
|
super(new MigLayout("fill"));
|
|
|
|
this.simulation = simulation;
|
|
if (simulation.getSimulatedData() == null ||
|
|
simulation.getSimulatedData().getBranchCount() == 0) {
|
|
throw new IllegalArgumentException("Simulation contains no data.");
|
|
}
|
|
FlightDataBranch branch = simulation.getSimulatedData().getBranch(0);
|
|
types = branch.getTypes();
|
|
|
|
setConfiguration(defaultConfiguration);
|
|
|
|
//// Configuration selector
|
|
|
|
// Setup the combo box
|
|
configurationSelector = new JComboBox<PlotConfiguration>(PRESET_ARRAY);
|
|
for (PlotConfiguration config : PRESET_ARRAY) {
|
|
if (config.getName().equals(configuration.getName())) {
|
|
configurationSelector.setSelectedItem(config);
|
|
}
|
|
}
|
|
|
|
configurationSelector.addItemListener(new ItemListener() {
|
|
|
|
@Override
|
|
public void itemStateChanged(ItemEvent e) {
|
|
// We are only concerned with ItemEvent.SELECTED to update
|
|
// the UI when the selected item changes.
|
|
// TODO - this should probably be implemented as an ActionListener instead
|
|
// of ItemStateListener.
|
|
if (e.getStateChange() == ItemEvent.DESELECTED) {
|
|
return;
|
|
}
|
|
if (modifying > 0)
|
|
return;
|
|
PlotConfiguration conf = (PlotConfiguration) configurationSelector.getSelectedItem();
|
|
if (conf == CUSTOM_CONFIGURATION)
|
|
return;
|
|
modifying++;
|
|
setConfiguration(conf.clone().resetUnits());
|
|
updatePlots();
|
|
modifying--;
|
|
}
|
|
});
|
|
//// Preset plot configurations:
|
|
this.add(new JLabel(trans.get("simplotpanel.lbl.Presetplotconf")), "spanx, split");
|
|
this.add(configurationSelector, "growx, wrap 20lp");
|
|
|
|
|
|
|
|
//// X axis
|
|
|
|
//// X axis type:
|
|
this.add(new JLabel(trans.get("simplotpanel.lbl.Xaxistype")), "spanx, split");
|
|
domainTypeSelector = new JComboBox<FlightDataType>(types);
|
|
domainTypeSelector.setSelectedItem(configuration.getDomainAxisType());
|
|
domainTypeSelector.addItemListener(new ItemListener() {
|
|
@Override
|
|
public void itemStateChanged(ItemEvent e) {
|
|
if (modifying > 0)
|
|
return;
|
|
FlightDataType type = (FlightDataType) domainTypeSelector.getSelectedItem();
|
|
configuration.setDomainAxisType(type);
|
|
domainUnitSelector.setUnitGroup(type.getUnitGroup());
|
|
domainUnitSelector.setSelectedUnit(configuration.getDomainAxisUnit());
|
|
setToCustom();
|
|
}
|
|
});
|
|
this.add(domainTypeSelector, "gapright para");
|
|
|
|
//// Unit:
|
|
this.add(new JLabel(trans.get("simplotpanel.lbl.Unit")));
|
|
domainUnitSelector = new UnitSelector(configuration.getDomainAxisType().getUnitGroup());
|
|
domainUnitSelector.setSelectedUnit(configuration.getDomainAxisUnit());
|
|
domainUnitSelector.addItemListener(new ItemListener() {
|
|
@Override
|
|
public void itemStateChanged(ItemEvent e) {
|
|
if (modifying > 0)
|
|
return;
|
|
configuration.setDomainAxisUnit(domainUnitSelector.getSelectedUnit());
|
|
}
|
|
});
|
|
this.add(domainUnitSelector, "width 40lp, gapright para");
|
|
|
|
//// The data will be plotted in time order even if the X axis type is not time.
|
|
DescriptionArea desc = new DescriptionArea(trans.get("simplotpanel.Desc"), 2, -2f);
|
|
desc.setViewportBorder(BorderFactory.createEmptyBorder());
|
|
this.add(desc, "width 1px, growx 1, wrap unrel");
|
|
|
|
|
|
|
|
//// Y axis selector panel
|
|
//// Y axis types:
|
|
this.add(new JLabel(trans.get("simplotpanel.lbl.Yaxistypes")));
|
|
//// Flight events:
|
|
this.add(new JLabel(trans.get("simplotpanel.lbl.Flightevents")), "wrap rel");
|
|
|
|
typeSelectorPanel = new JPanel(new MigLayout("gapy rel"));
|
|
JScrollPane scroll = new JScrollPane(typeSelectorPanel);
|
|
this.add(scroll, "spany 3, height 10px, wmin 400lp, grow 100, gapright para");
|
|
|
|
|
|
//// Flight events
|
|
eventTableModel = new FlightEventTableModel();
|
|
JTable table = new JTable(eventTableModel);
|
|
table.setTableHeader(null);
|
|
table.setShowVerticalLines(false);
|
|
table.setRowSelectionAllowed(false);
|
|
table.setColumnSelectionAllowed(false);
|
|
|
|
TableColumnModel columnModel = table.getColumnModel();
|
|
TableColumn col0 = columnModel.getColumn(0);
|
|
int w = table.getRowHeight() + 2;
|
|
col0.setMinWidth(w);
|
|
col0.setPreferredWidth(w);
|
|
col0.setMaxWidth(w);
|
|
table.addMouseListener(new GUIUtil.BooleanTableClickListener(table));
|
|
this.add(new JScrollPane(table), "height 200px, width 200lp, grow 1, wrap rel");
|
|
|
|
|
|
//// All + None buttons
|
|
JButton button = new SelectColorButton(trans.get("simplotpanel.but.All"));
|
|
button.addActionListener(new ActionListener() {
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
for (FlightEvent.Type t : FlightEvent.Type.values())
|
|
configuration.setEvent(t, true);
|
|
eventTableModel.fireTableDataChanged();
|
|
}
|
|
});
|
|
this.add(button, "split 2, gapleft para, gapright para, growx, sizegroup buttons");
|
|
|
|
//// None
|
|
button = new SelectColorButton(trans.get("simplotpanel.but.None"));
|
|
button.addActionListener(new ActionListener() {
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
for (FlightEvent.Type t : FlightEvent.Type.values())
|
|
configuration.setEvent(t, false);
|
|
eventTableModel.fireTableDataChanged();
|
|
}
|
|
});
|
|
this.add(button, "gapleft para, gapright para, growx, sizegroup buttons, wrap");
|
|
|
|
|
|
//// Style event marker
|
|
JLabel styleEventMarker = new JLabel(trans.get("simplotpanel.MarkerStyle.lbl.MarkerStyle"));
|
|
JRadioButton radioVerticalMarker = new JRadioButton(trans.get("simplotpanel.MarkerStyle.btn.VerticalMarker"));
|
|
JRadioButton radioIcon = new JRadioButton(trans.get("simplotpanel.MarkerStyle.btn.Icon"));
|
|
ButtonGroup bg = new ButtonGroup();
|
|
bg.add(radioVerticalMarker);
|
|
bg.add(radioIcon);
|
|
|
|
boolean useIcon = preferences.getBoolean(Preferences.MARKER_STYLE_ICON, false);
|
|
if (useIcon) {
|
|
radioIcon.setSelected(true);
|
|
} else {
|
|
radioVerticalMarker.setSelected(true);
|
|
}
|
|
|
|
radioIcon.addItemListener(new ItemListener() {
|
|
@Override
|
|
public void itemStateChanged(ItemEvent e) {
|
|
if (modifying > 0)
|
|
return;
|
|
preferences.putBoolean(Preferences.MARKER_STYLE_ICON, radioIcon.isSelected());
|
|
}
|
|
});
|
|
|
|
domainTypeSelector.addItemListener(new ItemListener() {
|
|
@Override
|
|
public void itemStateChanged(ItemEvent e) {
|
|
updateStyleEventWidgets(styleEventMarker, radioVerticalMarker, radioIcon);
|
|
}
|
|
});
|
|
updateStyleEventWidgets(styleEventMarker, radioVerticalMarker, radioIcon);
|
|
|
|
this.add(styleEventMarker, "split 3, growx");
|
|
this.add(radioVerticalMarker);
|
|
this.add(radioIcon, "wrap para");
|
|
|
|
|
|
//// New Y axis plot type
|
|
button = new SelectColorButton(trans.get("simplotpanel.but.NewYaxisplottype"));
|
|
button.addActionListener(new ActionListener() {
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
if (configuration.getTypeCount() >= 15) {
|
|
JOptionPane.showMessageDialog(SimulationPlotPanel.this,
|
|
//// A maximum of 15 plots is allowed.
|
|
//// Cannot add plot
|
|
trans.get("simplotpanel.OptionPane.lbl1"),
|
|
trans.get("simplotpanel.OptionPane.lbl2"),
|
|
JOptionPane.ERROR_MESSAGE);
|
|
return;
|
|
}
|
|
|
|
// Select new type smartly
|
|
FlightDataType type = null;
|
|
for (FlightDataType t :
|
|
simulation.getSimulatedData().getBranch(0).getTypes()) {
|
|
|
|
boolean used = false;
|
|
if (configuration.getDomainAxisType().equals(t)) {
|
|
used = true;
|
|
} else {
|
|
for (int i = 0; i < configuration.getTypeCount(); i++) {
|
|
if (configuration.getType(i).equals(t)) {
|
|
used = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!used) {
|
|
type = t;
|
|
break;
|
|
}
|
|
}
|
|
if (type == null) {
|
|
type = simulation.getSimulatedData().getBranch(0).getTypes()[0];
|
|
}
|
|
|
|
// Add new type
|
|
configuration.addPlotDataType(type);
|
|
setToCustom();
|
|
updatePlots();
|
|
}
|
|
});
|
|
this.add(button, "spanx, split");
|
|
|
|
|
|
this.add(new JPanel(), "growx");
|
|
|
|
/*
|
|
//// Plot flight
|
|
button = new SelectColorButton(trans.get("simplotpanel.but.Plotflight"));
|
|
button.addActionListener(new ActionListener() {
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
if (configuration.getTypeCount() == 0) {
|
|
JOptionPane.showMessageDialog(SimulationPlotPanel.this,
|
|
trans.get("error.noPlotSelected"),
|
|
trans.get("error.noPlotSelected.title"),
|
|
JOptionPane.ERROR_MESSAGE);
|
|
return;
|
|
}
|
|
defaultConfiguration = configuration.clone();
|
|
SimulationPlotDialog.showPlot(SwingUtilities.getWindowAncestor(SimulationPlotPanel.this),
|
|
simulation, configuration);
|
|
}
|
|
});
|
|
this.add(button, "right");
|
|
*/
|
|
updatePlots();
|
|
}
|
|
|
|
private void updateStyleEventWidgets(JLabel styleEventMarker, JRadioButton radioVerticalMarker, JRadioButton radioIcon) {
|
|
if (modifying > 0)
|
|
return;
|
|
FlightDataType type = (FlightDataType) domainTypeSelector.getSelectedItem();
|
|
boolean isTime = type == FlightDataType.TYPE_TIME;
|
|
styleEventMarker.setEnabled(isTime);
|
|
radioVerticalMarker.setEnabled(isTime);
|
|
radioIcon.setEnabled(isTime);
|
|
styleEventMarker.setToolTipText(isTime ? trans.get("simplotpanel.MarkerStyle.lbl.MarkerStyle.ttip") : trans.get("simplotpanel.MarkerStyle.OnlyInTime"));
|
|
radioVerticalMarker.setToolTipText(isTime ? null : trans.get("simplotpanel.MarkerStyle.OnlyInTime"));
|
|
radioIcon.setToolTipText(isTime ? null : trans.get("simplotpanel.MarkerStyle.OnlyInTime"));
|
|
}
|
|
|
|
public JDialog doPlot(Window parent) {
|
|
if (configuration.getTypeCount() == 0) {
|
|
JOptionPane.showMessageDialog(SimulationPlotPanel.this,
|
|
trans.get("error.noPlotSelected"),
|
|
trans.get("error.noPlotSelected.title"),
|
|
JOptionPane.ERROR_MESSAGE);
|
|
return null;
|
|
}
|
|
defaultConfiguration = configuration.clone();
|
|
return SimulationPlotDialog.getPlot(parent, simulation, configuration);
|
|
}
|
|
|
|
private void setConfiguration(PlotConfiguration conf) {
|
|
|
|
boolean modified = false;
|
|
|
|
configuration = conf.clone();
|
|
if (!Utils.contains(types, configuration.getDomainAxisType())) {
|
|
configuration.setDomainAxisType(types[0]);
|
|
modified = true;
|
|
}
|
|
|
|
for (int i = 0; i < configuration.getTypeCount(); i++) {
|
|
if (!Utils.contains(types, configuration.getType(i))) {
|
|
configuration.removePlotDataType(i);
|
|
i--;
|
|
modified = true;
|
|
}
|
|
}
|
|
|
|
if (modified) {
|
|
configuration.setName(CUSTOM);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private void setToCustom() {
|
|
modifying++;
|
|
configuration.setName(CUSTOM);
|
|
configurationSelector.setSelectedItem(CUSTOM_CONFIGURATION);
|
|
modifying--;
|
|
}
|
|
|
|
|
|
private void updatePlots() {
|
|
domainTypeSelector.setSelectedItem(configuration.getDomainAxisType());
|
|
domainUnitSelector.setUnitGroup(configuration.getDomainAxisType().getUnitGroup());
|
|
domainUnitSelector.setSelectedUnit(configuration.getDomainAxisUnit());
|
|
|
|
typeSelectorPanel.removeAll();
|
|
for (int i = 0; i < configuration.getTypeCount(); i++) {
|
|
FlightDataType type = configuration.getType(i);
|
|
Unit unit = configuration.getUnit(i);
|
|
int axis = configuration.getAxis(i);
|
|
|
|
typeSelectorPanel.add(new PlotTypeSelector(i, type, unit, axis), "wrap");
|
|
}
|
|
|
|
// In order to consistantly update the ui, we need to validate before repaint.
|
|
typeSelectorPanel.validate();
|
|
typeSelectorPanel.repaint();
|
|
|
|
eventTableModel.fireTableDataChanged();
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
* A JPanel which configures a single plot of a PlotConfiguration.
|
|
*/
|
|
private class PlotTypeSelector extends JPanel {
|
|
private static final long serialVersionUID = 9056324972817542570L;
|
|
|
|
private final String[] POSITIONS = { AUTO_NAME, LEFT_NAME, RIGHT_NAME };
|
|
|
|
private final int index;
|
|
private JComboBox<FlightDataType> typeSelector;
|
|
private UnitSelector unitSelector;
|
|
private JComboBox<String> axisSelector;
|
|
|
|
|
|
public PlotTypeSelector(int plotIndex, FlightDataType type, Unit unit, int position) {
|
|
super(new MigLayout("ins 0"));
|
|
|
|
this.index = plotIndex;
|
|
|
|
typeSelector = new JComboBox<FlightDataType>(types);
|
|
typeSelector.setSelectedItem(type);
|
|
typeSelector.addItemListener(new ItemListener() {
|
|
@Override
|
|
public void itemStateChanged(ItemEvent e) {
|
|
if (modifying > 0)
|
|
return;
|
|
FlightDataType selectedType = (FlightDataType) typeSelector.getSelectedItem();
|
|
configuration.setPlotDataType(index, selectedType);
|
|
unitSelector.setUnitGroup(selectedType.getUnitGroup());
|
|
unitSelector.setSelectedUnit(configuration.getUnit(index));
|
|
setToCustom();
|
|
}
|
|
});
|
|
this.add(typeSelector, "gapright para");
|
|
|
|
//// Unit:
|
|
this.add(new JLabel(trans.get("simplotpanel.lbl.Unit")));
|
|
unitSelector = new UnitSelector(type.getUnitGroup());
|
|
if (unit != null)
|
|
unitSelector.setSelectedUnit(unit);
|
|
unitSelector.addItemListener(new ItemListener() {
|
|
@Override
|
|
public void itemStateChanged(ItemEvent e) {
|
|
if (modifying > 0)
|
|
return;
|
|
Unit selectedUnit = unitSelector.getSelectedUnit();
|
|
configuration.setPlotDataUnit(index, selectedUnit);
|
|
}
|
|
});
|
|
this.add(unitSelector, "width 40lp, gapright para");
|
|
|
|
//// Axis:
|
|
this.add(new JLabel(trans.get("simplotpanel.lbl.Axis")));
|
|
axisSelector = new JComboBox<String>(POSITIONS);
|
|
if (position == LEFT)
|
|
axisSelector.setSelectedIndex(1);
|
|
else if (position == RIGHT)
|
|
axisSelector.setSelectedIndex(2);
|
|
else
|
|
axisSelector.setSelectedIndex(0);
|
|
axisSelector.addItemListener(new ItemListener() {
|
|
@Override
|
|
public void itemStateChanged(ItemEvent e) {
|
|
if (modifying > 0)
|
|
return;
|
|
int axis = axisSelector.getSelectedIndex() - 1;
|
|
configuration.setPlotDataAxis(index, axis);
|
|
}
|
|
});
|
|
this.add(axisSelector);
|
|
|
|
|
|
JButton button = new SelectColorButton(Icons.EDIT_DELETE);
|
|
//// Remove this plot
|
|
button.setToolTipText(trans.get("simplotpanel.but.ttip.Deletethisplot"));
|
|
button.setBorderPainted(false);
|
|
button.addActionListener(new ActionListener() {
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
configuration.removePlotDataType(index);
|
|
setToCustom();
|
|
updatePlots();
|
|
}
|
|
});
|
|
this.add(button, "gapright 0");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private class FlightEventTableModel extends AbstractTableModel {
|
|
private static final long serialVersionUID = -1108240805614567627L;
|
|
private final FlightEvent.Type[] eventTypes;
|
|
|
|
public FlightEventTableModel() {
|
|
EnumSet<FlightEvent.Type> set = EnumSet.noneOf(FlightEvent.Type.class);
|
|
for (int i = 0; i < simulation.getSimulatedData().getBranchCount(); i++) {
|
|
for (FlightEvent e : simulation.getSimulatedData().getBranch(i).getEvents()) {
|
|
set.add(e.getType());
|
|
}
|
|
}
|
|
set.remove(FlightEvent.Type.ALTITUDE);
|
|
int count = set.size();
|
|
|
|
eventTypes = new FlightEvent.Type[count];
|
|
int pos = 0;
|
|
for (FlightEvent.Type t : FlightEvent.Type.values()) {
|
|
if (set.contains(t)) {
|
|
eventTypes[pos] = t;
|
|
pos++;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getColumnCount() {
|
|
return 2;
|
|
}
|
|
|
|
@Override
|
|
public int getRowCount() {
|
|
return eventTypes.length;
|
|
}
|
|
|
|
@Override
|
|
public Class<?> getColumnClass(int column) {
|
|
switch (column) {
|
|
case 0:
|
|
return Boolean.class;
|
|
|
|
case 1:
|
|
return String.class;
|
|
|
|
default:
|
|
throw new IndexOutOfBoundsException("column=" + column);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Object getValueAt(int row, int column) {
|
|
switch (column) {
|
|
case 0:
|
|
return Boolean.valueOf(configuration.isEventActive(eventTypes[row]));
|
|
|
|
case 1:
|
|
return eventTypes[row].toString();
|
|
|
|
default:
|
|
throw new IndexOutOfBoundsException("column=" + column);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isCellEditable(int row, int column) {
|
|
return column == 0;
|
|
}
|
|
|
|
@Override
|
|
public void setValueAt(Object value, int row, int column) {
|
|
if (column != 0 || !(value instanceof Boolean)) {
|
|
throw new IllegalArgumentException("column=" + column + ", value=" + value);
|
|
}
|
|
|
|
configuration.setEvent(eventTypes[row], (Boolean) value);
|
|
this.fireTableCellUpdated(row, column);
|
|
}
|
|
}
|
|
}
|