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 Message Connection Table.
34   */
35  public class ArduinoTableMsgConnect {
36      /**
37       * The splitPane.
38       */
39      private final JSplitPane thePane;
40  
41      /**
42       * The signals table.
43       */
44      private final JTable theSignalsTable;
45  
46      /**
47       * The signals model.
48       */
49      private final ArduinoSignalsModel theSignalsModel;
50  
51      /**
52       * The signals nodes model.
53       */
54      private final ArduinoSignalNodesModel theNodesModel;
55  
56      /**
57       * The senders model.
58       */
59      private final ArduinoSentByModel theSendersModel;
60  
61      /**
62       * Constructor.
63       */
64      ArduinoTableMsgConnect() {
65          /* Create the tables */
66          theSignalsTable = new JTable();
67          theSignalsTable.setAutoCreateRowSorter(true);
68          theSignalsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
69          final JTable mySignalNodesTable = new JTable();
70          mySignalNodesTable.setAutoCreateRowSorter(true);
71          final JTable mySendingNodesTable = new JTable();
72          mySendingNodesTable.setAutoCreateRowSorter(true);
73  
74          /* Create the table models */
75          theSignalsModel = new ArduinoSignalsModel();
76          theSignalsTable.setModel(theSignalsModel);
77          theNodesModel = new ArduinoSignalNodesModel();
78          mySignalNodesTable.setModel(theNodesModel);
79          theSendersModel = new ArduinoSentByModel();
80          mySendingNodesTable.setModel(theSendersModel);
81  
82          /* Create a splitPane */
83          final JSplitPane myPane =  new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
84          myPane.setLeftComponent(new JScrollPane(theSignalsTable));
85          myPane.setRightComponent(new JScrollPane(mySignalNodesTable));
86          myPane.setResizeWeight(ArduinoTableNodeConnect.HALF_WEIGHT);
87  
88          /* Update nodes on selection of signal */
89          final ListSelectionModel mySelect = theSignalsTable.getSelectionModel();
90          mySelect.addListSelectionListener(e -> {
91              if (!e.getValueIsAdjusting()) {
92                  int myIndex = mySelect.getMinSelectionIndex();
93                  if (myIndex != -1) {
94                      myIndex = theSignalsTable.convertRowIndexToModel(myIndex);
95                      theNodesModel.refresh(theSignalsModel.getItem(myIndex));
96                  }
97              }
98          });
99  
100         /* Create a splitPane */
101         thePane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
102         thePane.setLeftComponent(new JScrollPane(mySendingNodesTable));
103         thePane.setRightComponent(myPane);
104         thePane.setResizeWeight(ArduinoTableNodeConnect.THIRD_WEIGHT);
105     }
106 
107     /**
108      * Obtain the component.
109      * @return the component
110      */
111     JComponent getComponent() {
112         return thePane;
113     }
114 
115     /**
116      * Configure the table.
117      *
118      * @param pMessage the message
119      */
120     void configureTable(final ArduinoMessage pMessage) {
121         /* refresh the tables */
122         theSignalsModel.refresh(pMessage);
123         theSendersModel.refresh(pMessage);
124     }
125 
126     /**
127      * Sending Nodes Table Model.
128      */
129     private static class ArduinoSentByModel
130             extends AbstractTableModel {
131         /**
132          * Serial Id.
133          */
134         private static final long serialVersionUID = 5860442671388666448L;
135 
136         /**
137          * The sender column.
138          */
139         private static final int COL_SENDER = 0;
140 
141         /**
142          * The active Nodes list.
143          */
144         private final List<ArduinoNode> theSenders;
145 
146         /**
147          * Constructor.
148          */
149         ArduinoSentByModel() {
150             theSenders = new ArrayList<>();
151         }
152 
153         /**
154          * Refresh.
155          * @param pMessage the message
156          */
157         void refresh(final ArduinoMessage pMessage) {
158             /* Clear the messages */
159             theSenders.clear();
160 
161             /* If we have a node */
162             if (pMessage != null) {
163                 /* Loop through the messages */
164                 for (ArduinoNode myNode : pMessage.getSystem().getNodes()) {
165                     /* Add if this is not the Null node and it sends the message */
166                     if (!ArduinoNode.NULL_NODE.equals(myNode.getName())
167                         && myNode.sendsMessage(pMessage)) {
168                         theSenders.add(myNode);
169                     }
170                 }
171             }
172 
173             /* Refresh the table */
174             fireTableDataChanged();
175         }
176 
177         @Override
178         public int getRowCount() {
179             return theSenders.size();
180         }
181 
182         @Override
183         public String getColumnName(final int pColIndex) {
184             return pColIndex == COL_SENDER ? "Sent By" :  null;
185         }
186 
187         @Override
188         public int getColumnCount() {
189             return COL_SENDER + 1;
190         }
191 
192         @Override
193         public boolean isCellEditable(final int pRowIndex,
194                                       final int pColIndex) {
195             return false;
196         }
197 
198         @Override
199         public Object getValueAt(final int pRowIndex,
200                                  final int pColIndex) {
201             return pColIndex == COL_SENDER ? theSenders.get(pRowIndex).getName() : null;
202         }
203     }
204 
205     /**
206      * Signals Table Model.
207      */
208     private class ArduinoSignalsModel
209             extends AbstractTableModel {
210         /**
211          * Serial Id.
212          */
213         private static final long serialVersionUID = 3438477307113875891L;
214 
215         /**
216          * The signal column.
217          */
218         private static final int COL_SIGNAL = 0;
219 
220         /**
221          * The active Signals list.
222          */
223         private List<ArduinoSignal> theSignals;
224 
225         /**
226          * Constructor.
227          */
228         ArduinoSignalsModel() {
229         }
230 
231         /**
232          * Refresh.
233          * @param pMessage the message
234          */
235         void refresh(final ArduinoMessage pMessage) {
236             /* Record the nodes */
237             theSignals = pMessage == null ? null : pMessage.getAllSignals();
238 
239             /* Refresh the table */
240             fireTableDataChanged();
241 
242             /* Select the first message if available */
243             if (theSignals != null && !theSignals.isEmpty()) {
244                 theSignalsTable.changeSelection(0, 0, false, false);
245 
246                 /* else clear the nodes */
247             } else {
248                 theNodesModel.refresh(null);
249             }
250         }
251 
252         @Override
253         public int getRowCount() {
254             return theSignals == null ? 0 : theSignals.size();
255         }
256 
257         @Override
258         public String getColumnName(final int pColIndex) {
259             return pColIndex == COL_SIGNAL ? "Signal" :  null;
260         }
261 
262         @Override
263         public int getColumnCount() {
264             return COL_SIGNAL + 1;
265         }
266 
267         @Override
268         public boolean isCellEditable(final int pRowIndex,
269                                       final int pColIndex) {
270             return false;
271         }
272 
273         @Override
274         public Object getValueAt(final int pRowIndex,
275                                  final int pColIndex) {
276             return pColIndex == COL_SIGNAL ? theSignals.get(pRowIndex).getName() : null;
277         }
278 
279         /**
280          * Obtain the item at index.
281          * @param pIndex the index
282          * @return the item
283          */
284         ArduinoSignal getItem(final int pIndex) {
285             return theSignals.get(pIndex);
286         }
287     }
288 
289     /**
290      * Signal Nodes Table Model.
291      */
292     private static class ArduinoSignalNodesModel
293             extends AbstractTableModel {
294         /**
295          * Serial Id.
296          */
297         private static final long serialVersionUID = 2945394153649721652L;
298 
299         /**
300          * The node column.
301          */
302         private static final int COL_NODE = 0;
303 
304         /**
305          * The active Nodes list.
306          */
307         private final List<ArduinoNode> theNodes;
308 
309         /**
310          * Constructor.
311          */
312         ArduinoSignalNodesModel() {
313             theNodes = new ArrayList<>();
314         }
315 
316         /**
317          * Refresh.
318          * @param pSignal the signal
319          */
320         void refresh(final ArduinoSignal pSignal) {
321             /* Clear the list */
322             theNodes.clear();
323 
324             /* If we have a signal */
325             if (pSignal != null) {
326                 /* Loop through the receivers */
327                 for (ArduinoNode myNode : pSignal.getReceivers()) {
328                     /* Add if this is not the Null node */
329                     if (!ArduinoNode.NULL_NODE.equals(myNode.getName())) {
330                         theNodes.add(myNode);
331                     }
332                 }
333             }
334 
335             /* Refresh the table */
336             fireTableDataChanged();
337         }
338 
339         @Override
340         public int getRowCount() {
341             return theNodes.size();
342         }
343 
344         @Override
345         public String getColumnName(final int pColIndex) {
346             return pColIndex == COL_NODE ? "Received By" :  null;
347         }
348 
349         @Override
350         public int getColumnCount() {
351             return COL_NODE + 1;
352         }
353 
354         @Override
355         public boolean isCellEditable(final int pRowIndex,
356                                       final int pColIndex) {
357             return false;
358         }
359 
360         @Override
361         public Object getValueAt(final int pRowIndex,
362                                  final int pColIndex) {
363             return pColIndex == COL_NODE ? theNodes.get(pRowIndex).getName() : null;
364         }
365     }
366 }