View Javadoc
1   /*******************************************************************************
2    * jArduino: Arduino C++ Code Generation From Java
3    * Copyright 2020 Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   ******************************************************************************/
17  package net.sourceforge.jarduino.gui;
18  
19  import net.sourceforge.jarduino.message.ArduinoMessage;
20  import net.sourceforge.jarduino.message.ArduinoNode;
21  import net.sourceforge.jarduino.message.ArduinoSignal;
22  
23  import javax.swing.JComponent;
24  import javax.swing.JScrollPane;
25  import javax.swing.JSplitPane;
26  import javax.swing.JTable;
27  import javax.swing.ListSelectionModel;
28  import javax.swing.table.AbstractTableModel;
29  import java.util.ArrayList;
30  import java.util.List;
31  
32  /**
33   * Arduino Node Connection Table.
34   */
35  public class ArduinoTableNodeConnect {
36      /**
37       * Half Weight.
38       */
39      static final double HALF_WEIGHT = 0.5;
40  
41      /**
42       * Third Weight.
43       */
44      static final double THIRD_WEIGHT = 0.33;
45  
46      /**
47       * The splitPane.
48       */
49      private final JSplitPane thePane;
50  
51      /**
52       * The sent model.
53       */
54      private final ArduinoSentModel theSentModel;
55  
56      /**
57       * The received table.
58       */
59      private final JTable theReceivedTable;
60  
61      /**
62       * The received model.
63       */
64      private final ArduinoReceivedModel theReceivedModel;
65  
66      /**
67       * The signals model.
68       */
69      private final ArduinoSignalsModel theSignalsModel;
70  
71      /**
72       * The selected node.
73       */
74      private ArduinoNode theSelected;
75  
76      /**
77       * Constructor.
78       */
79      ArduinoTableNodeConnect() {
80          /* Create the tables */
81          final JTable mySentTable = new JTable();
82          mySentTable.setAutoCreateRowSorter(true);
83          theReceivedTable = new JTable();
84          theReceivedTable.setAutoCreateRowSorter(true);
85          theReceivedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
86          final JTable mySignalsTable = new JTable();
87          mySignalsTable.setAutoCreateRowSorter(true);
88  
89          /* Create the table models */
90          theSentModel = new ArduinoSentModel();
91          mySentTable.setModel(theSentModel);
92          theReceivedModel = new ArduinoReceivedModel();
93          theReceivedTable.setModel(theReceivedModel);
94          theSignalsModel = new ArduinoSignalsModel();
95          mySignalsTable.setModel(theSignalsModel);
96  
97          /* Create a splitPane */
98          final JSplitPane myPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
99          myPane.setLeftComponent(new JScrollPane(theReceivedTable));
100         myPane.setRightComponent(new JScrollPane(mySignalsTable));
101         myPane.setResizeWeight(HALF_WEIGHT);
102 
103         /* Update nodes on selection of signal */
104         final ListSelectionModel mySelect = theReceivedTable.getSelectionModel();
105         mySelect.addListSelectionListener(e -> {
106             if (!e.getValueIsAdjusting()) {
107                 int myIndex = mySelect.getMinSelectionIndex();
108                 if (myIndex != -1) {
109                     myIndex = theReceivedTable.convertRowIndexToModel(myIndex);
110                     theSignalsModel.refresh(theSelected, theReceivedModel.getItem(myIndex));
111                 }
112             }
113         });
114 
115         /* Create a splitPane */
116         thePane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
117         thePane.setLeftComponent(new JScrollPane(mySentTable));
118         thePane.setRightComponent(myPane);
119         thePane.setResizeWeight(THIRD_WEIGHT);
120     }
121 
122     /**
123      * Obtain the component.
124      * @return the component
125      */
126     JComponent getComponent() {
127         return thePane;
128     }
129 
130     /**
131      * Configure the table.
132      *
133      * @param pNode the node
134      */
135     void configureTable(final ArduinoNode pNode) {
136         /* refresh the tables */
137         theSelected = pNode;
138         theReceivedModel.refresh(pNode);
139         theSentModel.refresh(pNode);
140     }
141 
142     /**
143      * Sent Messages Table Model.
144      */
145     private static class ArduinoSentModel
146             extends AbstractTableModel {
147         /**
148          * Serial Id.
149          */
150         private static final long serialVersionUID = -3464529356295378185L;
151 
152         /**
153          * The message column.
154          */
155         private static final int COL_MSG = 0;
156 
157         /**
158          * The active Messages list.
159          */
160         private final List<ArduinoMessage> theMessages;
161 
162         /**
163          * Constructor.
164          */
165         ArduinoSentModel() {
166             theMessages = new ArrayList<>();
167         }
168 
169         /**
170          * Refresh.
171          * @param pNode the node
172          */
173         void refresh(final ArduinoNode pNode) {
174             /* Clear the messages */
175             theMessages.clear();
176 
177             /* If we have a node */
178             if (pNode != null) {
179                 /* Loop through the messages */
180                 for (ArduinoMessage myMsg : pNode.getOwner().getMessages()) {
181                     if (pNode.sendsMessage(myMsg)) {
182                         theMessages.add(myMsg);
183                     }
184                 }
185             }
186 
187             /* Refresh the table */
188             fireTableDataChanged();
189         }
190 
191         @Override
192         public int getRowCount() {
193             return theMessages.size();
194         }
195 
196         @Override
197         public String getColumnName(final int pColIndex) {
198             return pColIndex == COL_MSG ? "Sent Messages" :  null;
199         }
200 
201         @Override
202         public int getColumnCount() {
203             return COL_MSG + 1;
204         }
205 
206         @Override
207         public boolean isCellEditable(final int pRowIndex,
208                                       final int pColIndex) {
209             return false;
210         }
211 
212         @Override
213         public Object getValueAt(final int pRowIndex,
214                                  final int pColIndex) {
215             return pColIndex == COL_MSG ? theMessages.get(pRowIndex).getName() : null;
216         }
217     }
218 
219     /**
220      * Received Messages Table Model.
221      */
222     private class ArduinoReceivedModel
223             extends AbstractTableModel {
224         /**
225          * Serial Id.
226          */
227         private static final long serialVersionUID = 1102886271097401423L;
228 
229         /**
230          * The message column.
231          */
232         private static final int COL_MSG = 0;
233 
234         /**
235          * The active Messages list.
236          */
237         private final List<ArduinoMessage> theMessages;
238 
239         /**
240          * Constructor.
241          */
242         ArduinoReceivedModel() {
243             theMessages = new ArrayList<>();
244         }
245 
246         /**
247          * Refresh.
248          * @param pNode the node
249          */
250         void refresh(final ArduinoNode pNode) {
251             /* Clear the messages */
252             theMessages.clear();
253 
254             /* If we have a node */
255             if (pNode != null) {
256                 /* Loop through the messages */
257                 for (ArduinoMessage myMsg : pNode.getOwner().getMessages()) {
258                     if (pNode.receivesMessage(myMsg)) {
259                         theMessages.add(myMsg);
260                     }
261                 }
262             }
263 
264             /* Refresh the table */
265             fireTableDataChanged();
266 
267             /* Select the first message if available */
268             if (!theMessages.isEmpty()) {
269                 theReceivedTable.changeSelection(0, 0, false, false);
270 
271                 /* else clear the signals */
272             } else {
273                 theSignalsModel.refresh(null, null);
274             }
275         }
276 
277         @Override
278         public int getRowCount() {
279             return theMessages.size();
280         }
281 
282         @Override
283         public String getColumnName(final int pColIndex) {
284             return pColIndex == COL_MSG ? "Received Messages" :  null;
285         }
286 
287         @Override
288         public int getColumnCount() {
289             return COL_MSG + 1;
290         }
291 
292         @Override
293         public boolean isCellEditable(final int pRowIndex,
294                                       final int pColIndex) {
295             return false;
296         }
297 
298         @Override
299         public Object getValueAt(final int pRowIndex,
300                                  final int pColIndex) {
301             return pColIndex == COL_MSG ? theMessages.get(pRowIndex).getName() : null;
302         }
303 
304         /**
305          * Obtain the item at index.
306          * @param pIndex the index
307          * @return the item
308          */
309         ArduinoMessage getItem(final int pIndex) {
310             return theMessages.get(pIndex);
311         }
312     }
313 
314     /**
315      * Received Signals Model.
316      */
317     private static class ArduinoSignalsModel
318             extends AbstractTableModel {
319         /**
320          * Serial Id.
321          */
322         private static final long serialVersionUID = 6232968337216069200L;
323 
324         /**
325          * The signal column.
326          */
327         private static final int COL_SIGNAL = 0;
328 
329         /**
330          * The active signals list.
331          */
332         private final List<ArduinoSignal> theSignals;
333 
334         /**
335          * Constructor.
336          */
337         ArduinoSignalsModel() {
338             theSignals = new ArrayList<>();
339         }
340 
341         /**
342          * Refresh.
343          * @param pNode the node
344          * @param pMessage the message
345          */
346         void refresh(final ArduinoNode pNode,
347                      final ArduinoMessage pMessage) {
348             /* Clear the signals */
349             theSignals.clear();
350 
351             /* If we have a message */
352             if (pMessage != null) {
353                 /* Loop through the signals */
354                 for (ArduinoSignal mySignal : pMessage.getAllSignals()) {
355                     /* Add signal if it is received by the node */
356                     if (mySignal.getReceivers().contains(pNode)) {
357                         theSignals.add(mySignal);
358                     }
359                 }
360             }
361 
362             /* Refresh the table */
363             fireTableDataChanged();
364         }
365 
366         @Override
367         public int getRowCount() {
368             return theSignals.size();
369         }
370 
371         @Override
372         public String getColumnName(final int pColIndex) {
373             return pColIndex == COL_SIGNAL ? "Received Signals" :  null;
374         }
375 
376         @Override
377         public int getColumnCount() {
378             return COL_SIGNAL + 1;
379         }
380 
381         @Override
382         public boolean isCellEditable(final int pRowIndex,
383                                       final int pColIndex) {
384             return false;
385         }
386 
387         @Override
388         public Object getValueAt(final int pRowIndex,
389                                  final int pColIndex) {
390             return pColIndex == COL_SIGNAL ? theSignals.get(pRowIndex).getName() : null;
391         }
392     }
393 }