package thaw.core; import java.awt.BorderLayout; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.WindowEvent; import java.util.Iterator; import java.util.Vector; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JTabbedPane; import javax.swing.JToolBar; import javax.swing.JTextField; import javax.swing.WindowConstants; import java.awt.event.WindowListener; import thaw.gui.TabbedPane; import thaw.gui.IconBox; /** * MainWindow. This class create the main window. * * Main window is divided in three parts: * * <pre> * ------------------------------------ * | MenuBar | * ------------------------------------ * | ToolBar | * ------------------------------------ * | Tab 1 | Tab 2 | Tab 3 | | * |----------------------------------| * | Tab content | * | | * | | * | | * | | * ------------------------------------ * | JLabel (status) | * ------------------------------------ * </pre> * * @author <a href="mailto:jflesch@nerim.net">Jerome Flesch</a> */ public class MainWindow implements java.awt.event.ActionListener, WindowListener, java.util.Observer { public final static int DEFAULT_SIZE_X = 790; public final static int DEFAULT_SIZE_Y = 550; private JFrame mainWindow = null; private JMenuBar menuBar = null; private JMenu fileMenu = null; private Vector fileMenuList = null; private JMenuItem reconnectionFileMenuItem = null; private JMenuItem optionsFileMenuItem = null; private JMenuItem quitFileMenuItem = null; private JMenu helpMenu = null; private Vector menuList = null; private JMenuItem aboutHelpMenuItem = null; private JToolBar toolBar = null; private JButton connectButton = null; private JButton disconnectButton = null; private JButton settingsButton = null; private JButton quitButton = null; private TabbedPane tabbedPane = null; private JLabel statusBar = null; private Core core = null; /* core is called back when exit() */ private Object lastToolBarModifier = null; /** * Creates a new <code>MainWindow</code> instance, and so a new Swing window. * @param core a <code>Core</code> value */ public MainWindow(final Core core) { this.core = core; mainWindow = new JFrame("Thaw"); mainWindow.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); mainWindow.setVisible(false); try { mainWindow.setIconImage(IconBox.blueBunny.getImage()); } catch(final Throwable e) { Logger.notice(this, "No icon"); } // MENUS menuBar = new JMenuBar(); menuList = new Vector(); fileMenu = new JMenu(I18n.getMessage("thaw.menu.file")); fileMenuList = new Vector(); reconnectionFileMenuItem = new JMenuItem(I18n.getMessage("thaw.menu.item.reconnect"), IconBox.minReconnectAction); optionsFileMenuItem = new JMenuItem(I18n.getMessage("thaw.menu.item.options"), IconBox.minSettings); quitFileMenuItem = new JMenuItem(I18n.getMessage("thaw.menu.item.quit"), IconBox.minQuitAction); fileMenuList.add(reconnectionFileMenuItem); fileMenuList.add(optionsFileMenuItem); fileMenuList.add(quitFileMenuItem); reconnectionFileMenuItem.addActionListener(this); optionsFileMenuItem.addActionListener(this); quitFileMenuItem.addActionListener(this); fileMenu.add(reconnectionFileMenuItem); fileMenu.add(optionsFileMenuItem); fileMenu.add(quitFileMenuItem); menuBar.add(fileMenu); menuList.add(fileMenu); helpMenu = new JMenu(I18n.getMessage("thaw.menu.help")); aboutHelpMenuItem = new JMenuItem(I18n.getMessage("thaw.menu.item.about"), IconBox.minHelp); aboutHelpMenuItem.addActionListener(this); helpMenu.add(aboutHelpMenuItem); //menuBar.add(Box.createHorizontalGlue()); menuBar.add(helpMenu); menuList.add(helpMenu); // TOOLBAR connectButton = new JButton(IconBox.connectAction); connectButton.setBorderPainted(false); connectButton.setToolTipText(I18n.getMessage("thaw.toolbar.button.connect")); disconnectButton = new JButton(IconBox.disconnectAction); disconnectButton.setBorderPainted(false); disconnectButton.setToolTipText(I18n.getMessage("thaw.toolbar.button.disconnect")); settingsButton = new JButton(IconBox.settings); settingsButton.setBorderPainted(false); settingsButton.setToolTipText(I18n.getMessage("thaw.toolbar.button.settings")); quitButton = new JButton(IconBox.quitAction); quitButton.setBorderPainted(false); quitButton.setToolTipText(I18n.getMessage("thaw.toolbar.button.quit")); connectButton.addActionListener(this); disconnectButton.addActionListener(this); settingsButton.addActionListener(this); quitButton.addActionListener(this); // TABBED PANE tabbedPane = new TabbedPane(); // STATUS BAR statusBar = new JLabel(); setStatus(null, null); statusBar.setSize(500, 30); mainWindow.getContentPane().setLayout(new BorderLayout(5,5)); mainWindow.setJMenuBar(menuBar); /* Toolbar adding: */ changeButtonsInTheToolbar(this, null); mainWindow.getContentPane().add(tabbedPane, BorderLayout.CENTER); mainWindow.getContentPane().add(statusBar, BorderLayout.SOUTH); mainWindow.setSize(MainWindow.DEFAULT_SIZE_X, MainWindow.DEFAULT_SIZE_Y); mainWindow.addWindowListener(this); core.getConnectionManager().addObserver(this); if (core.getConfig().getValue("mainWindowSizeX") != null && core.getConfig().getValue("mainWindowSizeY") != null) { try { mainWindow.setSize(Integer.parseInt(core.getConfig().getValue("mainWindowSizeX")), Integer.parseInt(core.getConfig().getValue("mainWindowSizeY"))); } catch(NumberFormatException e) { Logger.warning(this, "Exception while setting the main window size"); } } if (core.getConfig().getValue("mainWindowState") != null) { mainWindow.setExtendedState(Integer.parseInt(core.getConfig().getValue("mainWindowState"))); } mainWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); } public void addWindowListener(WindowListener wl) { mainWindow.addWindowListener(wl); } public void removeWindowListener(WindowListener wl) { mainWindow.removeWindowListener(wl); } public void connectionHasChanged() { core.getConnectionManager().addObserver(this); } /** * Make the window visible or not. */ public void setVisible(final boolean v) { if (!v || !core.isStopping()) { mainWindow.setVisible(v); } if (!v && core.isStopping()) mainWindow.dispose(); } public boolean isVisible() { return mainWindow.isVisible(); } public void setIconified() { int state = mainWindow.getExtendedState(); state |= JFrame.ICONIFIED; mainWindow.setExtendedState(state); } public void setNonIconified() { int state = mainWindow.getExtendedState(); state &= ~JFrame.ICONIFIED; mainWindow.setExtendedState(state); } public JFrame getMainFrame() { return mainWindow; } /** * Should not be used. * @see #addTab(String, java.awt.Component) * @return In the future, it's possible that it will sometimes return null. */ public JTabbedPane getTabbedPane() { return tabbedPane; } public Object getLastToolbarModifier() { return lastToolBarModifier; } /** * @param modifier Correspond to the caller object: it's a security to avoid that a modifier wipe out the buttons from another one * @param newButtons JButton vector : if null, then it means to remove the buttons from the toolbar. Only the object having currently its buttons displayed will be able to remove them, other will simply be ignored. */ public void changeButtonsInTheToolbar(final Object modifier, final Vector newButtons) { JToolBar newToolBar; Logger.debug(this, "changeButtonsInTheToolbar() : Called by "+modifier.getClass().getName()); Logger.debug(this, newButtons == null ? "-> no button" : Integer.toString(newButtons.size()) + " buttons"); if ((lastToolBarModifier == null) || (newButtons != null) || (lastToolBarModifier == modifier)) { lastToolBarModifier = modifier; } else /* Only the modifier who added the buttons can remove them */ return; if (newButtons == null) lastToolBarModifier = null; newToolBar = new JToolBar(I18n.getMessage("thaw.toolbar.title")); newToolBar.setBorderPainted(false); newToolBar.add(connectButton); newToolBar.add(disconnectButton); newToolBar.addSeparator(); newToolBar.add(settingsButton); newToolBar.addSeparator(); if (newButtons != null) { for (final Iterator it = newButtons.iterator(); it.hasNext();) { final JButton button = (JButton)it.next(); if (button != null) { button.setBorderPainted(false); newToolBar.add(button); } else newToolBar.addSeparator(); } newToolBar.addSeparator(); } newToolBar.add(quitButton); newToolBar.setFloatable(false); if (toolBar != null) { mainWindow.getContentPane().remove(toolBar); } toolBar = newToolBar; mainWindow.getContentPane().add(toolBar, BorderLayout.NORTH); updateToolBar(); mainWindow.getContentPane().validate(); } public void resetLastKnowToolBarModifier() { lastToolBarModifier = null; } /** * Used to add a tab in the main window. * In the future, even if the interface change, * this function should remain available. */ public boolean addTab(final String tabName, final java.awt.Component panel) { return addTab(tabName, IconBox.add, panel); } /** * Used to add a tab in the main window. * In the future, even if the interface change, * this function should remain available * @see #addTab(String, java.awt.Component) */ public boolean addTab(final String tabName, final Icon icon, final java.awt.Component panel) { tabbedPane.addTab(tabName, icon, panel); return true; } public boolean setSelectedTab(java.awt.Component c) { tabbedPane.setSelectedComponent(c); return true; } /** * Used to remove a tab from the main window. */ public boolean removeTab(final java.awt.Component panel) { tabbedPane.remove(panel); return true; } /** * Used by plugins to add their own menu. */ public void insertMenuAt(JMenu menu, int position) { menuList.add(position, menu); refreshMenuBar(); } public void removeMenu(JMenu menu) { menuList.remove(menu); refreshMenuBar(); } protected void refreshMenuBar() { Logger.info(this, "Display "+ Integer.toString(menuList.size())+ " menus in the main window"); /* rebuilding menubar */ JMenuBar bar = new JMenuBar(); for (Iterator it = menuList.iterator(); it.hasNext();) { JMenu m = (JMenu)it.next(); bar.add(m); } mainWindow.setJMenuBar(bar); menuBar = bar; mainWindow.validate(); /* no getContentPane() ! else it won't work ! */ } /** * Used by plugins to add their own menu / menuItem to the menu 'file'. */ public void insertInFileMenuAt(Object newItem, int position) { fileMenuList.add(position, newItem); refreshFileMenu(); } public void removeFromFileMenu(Object item) { fileMenuList.remove(item); refreshFileMenu(); } protected void refreshFileMenu() { /* rebuilding menubar */ JMenu m = new JMenu(I18n.getMessage("thaw.menu.file")); for (Iterator it = fileMenuList.iterator(); it.hasNext();) { Object e = it.next(); if (e instanceof JMenuItem) m.add((JMenuItem)e); else m.add((JMenu)e); } menuList.remove(fileMenu); fileMenu = m; menuList.add(0, fileMenu); refreshMenuBar(); } /** * Called when an element from the menu is called. */ public void actionPerformed(final ActionEvent e) { if(e.getSource() == connectButton) { core.reconnect(false); } if(e.getSource() == disconnectButton) { if(!core.canDisconnect()) { if(!core.askDeconnectionConfirmation()) return; } core.getPluginManager().stopPlugins(); core.disconnect(); core.getPluginManager().loadAndRunPlugins(); } if(e.getSource() == settingsButton) { setEnabled(false); core.getConfigWindow().setVisible(true); } if(e.getSource() == quitButton) { endOfTheWorld(); } if(e.getSource() == reconnectionFileMenuItem) { if(!core.canDisconnect()) { if(!core.askDeconnectionConfirmation()) return; } core.reconnect(false); } if(e.getSource() == optionsFileMenuItem) { core.getConfigWindow().setVisible(true); } if(e.getSource() == quitFileMenuItem) { endOfTheWorld(); } if(e.getSource() == aboutHelpMenuItem) { showDialogAbout(); } } /** * Warns the user by a popup. */ protected void unableToConnect() { new thaw.gui.WarningWindow(core, I18n.getMessage("thaw.warning.unableToConnectTo")+ " "+core.getConfig().getValue("nodeAddress")+":"+ core.getConfig().getValue("nodePort")); } public void update(final java.util.Observable o, final Object arg) { updateToolBar(); } public void updateToolBar() { if( core.getConnectionManager() != null && (core.getConnectionManager().isConnected() || core.isReconnecting())) { connectButton.setEnabled(false); disconnectButton.setEnabled(true); } else { connectButton.setEnabled(true); disconnectButton.setEnabled(false); } } /** * Called when window is closed or 'quit' is choosed is the menu. */ public void endOfTheWorld() { if (mainWindow != null) { java.awt.Dimension size = mainWindow.getSize(); core.getConfig().setValue("mainWindowSizeX", Integer.toString((new Double(size.getWidth())).intValue())); core.getConfig().setValue("mainWindowSizeY", Integer.toString((new Double(size.getHeight())).intValue())); core.getConfig().setValue("mainWindowState", Integer.toString(mainWindow.getExtendedState())); } core.exit(); } public void setStatus(final javax.swing.Icon icon, final String status) { setStatus(icon, status, java.awt.Color.BLACK); } /** * Change text in the status bar. * @param status Null is accepted. */ public void setStatus(final javax.swing.Icon icon, final String status, java.awt.Color color) { if(status != null) { statusBar.setText(status); } else { statusBar.setText(" ");/* not empty else the status bar disappear */ } if (icon != null) statusBar.setIcon(icon); if (color != null) statusBar.setForeground(color); } public String getStatus() { return statusBar.getText(); } /** * @param pos can be BorderLayout.EAST or BorderLayout.WEST */ public void addComponent(java.awt.Component c, Object pos) { mainWindow.getContentPane().add(c, pos); } protected void setEnabled(boolean value) { mainWindow.setEnabled(value); } /** * @see #addComponent(java.awt.Component, Object) */ public void removeComponent(java.awt.Component c) { mainWindow.getContentPane().remove(c); } public void showDialogAbout() { final JComponent[] labels = new JComponent[] { new JTextField("Thaw "+Main.VERSION), new JLabel(I18n.getMessage("thaw.about.l02")), new JLabel(I18n.getMessage("thaw.about.l03")), new JLabel(I18n.getMessage("thaw.about.l04")), new JLabel(""), new JLabel(I18n.getMessage("thaw.about.l06")), new JLabel(""), new JLabel(I18n.getMessage("thaw.about.l07")), new JLabel(I18n.getMessage("thaw.about.l08")), new JLabel(I18n.getMessage("thaw.about.l09")), new JLabel(I18n.getMessage("thaw.about.l10")), new JLabel(I18n.getMessage("thaw.about.l11")), new JLabel(I18n.getMessage("thaw.about.l12")), new JLabel(I18n.getMessage("thaw.about.l13")), new JLabel(I18n.getMessage("thaw.about.l14")), new JLabel(I18n.getMessage("thaw.about.l15")) }; for (int i = 0 ; i < labels.length ; i++) { if (labels[i] instanceof JTextField) { ((JTextField)labels[i]).setEditable(false); } } ((JTextField)labels[0]).setFont(new Font("Dialog", Font.BOLD, 30)); JOptionPane.showMessageDialog(null, labels, I18n.getMessage("thaw.about.title"), JOptionPane.INFORMATION_MESSAGE); } public void windowActivated(final WindowEvent e) { } public void windowClosing(final WindowEvent e) { /* Should be in windowClosed(), but doesn't seem to work */ if(e.getSource() == mainWindow) endOfTheWorld(); } public void windowClosed(final WindowEvent e) { // gni } public void windowDeactivated(final WindowEvent e) { // C'est pas comme si on en avait quelque chose a foutre :p } public void windowDeiconified(final WindowEvent e) { // idem } public void windowIconified(final WindowEvent e) { // idem } public void windowOpened(final WindowEvent e) { // idem } }