
org.bidib.wizard.mvc.main.model.MacroTableModel Maven / Gradle / Ivy
package org.bidib.wizard.mvc.main.model;
import java.util.Objects;
import javax.swing.table.DefaultTableModel;
import org.bidib.wizard.comm.AccessoryOkayStatus;
import org.bidib.wizard.comm.BidibStatus;
import org.bidib.wizard.comm.MacroStatus;
import org.bidib.wizard.locale.Resources;
import org.bidib.wizard.mvc.main.model.function.AccessoryOkayFunction;
import org.bidib.wizard.mvc.main.model.function.BacklightPortAction;
import org.bidib.wizard.mvc.main.model.function.Delayable;
import org.bidib.wizard.mvc.main.model.function.FlagFunction;
import org.bidib.wizard.mvc.main.model.function.Function;
import org.bidib.wizard.mvc.main.model.function.InputFunction;
import org.bidib.wizard.mvc.main.model.function.MacroFunction;
import org.bidib.wizard.mvc.main.model.function.PortAware;
import org.bidib.wizard.mvc.main.model.function.RandomDelayFunction;
import org.bidib.wizard.mvc.main.model.function.ServoMoveQueryFunction;
import org.bidib.wizard.mvc.main.model.function.ServoPortAction;
import org.bidib.wizard.mvc.main.model.listener.MacroListener;
import org.bidib.wizard.mvc.main.view.table.Reorderable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MacroTableModel extends DefaultTableModel implements MacroListener, Reorderable {
private static final Logger LOGGER = LoggerFactory.getLogger(MacroTableModel.class);
private static final long serialVersionUID = 1L;
public static final int COLUMN_STEP = 0;
public static final int COLUMN_DELAY = 1;
public static final int COLUMN_PORT_TYPE = 2;
public static final int COLUMN_ACTION = 3;
public static final int COLUMN_PORT_NUMBER = 4;
public static final int COLUMN_EXTRA = 5;
private String[] columnNames;
private Macro macro;
private final MainModel model;
public MacroTableModel(MainModel model) {
this.model = model;
initialize();
setColumnIdentifiers(columnNames);
}
protected void initialize() {
columnNames =
new String[] { Resources.getString(getClass(), "step"), Resources.getString(getClass(), "delay"),
Resources.getString(getClass(), "portType"), Resources.getString(getClass(), "action"),
Resources.getString(getClass(), "portNumber"), Resources.getString(getClass(), "extra") };
}
private void addRow(Function extends BidibStatus> function, int functionIndex) {
Object[] rowData = new Object[columnNames.length];
for (int column = 0; column < columnNames.length; column++) {
rowData[column] = getRowData(column, function, functionIndex);
}
addRow(rowData);
}
@Override
public Class> getColumnClass(int column) {
switch (column) {
case COLUMN_DELAY:
return Integer.class;
case COLUMN_PORT_TYPE:
return Object.class;
case COLUMN_ACTION:
return Object.class;
case COLUMN_PORT_NUMBER:
return Object.class;
case COLUMN_EXTRA:
return Integer.class;
default:
return String.class;
}
}
private Object getRowData(int column, Function extends BidibStatus> function, int functionIndex) {
Object result = null;
switch (column) {
case COLUMN_STEP:
result = (functionIndex + 1) + ". " + Resources.getString(getClass(), "step");
break;
case COLUMN_DELAY:
if (function != null) {
if (function instanceof Delayable) {
result = ((Delayable) function).getDelay();
}
else if (function instanceof RandomDelayFunction) {
result = ((RandomDelayFunction) function).getMaximumValue();
}
}
break;
case COLUMN_PORT_TYPE:
result = function;
break;
case COLUMN_ACTION:
if (function != null) {
result = function.getAction();
}
break;
case COLUMN_PORT_NUMBER:
if (function != null) {
LOGGER.info("Current function: {}", function);
if (function instanceof AccessoryOkayFunction) {
result = ((AccessoryOkayFunction) function).getInput();
}
else if (function instanceof InputFunction) {
result = ((InputFunction) function).getInput();
}
else if (function instanceof MacroFunction) {
result = model.getMacros().get(((MacroFunction) function).getMacroId());
}
else if (function instanceof FlagFunction) {
result = ((FlagFunction) function).getFlag();
}
else if (function instanceof PortAware) {
result = ((PortAware>) function).getPort();
}
}
break;
case COLUMN_EXTRA:
if (function != null) {
if (function instanceof ServoPortAction) {
result = ((ServoPortAction) function).getValue();
}
else if (function instanceof BacklightPortAction) {
result = ((BacklightPortAction) function).getValue();
}
}
break;
}
return result;
}
@Override
public Object getValueAt(int row, int column) {
Object result = super.getValueAt(row, column);
if (result != null && column == COLUMN_EXTRA) {
Function extends BidibStatus> function = macro.getFunction(row);
if (function instanceof ServoPortAction) {
ServoPort port = ((ServoPortAction) function).getPort();
if (port != null) {
result = port.getRelativeValue(Integer.parseInt(result.toString()));
}
}
else if (function instanceof BacklightPortAction) {
BacklightPort port = ((BacklightPortAction) function).getPort();
if (port != null) {
result = port.getRelativeValue(Integer.parseInt(result.toString()));
}
}
}
return result;
}
private void insertRow(int row, Function extends BidibStatus> function, int functionIndex) {
Object[] rowData = new Object[columnNames.length];
for (int column = 0; column < columnNames.length; column++) {
rowData[column] = getRowData(column, function, functionIndex);
}
insertRow(row, rowData);
}
@Override
public boolean isCellEditable(int row, int column) {
boolean editable = true;
switch (column) {
case COLUMN_EXTRA:
Function> function = macro.getFunction(row);
if (function instanceof ServoPortAction) {
ServoPort port = ((ServoPortAction) function).getPort();
if (port == null) {
editable = false;
}
}
break;
default:
break;
}
return editable;
}
private void renumberSteps() {
for (int row = 0; row < getRowCount(); row++) {
Object rowData = getRowData(0, (Function>) getValueAt(row, 2), row);
rowData = (row + 1) + ". " + Resources.getString(getClass(), "step");
setValueAt(rowData, row, 0);
}
}
public void setMacro(Macro macro) {
LOGGER.debug("Set the macro: {}", macro);
setRowCount(0);
if (this.macro != null) {
this.macro.removeMacroListener(this);
}
// set the macro
this.macro = macro;
if (macro != null) {
for (int index = 0; index < macro.getFunctionCount(); index++) {
addRow(macro.getFunction(index), index);
}
macro.addMacroListener(this);
}
}
@Override
public void setValueAt(Object value, int row, int column) {
boolean valueChanged = false;
switch (column) {
case COLUMN_DELAY:
Function function = macro.getFunction(row);
if (function instanceof Delayable) {
int delayValue = Integer.parseInt(value.toString());
if (delayValue != ((Delayable) function).getDelay()) {
((Delayable) function).setDelay(delayValue);
valueChanged = true;
}
super.setValueAt(value, row, column);
}
else if (function instanceof RandomDelayFunction) {
int maxValue = Integer.parseInt(value.toString());
if (maxValue != ((RandomDelayFunction) function).getMaximumValue()) {
((RandomDelayFunction) function).setMaximumValue(maxValue);
valueChanged = true;
}
super.setValueAt(value, row, column);
}
break;
case COLUMN_PORT_TYPE:
if (value != null
&& (macro.getFunction(row) == null || value.getClass() != macro.getFunction(row).getClass())) {
try {
function = (Function>) ((Function>) value).clone();
macro.replaceFunction(row, function);
for (int col = columnNames.length - 1; col > 0; col--) {
super.setValueAt(getRowData(col, function, row), row, col);
}
valueChanged = true;
}
catch (Exception e) {
LOGGER.warn("Set new functions for selected port type failed.");
throw new RuntimeException(e);
}
}
else {
LOGGER.info("Port type has not been changed.");
}
break;
case COLUMN_ACTION:
function = macro.getFunction(row);
if (!Objects.equals((BidibStatus) value, function.getAction())) {
// the action has been changed
LOGGER.info("the action has been changed.");
function.setAction((BidibStatus) value);
if (function instanceof AccessoryOkayFunction) {
if (AccessoryOkayStatus.NO_FEEDBACK.equals(((AccessoryOkayFunction) function).getAction())) {
// no input selected if 'no feedback'
((AccessoryOkayFunction) function).setInput((InputPort) null);
super.setValueAt(null, row, column + 1);
}
else {
// show the combobox if not already displayed
Object currentValue = getValueAt(row, column + 1);
((AccessoryOkayFunction) function).setInput((InputPort) currentValue);
super.setValueAt(currentValue, row, column + 1);
}
}
else if (function instanceof ServoMoveQueryFunction) {
// show the combobox if not already displayed
Object currentValue = getValueAt(row, column + 1);
((ServoMoveQueryFunction) function).setPort((ServoPort) currentValue);
super.setValueAt(currentValue, row, column + 1);
}
else if (function instanceof MacroFunction) {
if (MacroStatus.END.equals(((MacroFunction) function).getAction())) {
// no macro selected if END
((MacroFunction) function).setMacroId(0);
super.setValueAt(null, row, column + 1);
}
else {
// show the combobox if not already displayed
Object currentValue = getValueAt(row, column + 1);
if (currentValue instanceof Macro) {
((MacroFunction) function).setMacroId(((Macro) currentValue).getId());
}
else {
((MacroFunction) function).setMacroId(0);
}
super.setValueAt(currentValue, row, column + 1);
}
}
super.setValueAt(value, row, column);
valueChanged = true;
}
break;
case COLUMN_PORT_NUMBER:
function = macro.getFunction(row);
if (function instanceof AccessoryOkayFunction) {
if (!Objects.equals(((AccessoryOkayFunction) function).getInput(), (InputPort) value)) {
((AccessoryOkayFunction) function).setInput((InputPort) value);
super.setValueAt(value, row, column);
valueChanged = true;
}
}
else if (function instanceof InputFunction) {
if (!Objects.equals(((InputFunction) function).getInput(), (InputPort) value)) {
((InputFunction) function).setInput((InputPort) value);
super.setValueAt(value, row, column);
valueChanged = true;
}
}
else if (function instanceof MacroFunction) {
if (!Objects.equals(((MacroFunction) function).getMacroId(), model.getMacros().indexOf(value))) {
((MacroFunction) function).setMacroId(model.getMacros().indexOf(value));
super.setValueAt(value, row, column);
valueChanged = true;
}
}
else if (function instanceof FlagFunction) {
if (!Objects.equals(((FlagFunction) function).getFlag(), (Flag) value)) {
((FlagFunction) function).setFlag((Flag) value);
super.setValueAt(value, row, column);
valueChanged = true;
}
}
else if (function instanceof PortAware) {
if (!Objects.equals(((PortAware>) function).getPort(), (Port>) value)) {
((PortAware>) function).setPort((Port>) value);
super.setValueAt(value, row, column);
valueChanged = true;
}
}
break;
case COLUMN_EXTRA:
function = macro.getFunction(row);
if (function instanceof ServoPortAction) {
ServoPort port = ((ServoPortAction) function).getPort();
if (port != null) {
int intValue = port.getAbsoluteValue(Integer.parseInt(value.toString()));
int oldValue = ((ServoPortAction) function).getValue();
if (oldValue != intValue) {
((ServoPortAction) function).setValue(intValue);
super.setValueAt(intValue, row, column);
valueChanged = true;
}
}
}
else if (function instanceof BacklightPortAction) {
BacklightPort port = ((BacklightPortAction) function).getPort();
if (port != null) {
int intValue = port.getAbsoluteValue(Integer.parseInt(value.toString()));
int oldValue = ((BacklightPortAction) function).getValue();
if (oldValue != intValue) {
((BacklightPortAction) function).setValue(intValue);
super.setValueAt(intValue, row, column);
valueChanged = true;
}
}
}
break;
default:
super.setValueAt(value, row, column);
}
if (valueChanged) {
LOGGER.info("The current value was changed, set the pending changes state.");
macro.setMacroSaveState(MacroSaveState.PENDING_CHANGES);
}
}
@Override
public void functionsAdded(int row, Function extends BidibStatus>[] functions) {
LOGGER.info("functions were added, row: {}", row);
if (functions != null) {
for (int index = 0; index < functions.length; index++) {
insertRow(row + index, functions[index], row);
}
}
else {
insertRow(row, (Function extends BidibStatus>) null, row);
}
renumberSteps();
}
@Override
public void functionRemoved(int row) {
removeRow(row);
renumberSteps();
}
@Override
public void functionsRemoved() {
setRowCount(0);
}
@Override
public void labelChanged(String label) {
}
@Override
public void reorder(int fromIndex, int toIndex, int rowCount) {
LOGGER.info("reorder, fromIndex: {}, toIndex: {}, rowCount: {}", fromIndex, toIndex, rowCount);
if (fromIndex < toIndex) {
for (int row = 0; row < rowCount; row++) {
LOGGER.info("I. Move row: {}, fromIndex: {}, toIndex: {}", row, fromIndex, toIndex);
macro.moveFunction(fromIndex, toIndex);
}
}
else { // fromIndex > toIndex
for (int row = 0; row < rowCount; row++) {
LOGGER.info("II. Move row: {}, fromIndex: {}, toIndex: {}", row, fromIndex, toIndex);
macro.moveFunction(fromIndex + (rowCount - 1), toIndex);
}
}
renumberSteps();
}
private void moveRow(int srcRow, int targetRow, Function extends BidibStatus> function) {
Object[] rowData = new Object[columnNames.length];
int functionIndex = 0;
for (int column = 0; column < columnNames.length; column++) {
rowData[column] = getRowData(column, function, functionIndex);
}
LOGGER.info("Remove srcRow: {}, targetRow: {}, rowData: {}", srcRow, targetRow, rowData);
removeRow(srcRow);
if (targetRow > srcRow) {
insertRow(targetRow, rowData);
}
else {
insertRow(targetRow, rowData);
}
}
@Override
public void functionMoved(int fromIndex, int toIndex, Function extends BidibStatus> fromFunction) {
LOGGER.info("functionMoved, fromIndex: {}, toIndex: {}, fromFunction: {}", fromIndex, toIndex,
fromFunction.getDebugString());
moveRow(fromIndex, toIndex, fromFunction);
}
@Override
public void startConditionChanged() {
}
@Override
public void slowdownFactorChanged() {
}
@Override
public void cyclesChanged() {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy