package jamel.gui; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Frame; import java.awt.Window; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Locale; import javax.swing.BoxLayout; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import jamel.util.JamelObject; import jamel.util.Simulation; /** * A basic graphical user interface. */ public class BasicGui extends JamelObject implements Gui { /** * The background color for the tabed panels. */ private static final Color tabPanelBackgroundColor = new Color(0, 0, 0, 0); /** * Marks the specified window as able to be full screened. * * @param window * the window to be marked. */ private static void enableOSXFullscreen(Window window) { if ("Mac OS X".equals(System.getProperty("os.name"))) { if (window != null) { try { final Class<?> util = Class.forName("com.apple.eawt.FullScreenUtilities"); util.getMethod("setWindowCanFullScreen", Window.class, Boolean.TYPE).invoke(util, window, true); } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { e.printStackTrace(); } } } } /** * Creates and returns a new panel (a chart panel or a html panel). * * @param elem * the description of the panel to be created. * @param gui * the parent Gui. * @return the new panel. */ private static Component getNewPanel(final Element elem, final Gui gui) { final Component result; try { if (elem.getNodeName().equals("empty")) { result = new EmptyPanel(); } else if (elem.getNodeName().equals("chart")) { JamelChartPanel chartPanel = null; try { chartPanel = JamelChartFactory.createChartPanel(elem, gui.getSimulation()); } catch (final Exception e) { e.printStackTrace(); } if (chartPanel != null) { result = chartPanel; } else { result = new EmptyPanel(); // TODO il vaudrait mieux un HtmlPanel avec un message // d'erreur. } } else if (elem.getNodeName().equals("html")) { result = new HtmlPanel(elem, gui); } else { throw new RuntimeException("Not yet implemented: " + elem.getNodeName()); } } catch (Exception e) { throw new RuntimeException("Not yet implemented", e); /*e.printStackTrace(); result = HtmlPanel .getErrorPanel("Error:<br />" + e.toString() + "<br />See jamel.log file for more details.");*/ } return result; } /** * The control panel. */ final private ControlPanel controlPanel; /** * The list of the panels (charts and html). */ final private List<Component> panels = new LinkedList<>(); /** * The tabbedPane. */ private final JTabbedPane tabbedPane = new JTabbedPane(); /** * The window. */ final private JFrame window = new JFrame(); /** * Creates a new basic gui. * * @param element * an XML element that specifies the gui to be created. * @param parentFile * the file where the Gui was described. * @param simulation * the parent simulation? */ public BasicGui(final Element element, final File parentFile, final Simulation simulation) { super(simulation); if (!element.getNodeName().equals("gui")) { throw new RuntimeException("Bad element: " + element.getNodeName()); } this.controlPanel = new ControlPanel(simulation); { // Ce bloc devrait ĂȘtre commentĂ©. final NodeList panelNodeList = element.getElementsByTagName("panel"); for (int i = 0; i < panelNodeList.getLength(); i++) { if (panelNodeList.item(i).getNodeType() != Node.ELEMENT_NODE) { throw new RuntimeException("This node should be a panel node."); } final Element panelElement = (Element) panelNodeList.item(i); if (!panelElement.getAttribute("visible").equals("false")) { final JPanel tabPanel = new JPanel(); tabPanel.setLayout(new BoxLayout(tabPanel, BoxLayout.X_AXIS)); tabPanel.setBackground(tabPanelBackgroundColor); tabPanel.setName(panelElement.getAttribute("title")); final NodeList nodeList = panelElement.getChildNodes(); JPanel col = new JPanel(); col.setLayout(new BoxLayout(col, BoxLayout.Y_AXIS)); tabPanel.add(col); for (int j = 0; j < nodeList.getLength(); j++) { final Node node = nodeList.item(j); if (node.getNodeName().equals("col")) { col = new JPanel(); col.setLayout(new BoxLayout(col, BoxLayout.Y_AXIS)); tabPanel.add(col); } else if (node.getNodeType() == Node.ELEMENT_NODE) { final Component subPanel = getNewPanel((Element) nodeList.item(j), this); this.panels.add(subPanel); col.add(subPanel); } } this.tabbedPane.add(tabPanel); } } } // Setting the window. enableOSXFullscreen(this.window); this.window.setMinimumSize(new Dimension(400, 200)); this.window.setPreferredSize(new Dimension(800, 400)); this.window.pack(); this.window.setExtendedState(Frame.MAXIMIZED_BOTH); this.window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.window.getContentPane().add(this.tabbedPane); this.window.getContentPane().add(this.controlPanel, "South"); this.controlPanel.repaint(); final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMM d HH:mm:ss", Locale.US); final String dateStr = simpleDateFormat.format(new Date()); this.window.setTitle(simulation.getName() + " (" + dateStr + ")"); this.window.setVisible(true); this.update(); } @Override public void doEvent(Element event) { // TODO implement me ! } @Override public File getFile() { throw new RuntimeException("Not yet implemented"); } @Override public void update() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { BasicGui.this.controlPanel.update(); } }); for (final Component panel : this.panels) { if (panel instanceof Updatable) { ((Updatable) panel).update(); } } } @Override public void displayErrorMessage(final String title, final String message) { JOptionPane.showMessageDialog(this.window, "<html>" + message + "<br>See the console for more details.</html>", title, JOptionPane.ERROR_MESSAGE); } }