1 package org.opentrafficsim.editor;
2
3 import java.util.Arrays;
4 import java.util.Optional;
5
6 import javax.swing.JTable;
7 import javax.swing.table.AbstractTableModel;
8
9 import org.djutils.exceptions.Throw;
10 import org.opentrafficsim.editor.DocumentReader.NodeAnnotation;
11 import org.opentrafficsim.swing.gui.OtsAnimationPanel;
12 import org.w3c.dom.Node;
13
14 import de.javagl.treetable.JTreeTable;
15
16
17
18
19
20
21
22
23
24 public class AttributesTableModel extends AbstractTableModel
25 {
26
27
28 private static final long serialVersionUID = 20230217L;
29
30
31 private static final String[] COLUMN_NAMES = new String[] {"Property", "Value", "Use", ""};
32
33
34 public static final int PROPERTY_COLUMN = Arrays.asList(COLUMN_NAMES).indexOf("Property");
35
36
37 public static final int VALUE_COLUMN = Arrays.asList(COLUMN_NAMES).indexOf("Value");
38
39
40 public static final int USE_COLUMN = Arrays.asList(COLUMN_NAMES).indexOf("Use");
41
42
43 public static final int DESCRIPTION_COLUMN = Arrays.asList(COLUMN_NAMES).indexOf("");
44
45
46 private static final int[] MIN_COLUMN_WIDTHS = new int[] {50, 50, 30, 20};
47
48
49 private static final int[] PREFERRED_COLUMN_WIDTHS = new int[] {400, 400, 30, 20};
50
51
52 private final XsdTreeNode node;
53
54
55 private final JTreeTable treeTable;
56
57
58
59
60
61
62 public AttributesTableModel(final XsdTreeNode node, final JTreeTable treeTable)
63 {
64 this.node = node;
65 this.treeTable = treeTable;
66 }
67
68 @Override
69 public int getRowCount()
70 {
71 return this.node == null ? 0 : this.node.attributeCount();
72 }
73
74 @Override
75 public int getColumnCount()
76 {
77 return COLUMN_NAMES.length;
78 }
79
80 @Override
81 public String getColumnName(final int columnIndex)
82 {
83 return COLUMN_NAMES[columnIndex];
84 }
85
86 @Override
87 public Class<?> getColumnClass(final int columnIndex)
88 {
89 return String.class;
90 }
91
92 @Override
93 public boolean isCellEditable(final int rowIndex, final int columnIndex)
94 {
95 if (this.node.getPathString().startsWith(XsdPaths.DEFINITIONS)
96 && "Default".equals(this.node.getAttributeNameByIndex(rowIndex))
97 && "xsd:boolean".equals(this.node.getAttributeBaseType(rowIndex)))
98 {
99
100 return false;
101 }
102 return columnIndex == VALUE_COLUMN && !this.node.isIncluded();
103 }
104
105 @Override
106 public Object getValueAt(final int rowIndex, final int columnIndex)
107 {
108 Node attribute = this.node.getAttributeNode(rowIndex);
109 if (columnIndex == PROPERTY_COLUMN)
110 {
111 return OtsAnimationPanel.separatedName(DocumentReader.getAttribute(attribute, "name").orElse(null));
112 }
113 else if (columnIndex == VALUE_COLUMN)
114 {
115 Object value = this.node.getAttributeValue(rowIndex);
116 return value;
117 }
118 else if (columnIndex == USE_COLUMN)
119 {
120 Optional<String> use = DocumentReader.getAttribute(attribute, "use");
121 return use.isPresent() && use.get().equals("required") ? "*" : "";
122 }
123 else if (columnIndex == DESCRIPTION_COLUMN)
124 {
125 return NodeAnnotation.DESCRIPTION.get(attribute).isPresent() ? "i" : null;
126 }
127 throw new IndexOutOfBoundsException();
128 }
129
130 @Override
131 public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex)
132 {
133 Throw.when(columnIndex != VALUE_COLUMN, IllegalArgumentException.class,
134 "Attribute table model requested to set a value from a column that does not represent the attribute value.");
135 if (aValue == null)
136 {
137 return;
138 }
139 if (this.node == null)
140 {
141
142 return;
143 }
144 this.node.setAttributeValue(rowIndex, aValue.toString());
145 this.treeTable.updateUI();
146 fireTableCellUpdated(rowIndex, columnIndex);
147 }
148
149
150
151
152
153 public XsdTreeNode getNode()
154 {
155 return this.node;
156 }
157
158
159
160
161
162 public static void applyColumnWidth(final JTable attributeTable)
163 {
164 Throw.when(attributeTable.getColumnCount() != COLUMN_NAMES.length, IllegalArgumentException.class,
165 "The number of columns in the table to show node attributes is not equal to the number of defined columns.");
166 for (int i = 0; i < attributeTable.getColumnCount(); i++)
167 {
168 attributeTable.getColumn(COLUMN_NAMES[i]).setMinWidth(MIN_COLUMN_WIDTHS[i]);
169 attributeTable.getColumn(COLUMN_NAMES[i]).setPreferredWidth(PREFERRED_COLUMN_WIDTHS[i]);
170 }
171 }
172
173 }