ArduinoTableAttr.java
/*******************************************************************************
* jArduino: Arduino C++ Code Generation From Java
* Copyright 2020 Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package net.sourceforge.jarduino.gui;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import net.sourceforge.jarduino.gui.ArduinoPanelMeta.ArduinoConfigMode;
import net.sourceforge.jarduino.message.ArduinoAttribute;
import net.sourceforge.jarduino.message.ArduinoAttribute.ArduinoAttrClass;
import net.sourceforge.jarduino.message.ArduinoAttribute.ArduinoAttrObject;
import net.sourceforge.jarduino.message.ArduinoMessage;
import net.sourceforge.jarduino.message.ArduinoNode;
import net.sourceforge.jarduino.message.ArduinoSignal;
import net.sourceforge.jarduino.message.ArduinoSystem;
/**
* Table for Attributes.
*/
public class ArduinoTableAttr {
/**
* The attributes.
*/
private final List<ArduinoAttribute> theAttributes;
/**
* The receivers.
*/
private final Map<Integer, ArduinoNode> theReceivers;
/**
* The values.
*/
private final List<Object> theValues;
/**
* The Attributes table.
*/
private final JTable theTable;
/**
* The Attributes table model.
*/
private final ArduinoAttrModel theModel;
/**
* The Parents column.
*/
private final TableColumn theParentCol;
/**
* Is the parent column visible?
*/
private boolean parentsVisible;
/**
* The system.
*/
private ArduinoSystem theSystem;
/**
* The mode.
*/
private ArduinoConfigMode theMode;
/**
* The selected Object.
*/
private ArduinoAttrObject theSelected;
/**
* Constructor.
*/
ArduinoTableAttr() {
/* Create lists and maps */
theAttributes = new ArrayList<>();
theValues = new ArrayList<>();
theReceivers = new HashMap<>();
/* Create the table */
theTable = new JTable();
theTable.setAutoCreateRowSorter(true);
/* Create the table model */
theModel = new ArduinoAttrModel();
theTable.setModel(theModel);
/* Access the parent column */
final TableColumnModel myColModel = theTable.getColumnModel();
theParentCol = myColModel.getColumn(ArduinoAttrModel.COL_RECEIVER);
parentsVisible = true;
}
/**
* Obtain the component.
* @return the component
*/
JComponent getComponent() {
return theTable;
}
/**
* Configure the table.
*
* @param pSystem the system
* @param pMode the mode
* @param pSelected the selected object
*/
void configureTable(final ArduinoSystem pSystem,
final ArduinoConfigMode pMode,
final ArduinoAttrObject pSelected) {
/* store the details */
theSystem = pSystem;
theMode = pMode;
theSelected = pSelected;
/* Refresh the table model */
theModel.refresh();
/* Determine whether parents column should be visible */
final boolean bParentsVisible = !theReceivers.isEmpty();
/* If we should modify the columns */
if (bParentsVisible != parentsVisible) {
/* Access the table column model */
final TableColumnModel myColModel = theTable.getColumnModel();
/* If we need to remove the column */
if (parentsVisible) {
myColModel.removeColumn(theParentCol);
/* else restore the column and move to correct position */
} else {
myColModel.addColumn(theParentCol);
myColModel.moveColumn(ArduinoAttrModel.COL_VALUE, ArduinoAttrModel.COL_RECEIVER);
}
/* Flip the flag */
parentsVisible = !parentsVisible;
}
}
/**
* Table Model.
*/
private class ArduinoAttrModel
extends AbstractTableModel {
/**
* Serial Id.
*/
private static final long serialVersionUID = -7093822082474013905L;
/**
* The attribute column.
*/
private static final int COL_ATTR = 0;
/**
* The receiver column.
*/
private static final int COL_RECEIVER = COL_ATTR + 1;
/**
* The value column.
*/
private static final int COL_VALUE = COL_RECEIVER + 1;
/**
* Constructor.
*/
ArduinoAttrModel() {
}
/**
* Refresh the model.
*/
void refresh() {
/* Clear the lists/maps */
theAttributes.clear();
theValues.clear();
theReceivers.clear();
/* Loop through the attributes */
for (ArduinoAttribute myAttr : theSystem.getAttributes()) {
/* If the attribute is relevant */
if (isRelevant(myAttr)) {
/* If this is a relation attribute */
if (myAttr.getAttrClass().isRelation()) {
/* Load values associated with it */
loadRelationAttribute(myAttr);
} else {
/* Load values associated with it */
loadAttribute(myAttr);
}
}
}
/* Refresh the table */
fireTableDataChanged();
}
/**
* loadAttribute.
* @param pAttr the attribute to load
*/
private void loadAttribute(final ArduinoAttribute pAttr) {
/* Add the item and its value to the list */
theAttributes.add(pAttr);
theValues.add(theSelected.getAttrValue(pAttr));
}
/**
* loadAttribute.
* @param pAttr the attribute to load
*/
private void loadRelationAttribute(final ArduinoAttribute pAttr) {
/* The index */
int myIndex = theAttributes.size();
/* Loop through the nodes */
for (ArduinoNode myNode : theSystem.getNodes()) {
/* If the node receives the signal/message */
if (nodeReceivesObject(myNode)) {
/* Access the value and store into map */
theAttributes.add(pAttr);
theReceivers.put(myIndex++, myNode);
theValues.add(myNode.getRelationValue(pAttr, theSelected));
}
}
}
/**
* is the attribute relevant in this mode?
* @param pAttr the attribute to load
* @return true/false
*/
private boolean isRelevant(final ArduinoAttribute pAttr) {
final ArduinoAttrClass myClass = pAttr.getAttrClass();
switch (theMode) {
case SYSTEM:
return myClass == ArduinoAttrClass.SYSTEM;
case NODE:
return myClass == ArduinoAttrClass.NODE;
case MESSAGE:
return myClass == ArduinoAttrClass.MESSAGE
|| myClass == ArduinoAttrClass.NODE2MSG;
case SIGNAL:
return myClass == ArduinoAttrClass.SIGNAL
|| myClass == ArduinoAttrClass.NODE2SIGNAL;
default:
return false;
}
}
/**
* is the node a receiver of the selected object.
* @param pNode the node
* @return true/false
*/
private boolean nodeReceivesObject(final ArduinoNode pNode) {
/* If the object is a message */
if (theSelected instanceof ArduinoMessage) {
return pNode.receivesMessage((ArduinoMessage) theSelected);
} else if (theSelected instanceof ArduinoSignal) {
return pNode.receivesSignal((ArduinoSignal) theSelected);
}
return false;
}
@Override
public int getRowCount() {
return theAttributes.size();
}
@Override
public String getColumnName(final int pColIndex) {
switch (pColIndex) {
case COL_ATTR:
return "Attribute";
case COL_RECEIVER:
return "Receiver";
case COL_VALUE:
return "Value";
default:
return null;
}
}
@Override
public int getColumnCount() {
return COL_VALUE + 1;
}
@Override
public boolean isCellEditable(final int pRowIndex,
final int pColIndex) {
return false;
}
@Override
public Object getValueAt(final int pRowIndex,
final int pColIndex) {
switch (pColIndex) {
case COL_ATTR:
return theAttributes.get(pRowIndex).getName();
case COL_RECEIVER:
return theReceivers.get(pRowIndex);
case COL_VALUE:
return theValues.get(pRowIndex);
default:
return null;
}
}
}
}