ArduinoPanelMain.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.awt.BorderLayout;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import net.sourceforge.jarduino.ArduinoException;
import net.sourceforge.jarduino.util.ArduinoLogManager;
import net.sourceforge.jarduino.util.ArduinoLogger;
/**
* Arduino Swing StartUp.
*/
public final class ArduinoPanelMain {
/**
* The LOGGER.
*/
private static final ArduinoLogger LOGGER = ArduinoLogManager.getLogger(ArduinoPanelMain.class);
/**
* The Default Width.
*/
static final int WIDTH = 900;
/**
* The Default Height.
*/
static final int HEIGHT = 400;
/**
* The StrutSize.
*/
static final int STRUTSIZE = 5;
/**
* The Frame.
*/
private final JFrame theFrame;
/**
* The tabPane.
*/
private final JTabbedPane theTabs;
/**
* The sourcePane.
*/
private final ArduinoPanelSource theSource;
/**
* The messagePane.
*/
private final ArduinoPanelSignal theMessage;
/**
* The metaDataPane.
*/
private final ArduinoPanelMeta theMeta;
/**
* The error panel.
*/
private final JPanel theErrorPanel;
/**
* The error Label.
*/
private final JLabel theErrorLabel;
/**
* The detail label.
*/
private final JLabel theDetail;
/**
* The error.
*/
private ArduinoException theError;
/**
* Constructor.
* @throws ArduinoException on error
*/
ArduinoPanelMain() throws ArduinoException {
/* Create the frame */
theFrame = new JFrame();
theFrame.setTitle("jArduino");
/* Build the tabs */
theTabs = new JTabbedPane();
/* Create the panels that exist for a loaded file */
theSource = new ArduinoPanelSource(theFrame);
theMessage = new ArduinoPanelSignal(theFrame);
theMeta = new ArduinoPanelMeta(theFrame);
/* Create the error detail and clear button */
theDetail = new JLabel();
final JButton myClear = new JButton();
myClear.setText("Clear");
myClear.addActionListener(e -> clearError());
/* Create the base error panel */
theErrorLabel = new JLabel();
final JPanel myErrorPanel = new JPanel();
myErrorPanel.setLayout(new BoxLayout(myErrorPanel, BoxLayout.X_AXIS));
myErrorPanel.add(theErrorLabel);
myErrorPanel.add(Box.createHorizontalGlue());
myErrorPanel.add(myClear);
/* Create the error panel */
theErrorPanel = new JPanel();
theErrorPanel.setLayout(new BoxLayout(theErrorPanel, BoxLayout.Y_AXIS));
theErrorPanel.add(myErrorPanel);
theErrorPanel.add(theDetail);
theErrorPanel.setVisible(false);
/* Build the frame */
buildFrame();
}
/**
* Obtain the frame.
* @return the frame
*/
JFrame getFrame() {
return theFrame;
}
/**
* Build the frame.
* @throws ArduinoException on error
*/
private void buildFrame() throws ArduinoException {
/* Create a borderLayout */
final JPanel myPanel = new JPanel();
myPanel.setLayout(new BorderLayout());
myPanel.add(theErrorPanel, BorderLayout.PAGE_START);
myPanel.add(theTabs, BorderLayout.CENTER);
/* Attach the panel to the frame */
theFrame.setContentPane(myPanel);
theFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
theFrame.addWindowListener(new WindowClose());
/* Load icon */
theFrame.setIconImage(loadImage());
/* Create menuBar */
final ArduinoMenuBar myMenuBar = new ArduinoMenuBar(theFrame, this);
theFrame.setJMenuBar(myMenuBar.getComponent());
/* Show the frame */
theFrame.pack();
theFrame.setLocationRelativeTo(null);
theFrame.setVisible(true);
}
/**
* Load image.
* @return the icon
* @throws ArduinoException on error
*/
private static Image loadImage() throws ArduinoException {
/* Protect against exceptions */
try (InputStream myStream = ArduinoPanelMain.class.getResourceAsStream("icons/BlueJellyGears.png")) {
return ImageIO.read(myStream);
/* Handle exceptions */
} catch (IOException e) {
throw new ArduinoException("Failed to load icon", e);
}
}
/**
* Set the selected system.
* @param pSelected the selected system.
* @param pCharSet the character set to use
* @return the error or null for success
*/
ArduinoException setSelected(final File pSelected,
final Charset pCharSet) {
/* Process the selected file */
final boolean bSuccess = theSource.setSelected(pSelected, pCharSet);
/* If we were successful */
if (bSuccess) {
/* Remove the source component */
theTabs.remove(theSource.getComponent());
theTabs.remove(theMessage.getComponent());
theTabs.remove(theMeta.getComponent());
/* Insert tab if we were successful */
theFrame.setTitle("jArduino - " + theSource.getSystem().getName());
theTabs.insertTab("MetaData", null, theMeta.getComponent(), null, 0);
theMeta.setSystem(theSource.getSystem());
theTabs.insertTab("Message", null, theMessage.getComponent(), null, 0);
theMessage.setSystem(theSource.getSystem());
theTabs.insertTab("Sources", null, theSource.getComponent(), null, 0);
theTabs.setSelectedIndex(0);
/* return success indication */
return null;
/* else report the error */
} else {
return theSource.getError();
}
}
/**
* Write the sketch output.
* @param pOutDir the output directory.
* @param pCharSet the character set to use
* @return the error or null for success
*/
ArduinoException writeSketch(final File pOutDir,
final Charset pCharSet) {
return theSource.writeSketchToDirectory(pOutDir, pCharSet);
}
/**
* Write the library output.
* @param pOutDir the output directory.
* @param pCharSet the character set to use
* @return the error or null for success
*/
ArduinoException writeLibrary(final File pOutDir,
final Charset pCharSet) {
return theSource.writeLibraryToDirectory(pOutDir, pCharSet);
}
/**
* Set error.
* @param pError the error
*/
void setError(final ArduinoException pError) {
theError = pError;
theErrorLabel.setText("Error: " + theError.getMessage());
theDetail.setText(ArduinoPanelMeta.cleanseLabelText(theError.getDetail()));
theErrorPanel.setVisible(true);
}
/**
* Clear the error.
*/
private void clearError() {
theError = null;
theErrorPanel.setVisible(false);
}
/**
* Handler for Window Close event.
*/
private class WindowClose
extends WindowAdapter {
@Override
public void windowClosing(final WindowEvent evt) {
/* Dispose of the frame */
theFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
theFrame.dispose();
}
}
/**
* Create and show the GUI.
*/
private static void createAndShowGUI() {
/* Protect against exceptions */
try {
/* Create the panel */
new ArduinoPanelMain();
/* Catch exceptions */
} catch (ArduinoException e) {
LOGGER.fatal("Failed to initialise", e);
}
}
/**
* Main function.
* @param args the arguments
*/
public static void main(final String[] args) {
/* Build the GUI */
SwingUtilities.invokeLater(ArduinoPanelMain::createAndShowGUI);
}
}