package jadex.tools.jcc; import jadex.base.gui.AboutDialog; import jadex.base.gui.JadexLogoButton; import jadex.base.gui.StatusBar; import jadex.base.gui.plugin.IControlCenterPlugin; import jadex.commons.BrowserLauncher; import jadex.commons.SUtil; import jadex.commons.concurrent.SwingDefaultResultListener; import jadex.commons.service.SServiceProvider; import jadex.commons.service.library.ILibraryService; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Box; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileFilter; import javax.swing.plaf.basic.BasicSplitPaneDivider; import javax.swing.plaf.basic.BasicSplitPaneUI; /** * The main window of the control center. */ public class ControlCenterWindow extends JFrame { //-------- constants -------- /** The dimension for toolbar buttons. */ protected static final Dimension BUTTON_DIM = new Dimension(32, 32); //-------- attributes -------- /** The control center. */ protected ControlCenter controlcenter; /** The file chooser. */ protected final JFileChooser filechooser; /** The current perspective. */ protected IControlCenterPlugin currentperspective; /** The layout. */ protected CardLayout clayout; /** The content. */ protected JPanel content; /** The status bar. */ protected StatusBar statusbar; /** The tool bar. */ protected JToolBar toolbar; //protected JToolBar lasttoolbar; // toolbar of last selected plugin (removed buttons will be readded when plugin is switched) /** The tool count. */ protected int toolcnt; /** A splitpane for?. */ protected JSplitPane sp; /** The console. */ protected ConsolePanel console; /** Map for console heights (plugin name -> height). */ protected Map consoleheights; //-------- constructors -------- /** * Create a new control center window. */ public ControlCenterWindow(ControlCenter main) { this.controlcenter = main; this.consoleheights = new HashMap(); getContentPane().setLayout(new BorderLayout()); clayout = new CardLayout(); content = new JPanel(clayout); this.console = new ConsolePanel(); console.setConsoleEnabled(false); this.sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT); sp.setOneTouchExpandable(true); sp.setDividerLocation(200); content.setMinimumSize(new Dimension(0,0)); console.setMinimumSize(new Dimension(0,0)); sp.add(content); sp.add(console); getContentPane().add("Center", sp); sp.setResizeWeight(1.0); statusbar = new StatusBar(); getContentPane().add("South", statusbar); this.filechooser = new JFileChooser("."); filechooser.setFileFilter(new FileFilter() { public boolean accept(File f) { return f.isDirectory() || f.getName().toLowerCase().endsWith(".jccproject.xml"); } public String getDescription() { return "Jadex Project Files"; } }); //BasicSplitPaneDivider.OneTouchActionHandler setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { console.close(); if(controlcenter.exit()) { dispose(); setVisible(false); } } }); } /** * Create a toolbar containing the given tools (if any). * @param template Conta */ protected void changeToolBar(JComponent[] template, IControlCenterPlugin selplugin) { // Setup the tool bar. if(toolbar==null) { toolbar = new JToolBar("Main Toolbar"); getContentPane().add(BorderLayout.NORTH, toolbar); // Add standard entries (after gap). toolbar.add(Box.createGlue()); toolcnt++; toolbar.addSeparator(); toolcnt++; //ButtonGroup bg = new ButtonGroup(); IControlCenterPlugin[] plugins = controlcenter.getPlugins(); for(int i=0; i<plugins.length; i++) { final IControlCenterPlugin plugin = plugins[i]; //final JToggleButton button = new JToggleButton(new PluginAction(plugins[i])); final JButton button = new JButton(new PluginAction(plugins[i])); Icon ic = plugin.getToolIcon(selplugin.getName().equals(plugins[i].getName())); if(ic!=null) button.setIcon(ic); else button.setText(plugins[i].getName()); button.setText("A"); button.putClientProperty("plugin", plugins[i]); button.setBorder(null); button.setText(null); button.setMinimumSize(BUTTON_DIM); button.setHorizontalAlignment(SwingConstants.CENTER); button.setVerticalAlignment(SwingConstants.CENTER); button.setToolTipText(plugins[i].getName()); button.getModel().addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { //System.out.println(plugin.getName()+" :"+button.isSelected()); button.setIcon(plugin.getToolIcon(button.isSelected())); } }); // if(plugins[i].getHelpID()!=null) // SHelp.setupHelp(button, plugins[i].getHelpID()); //bg.add(button); toolbar.add(button); toolcnt++; } toolbar.addSeparator(); toolcnt++; toolbar.add(new JadexLogoButton(toolbar)); toolcnt++; } else { while(toolbar.getComponentCount()>toolcnt) { // Component comp = toolbar.getComponent(0); toolbar.remove(0); //if(lasttoolbar!=null) // lasttoolbar.add(comp); } } for(int i=0; template!=null && i<template.length; i++) toolbar.add(template[i], i); //lasttoolbar = template; // Select plugins for(int i=0; i<toolbar.getComponentCount(); i++) { JComponent comp = (JComponent)toolbar.getComponent(i); if(comp.getClientProperty("plugin")!=null) { IControlCenterPlugin pl = (IControlCenterPlugin)comp.getClientProperty("plugin"); ((JButton)comp).setIcon(pl.getToolIcon(pl.equals(selplugin))); //((JToggleButton)comp).setSelected(pluginname.equals(comp.getClientProperty("pluginname"))); } } toolbar.validate(); toolbar.repaint(); // If toolbar has been dropped out -> pack the window (hack???). Container root = toolbar; while(root.getParent()!=null && !(root instanceof Window)) root = root.getParent(); if(root!=null && !(root instanceof JFrame)) { ((Window)root).pack(); } } /** * Create a menubar containing the given menus (if any). */ protected JMenuBar createMenuBar(JMenu[] pluginbar) { // Create the menu-bar if nec essary. JMenuBar menubar = new JMenuBar(); // File menu. JMenu file = new JMenu("File"); file.add(new JMenuItem(NEW_PROJECT)); file.add(new JMenuItem(OPEN_PROJECT)); file.addSeparator(); file.add(new JMenuItem(SAVE_PROJECT)); file.add(new JMenuItem(SAVE_PROJECT_AS)); file.addSeparator(); // file.add(new JMenuItem(SETTINGS)); // file.addSeparator(); file.add(new JMenuItem(EXIT)); menubar.add(file, 0); // prepend "File" menu. // Help menu. JMenu help = new JMenu("Help"); // HelpBroker hb = SHelp.setupHelp(this.getContentPane(), "tools.controlcenter"); // if(hb!=null) // { // JMenuItem helptopics = new JMenuItem("Help Topics"); // helptopics.addActionListener(new CSH.DisplayHelpFromSource(hb)); // // JMenuItem helptrack = new JMenuItem(new ImageIcon(ControlCenter.class // .getResource("/jadex/tools/common/images/help.png"), "Help cursor")); // // helptrack.addActionListener(new CSH.DisplayHelpAfterTracking(hb)); // // help.add(helptopics); // help.add(helptrack); // } help.add(new JMenuItem(ONLINE_DOC)); help.add(new JMenuItem(ABOUT)); menubar.add(help); for(int i=0; pluginbar!=null && i<pluginbar.length; i++) menubar.add(pluginbar[i], i+1); return menubar; } /** * This method may only be called from the swing thread */ protected void setPerspective(IControlCenterPlugin plugin) { if(plugin!=null && plugin!=currentperspective) { IControlCenterPlugin oldperspective = currentperspective; currentperspective = plugin; // Save console height of old perspective if(oldperspective!=null) consoleheights.put(oldperspective.getName()+".console.height", new Integer(getConsoleHeight())); // Set console height of new perspective Integer ch = (Integer)consoleheights.get(currentperspective.getName()+".console.height"); //System.out.println("Found: "+ch); if(ch!=null) setConsoleHeight(ch.intValue()); else setConsoleHeight(0); //System.out.println(consoleheights+" "+ch); try { // Get menu and toolbar before setting to avoid inconsistent state on error in plugin. JMenu[] menu = plugin.getMenuBar(); JComponent[] tool = plugin.getToolBar(); setJMenuBar(createMenuBar(menu)); changeToolBar(tool, plugin); clayout.show(content, plugin.getName()); validate(); repaint(); } catch(RuntimeException e) { System.err.println("Error in plugin " + plugin.getName()); e.printStackTrace(); // Restore perspective. if(oldperspective != null) { setPerspective(oldperspective); } // When no perspective: // Fallback to empty plugin. else { setJMenuBar(createMenuBar(null)); changeToolBar(null, plugin); clayout.show(content, plugin.getName()); validate(); repaint(); } } } } /** * Get the status bar. */ public StatusBar getStatusBar() { return statusbar; } /** * @return current perspective */ public IControlCenterPlugin getPerspective() { return currentperspective; } /** * Get the center split position. */ public int getCenterSplit() { return sp.getDividerLocation(); } /** * Set the center split position. * @param pos The position (-1 for max). */ public void setCenterSplit(int pos) { if(pos==-1) pos = sp.getMaximumDividerLocation(); sp.setDividerLocation(pos); } /** * Set the console enable state. * @param enabled The enabled state. */ public void setConsoleEnabled(boolean enabled) { console.setConsoleEnabled(enabled); } /** * Test if the console is enabled. * @return True, if enabled. */ public boolean isConsoleEnabled() { return console.isConsoleEnabled(); } /** * Show the console. * (Code simultes a one touch expanable click programmatically, * see BasicSplitPaneDivider.OneTouchActionHandler) */ public void showConsole(boolean show) { boolean shown = isConsoleShown(); //System.out.println(show+" "+shown); Insets insets = sp.getInsets(); int lastloc = sp.getLastDividerLocation(); int currentloc = sp.getUI().getDividerLocation(sp); int newloc = currentloc; BasicSplitPaneDivider divider = ((BasicSplitPaneUI)sp.getUI()).getDivider(); if(show && !shown) { if(currentloc >= (sp.getHeight() - insets.bottom - divider.getHeight())) { int maxloc = sp.getMaximumDividerLocation(); newloc = lastloc<maxloc? lastloc: maxloc*2/3; } } else if(!show && shown) { newloc = sp.getMaximumDividerLocation(); } if(currentloc != newloc) { sp.setDividerLocation(newloc); sp.setLastDividerLocation(currentloc); } /*if(show) { if(sp.getOrientation() == JSplitPane.VERTICAL_SPLIT) { if(currentLoc >= (sp.getHeight() - insets.bottom - divider.getHeight())) { int maxLoc = sp.getMaximumDividerLocation(); newLoc = Math.min(lastLoc, maxLoc); //((BasicSplitPaneUI)sp.getUI()).setKeepHidden(false); } /*else { newLoc = insets.top; //sp.setKeepHidden(true); }* / } else { if(currentLoc >= (sp.getWidth() - insets.right - divider.getWidth())) { int maxLoc = sp.getMaximumDividerLocation(); newLoc = Math.min(lastLoc, maxLoc); //sp.setKeepHidden(false); } /*else { newLoc = insets.left; //splitPaneUI.setKeepHidden(true); }* / } } else { if(sp.getOrientation() == JSplitPane.VERTICAL_SPLIT) { if(currentLoc == insets.top) { int maxLoc = sp.getMaximumDividerLocation(); newLoc = Math.min(lastLoc, maxLoc); //sp.getUI().setKeepHidden(false); } /*else { newLoc = sp.getHeight() - divider.getHeight() - insets.top; //splitPaneUI.setKeepHidden(true); }* / } else { if(currentLoc == insets.left) { int maxLoc = sp.getMaximumDividerLocation(); newLoc = Math.min(lastLoc, maxLoc); //splitPaneUI.setKeepHidden(false); } /*else { newLoc = sp.getWidth() - divider.getWidth() - insets.left; //splitPaneUI.setKeepHidden(true); }* / } }*/ } /** * Test if console is shown. */ public boolean isConsoleShown() { return getConsoleHeight() != 0; } /** * Set the console height. * @param height The console height. */ public void setConsoleHeight(final int height) { //System.out.println("old: "+sp.getDividerLocation()); sp.setDividerLocation(sp.getMaximumDividerLocation()- height); //System.out.println("new: "+sp.getDividerLocation()); } /** * Get the console height. * @return The console height. */ public int getConsoleHeight() { return sp.getMaximumDividerLocation() - sp.getDividerLocation(); } /** * Get the console heights. */ public Map getConsoleHeights() { return consoleheights; } //-------- project management -------- /** * Save the current project. * If no project is selcted, will ask for filename for new poroject. */ protected void saveProject() { if(controlcenter.hasProject()) { controlcenter.saveProject(); } else { saveProjectAs(); } } /** * Save the current project settings. * Asks the user for a project file name. * @param usename Use the last name as default? */ protected void saveProjectAs() { if(filechooser.showDialog(this, "Save Project As")==JFileChooser.APPROVE_OPTION) { final File f = filechooser.getSelectedFile(); SwingUtilities.invokeLater(new Runnable() { public void run() { File file = f; if(file!=null) { if(file.exists()) { String msg = SUtil.wrapText("The file: "+file.getAbsolutePath()+" exists.\n"+ " Do you want to overwrite the file?"); int o = JOptionPane.showConfirmDialog(ControlCenterWindow.this, msg, "Overwrite Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if(JOptionPane.NO_OPTION==o) return; } else if(!file.getName().toLowerCase().endsWith(ControlCenter.JCCPROJECT_EXTENSION)) { file = new File(file.getAbsolutePath()+ControlCenter.JCCPROJECT_EXTENSION); filechooser.setSelectedFile(file); } try { file.createNewFile(); } catch(IOException e) { } if(file.canWrite()) { controlcenter.setCurrentProject(file); controlcenter.saveProject(); } else { JOptionPane.showMessageDialog(ControlCenterWindow.this, "Cannot save project here. The project file: \n" +file.getAbsolutePath()+"\n cannot be written", "New Project Error",JOptionPane.ERROR_MESSAGE); } } } }); } } /** * Open a project. * Asks the user for a project file name. */ protected void openProject() { if(filechooser.showDialog(this, "Open Project")==JFileChooser.APPROVE_OPTION) { final File file = filechooser.getSelectedFile(); SServiceProvider.getService(controlcenter.getServiceProvider(), ILibraryService.class) .addResultListener(new SwingDefaultResultListener(ControlCenterWindow.this) { public void customResultAvailable(Object source, Object result) { ClassLoader cl = ((ILibraryService)result).getClassLoader(); boolean canopen = file!=null && file.canWrite() && file.getName().toLowerCase().endsWith(ControlCenter.JCCPROJECT_EXTENSION); if(canopen) { controlcenter.saveProject(); controlcenter.closeProject(); try { controlcenter.openProject(file, cl);//, true); } catch(Exception e) { canopen = false; } } if(!canopen) { SwingUtilities.invokeLater(new Runnable() { public void run() { String msg = SUtil.wrapText("Cannot open the project from file:\n"+file); JOptionPane.showMessageDialog(ControlCenterWindow.this, msg, "Cannot open the project", JOptionPane.ERROR_MESSAGE); } }); } } }); } } //-------- menu actions -------- final Action EXIT = new AbstractAction("Exit") { public void actionPerformed(ActionEvent e) { controlcenter.exit(); } }; final Action SAVE_PROJECT = new AbstractAction("Save Project") { public void actionPerformed(ActionEvent e) { saveProject(); } }; final Action SAVE_PROJECT_AS = new AbstractAction("Save Project As...") { public void actionPerformed(ActionEvent e) { saveProjectAs(); } }; final Action OPEN_PROJECT = new AbstractAction("Open Project...") { public void actionPerformed(ActionEvent e) { openProject(); } }; final Action NEW_PROJECT = new AbstractAction("New Project") { public void actionPerformed(ActionEvent e) { controlcenter.saveProject(); controlcenter.closeProject(); } }; final Action ABOUT = new AbstractAction("About...") { public void actionPerformed(ActionEvent ae) { new AboutDialog(ControlCenterWindow.this); } }; final Action ONLINE_DOC = new AbstractAction("WWW...") { public void actionPerformed(ActionEvent ae) { try { BrowserLauncher.openURL("http://jadex-agents.informatik.uni-hamburg.de/xwiki/bin/view/Resources/Online+Documentation"); } catch(IOException e) { } } }; // final AbstractAction SETTINGS = new AbstractAction("Settings...") // { // public void actionPerformed(ActionEvent ae) // { // JDialog f = new ConfigurationDialog(ControlCenterWindow.this); // f.pack(); // Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); // int centerx = (int)size.getWidth()/2; // int centery = (int)size.getHeight()/2; // f.setLocation(centerx-f.getWidth()/2, centery-f.getHeight()/2); // f.setVisible(true); // } // }; /** * Toolbar action for activating a plugin. */ class PluginAction extends AbstractAction { final IControlCenterPlugin plugin; /** * Constructor for PluginAction. * @param plugin */ public PluginAction(IControlCenterPlugin plugin) { super(plugin.getName()); this.plugin = plugin; } /** * @param e * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent e) { controlcenter.activatePlugin(plugin); } } }