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 java.awt.BorderLayout;
20  import java.awt.Image;
21  import java.awt.event.WindowAdapter;
22  import java.awt.event.WindowEvent;
23  import java.io.File;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.nio.charset.Charset;
27  import javax.imageio.ImageIO;
28  import javax.swing.Box;
29  import javax.swing.BoxLayout;
30  import javax.swing.JButton;
31  import javax.swing.JFrame;
32  import javax.swing.JLabel;
33  import javax.swing.JPanel;
34  import javax.swing.JTabbedPane;
35  import javax.swing.SwingUtilities;
36  import javax.swing.WindowConstants;
37  
38  import net.sourceforge.jarduino.ArduinoException;
39  import net.sourceforge.jarduino.util.ArduinoLogManager;
40  import net.sourceforge.jarduino.util.ArduinoLogger;
41  
42  /**
43   * Arduino Swing StartUp.
44   */
45  public final class ArduinoPanelMain {
46      /**
47       * The LOGGER.
48       */
49      private static final ArduinoLogger LOGGER = ArduinoLogManager.getLogger(ArduinoPanelMain.class);
50  
51      /**
52       * The Default Width.
53       */
54      static final int WIDTH = 900;
55  
56      /**
57       * The Default Height.
58       */
59      static final int HEIGHT = 400;
60  
61      /**
62       * The StrutSize.
63       */
64      static final int STRUTSIZE = 5;
65  
66      /**
67       * The Frame.
68       */
69      private final JFrame theFrame;
70  
71      /**
72       * The tabPane.
73       */
74      private final JTabbedPane theTabs;
75  
76     /**
77       * The sourcePane.
78       */
79      private final ArduinoPanelSource theSource;
80  
81      /**
82       * The messagePane.
83       */
84      private final ArduinoPanelSignal theMessage;
85  
86      /**
87       * The metaDataPane.
88       */
89      private final ArduinoPanelMeta theMeta;
90  
91      /**
92       * The error panel.
93       */
94      private final JPanel theErrorPanel;
95  
96      /**
97       * The error Label.
98       */
99      private final JLabel theErrorLabel;
100 
101     /**
102      * The detail label.
103      */
104     private final JLabel theDetail;
105 
106     /**
107      * The error.
108      */
109     private ArduinoException theError;
110 
111     /**
112      * Constructor.
113      * @throws ArduinoException on error
114      */
115     ArduinoPanelMain() throws ArduinoException {
116         /* Create the frame */
117         theFrame = new JFrame();
118         theFrame.setTitle("jArduino");
119 
120         /* Build the tabs */
121         theTabs = new JTabbedPane();
122 
123         /* Create the panels that exist for a loaded file */
124         theSource = new ArduinoPanelSource(theFrame);
125         theMessage = new ArduinoPanelSignal(theFrame);
126         theMeta = new ArduinoPanelMeta(theFrame);
127 
128         /* Create the error detail and clear button */
129         theDetail = new JLabel();
130         final JButton myClear = new JButton();
131         myClear.setText("Clear");
132         myClear.addActionListener(e -> clearError());
133 
134         /* Create the base error panel */
135         theErrorLabel = new JLabel();
136         final JPanel myErrorPanel = new JPanel();
137         myErrorPanel.setLayout(new BoxLayout(myErrorPanel, BoxLayout.X_AXIS));
138         myErrorPanel.add(theErrorLabel);
139         myErrorPanel.add(Box.createHorizontalGlue());
140         myErrorPanel.add(myClear);
141 
142         /* Create the error panel */
143         theErrorPanel = new JPanel();
144         theErrorPanel.setLayout(new BoxLayout(theErrorPanel, BoxLayout.Y_AXIS));
145         theErrorPanel.add(myErrorPanel);
146         theErrorPanel.add(theDetail);
147         theErrorPanel.setVisible(false);
148 
149         /* Build the frame */
150         buildFrame();
151     }
152 
153     /**
154      * Obtain the frame.
155      * @return the frame
156      */
157     JFrame getFrame() {
158         return theFrame;
159     }
160 
161     /**
162      * Build the frame.
163      * @throws ArduinoException on error
164      */
165     private void buildFrame() throws ArduinoException {
166         /* Create a borderLayout */
167         final JPanel myPanel = new JPanel();
168         myPanel.setLayout(new BorderLayout());
169         myPanel.add(theErrorPanel, BorderLayout.PAGE_START);
170         myPanel.add(theTabs, BorderLayout.CENTER);
171 
172         /* Attach the panel to the frame */
173         theFrame.setContentPane(myPanel);
174         theFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
175         theFrame.addWindowListener(new WindowClose());
176 
177         /* Load icon */
178         theFrame.setIconImage(loadImage());
179 
180         /* Create menuBar */
181         final ArduinoMenuBaruBar.html#ArduinoMenuBar">ArduinoMenuBar myMenuBar = new ArduinoMenuBar(theFrame, this);
182         theFrame.setJMenuBar(myMenuBar.getComponent());
183 
184         /* Show the frame */
185         theFrame.pack();
186         theFrame.setLocationRelativeTo(null);
187         theFrame.setVisible(true);
188     }
189 
190     /**
191      * Load image.
192      * @return the icon
193      * @throws ArduinoException on error
194      */
195     private static Image loadImage() throws ArduinoException {
196         /* Protect against exceptions */
197         try (InputStream myStream = ArduinoPanelMain.class.getResourceAsStream("icons/BlueJellyGears.png")) {
198             return ImageIO.read(myStream);
199 
200             /* Handle exceptions */
201         } catch (IOException e) {
202             throw new ArduinoException("Failed to load icon", e);
203         }
204     }
205 
206     /**
207      * Set the selected system.
208      * @param pSelected the selected system.
209      * @param pCharSet the character set to use
210      * @return the error or null for success
211      */
212     ArduinoException setSelected(final File pSelected,
213                                  final Charset pCharSet) {
214         /* Process the selected file */
215         final boolean bSuccess = theSource.setSelected(pSelected, pCharSet);
216 
217         /* If we were successful */
218         if (bSuccess) {
219             /* Remove the source component */
220             theTabs.remove(theSource.getComponent());
221             theTabs.remove(theMessage.getComponent());
222             theTabs.remove(theMeta.getComponent());
223 
224             /* Insert tab if we were successful */
225             theFrame.setTitle("jArduino - " + theSource.getSystem().getName());
226             theTabs.insertTab("MetaData", null, theMeta.getComponent(), null, 0);
227             theMeta.setSystem(theSource.getSystem());
228             theTabs.insertTab("Message", null, theMessage.getComponent(), null, 0);
229             theMessage.setSystem(theSource.getSystem());
230             theTabs.insertTab("Sources", null, theSource.getComponent(), null, 0);
231             theTabs.setSelectedIndex(0);
232 
233             /* return success indication */
234             return null;
235 
236             /* else report the error */
237         } else {
238             return theSource.getError();
239         }
240     }
241 
242     /**
243      * Write the sketch output.
244      * @param pOutDir the output directory.
245      * @param pCharSet the character set to use
246      * @return the error or null for success
247      */
248     ArduinoException writeSketch(final File pOutDir,
249                                  final Charset pCharSet) {
250         return theSource.writeSketchToDirectory(pOutDir, pCharSet);
251     }
252 
253     /**
254      * Write the library output.
255      * @param pOutDir the output directory.
256      * @param pCharSet the character set to use
257      * @return the error or null for success
258      */
259     ArduinoException writeLibrary(final File pOutDir,
260                                   final Charset pCharSet) {
261         return theSource.writeLibraryToDirectory(pOutDir, pCharSet);
262     }
263 
264     /**
265      * Set error.
266      * @param pError the error
267      */
268     void setError(final ArduinoException pError) {
269         theError = pError;
270         theErrorLabel.setText("Error: " + theError.getMessage());
271         theDetail.setText(ArduinoPanelMeta.cleanseLabelText(theError.getDetail()));
272         theErrorPanel.setVisible(true);
273     }
274 
275     /**
276      * Clear the error.
277      */
278     private void clearError() {
279         theError = null;
280         theErrorPanel.setVisible(false);
281     }
282 
283     /**
284      * Handler for Window Close event.
285      */
286     private class WindowClose
287             extends WindowAdapter {
288         @Override
289         public void windowClosing(final WindowEvent evt) {
290             /* Dispose of the frame */
291             theFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
292             theFrame.dispose();
293         }
294     }
295 
296     /**
297      * Create and show the GUI.
298      */
299     private static void createAndShowGUI() {
300         /* Protect against exceptions */
301         try {
302             /* Create the panel */
303             new ArduinoPanelMain();
304 
305             /* Catch exceptions */
306         } catch (ArduinoException e) {
307             LOGGER.fatal("Failed to initialise", e);
308         }
309     }
310 
311     /**
312      * Main function.
313      * @param args the arguments
314      */
315     public static void main(final String[] args) {
316         /* Build the GUI */
317         SwingUtilities.invokeLater(ArduinoPanelMain::createAndShowGUI);
318     }
319 }