/* * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package net.java.sip.communicator.impl.gui; import java.awt.*; import java.util.*; import java.util.List; import javax.swing.*; import net.java.sip.communicator.impl.gui.lookandfeel.*; import net.java.sip.communicator.impl.gui.main.*; import net.java.sip.communicator.impl.gui.main.account.*; import net.java.sip.communicator.impl.gui.main.chat.*; import net.java.sip.communicator.impl.gui.main.configforms.*; import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.impl.gui.main.contactlist.addcontact.*; import net.java.sip.communicator.impl.gui.main.login.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.gui.event.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; /** * An implementation of the UIService that gives access to other * bundles to this particular swing ui implementation. * * @author Yana Stamcheva */ public class UIServiceImpl implements UIService { private static final Logger logger = Logger.getLogger(UIServiceImpl.class); private PopupDialogImpl popupDialog; private AccountRegWizardContainerImpl wizardContainer; private Map registeredPlugins = new Hashtable(); private Vector pluginComponentListeners = new Vector(); private static final List supportedContainers = new ArrayList(); static { supportedContainers.add(UIService.CONTAINER_MAIN_TOOL_BAR); supportedContainers.add(UIService.CONTAINER_CONTACT_RIGHT_BUTTON_MENU); supportedContainers.add(UIService.CONTAINER_GROUP_RIGHT_BUTTON_MENU); supportedContainers.add(UIService.CONTAINER_TOOLS_MENU); supportedContainers.add(UIService.CONTAINER_CHAT_TOOL_BAR); supportedContainers.add(UIService.CONTAINER_CALL_HISTORY); } private static final Hashtable exportedWindows = new Hashtable(); private MainFrame mainFrame; private LoginManager loginManager; private ContactListPanel contactListPanel; private ConfigurationFrame configurationFrame; private boolean exitOnClose = true; /** * Creates an instance of UIServiceImpl. */ public UIServiceImpl() {} /** * Initializes all frames and panels and shows the gui. */ public void loadApplicationGui() { this.setDefaultThemePack(); this.mainFrame = new MainFrame(); this.loginManager = new LoginManager(mainFrame); this.contactListPanel = mainFrame.getContactListPanel(); this.popupDialog = new PopupDialogImpl(); this.wizardContainer = new AccountRegWizardContainerImpl(mainFrame); this.configurationFrame = new ConfigurationFrame(mainFrame); mainFrame.setContactList(GuiActivator.getMetaContactListService()); if(ConfigurationManager.isApplicationVisible()) SwingUtilities.invokeLater(new RunApplicationGui()); SwingUtilities.invokeLater(new RunLoginGui()); this.initExportedWindows(); } /** * Implements addComponent in UIService interface. Stores a plugin component * and fires a PluginComponentEvent to inform all interested listeners that * a plugin component has been added. * * @param containerID The ContainerID of the plugable container. * @param component The component to add. * * @see UIService#addComponent(ContainerID, Object) * * @throws java.lang.ClassCastException if component is not an * instance of a java.awt.Component * @throws java.lang.IllegalArgumentException if no component exists for * the specified container id. */ public void addComponent(ContainerID containerID, Object component) throws ClassCastException, IllegalArgumentException { if (!supportedContainers.contains(containerID)) { throw new IllegalArgumentException( "The constraint that you specified is not" + " supported by this UIService implementation."); } else if (!(component instanceof Component)) { throw new ClassCastException( "The specified plugin is not a valid swing or awt component."); } else { if (registeredPlugins.containsKey(containerID)) { ((Vector) registeredPlugins.get(containerID)).add(component); } else { Vector plugins = new Vector(); plugins.add(component); registeredPlugins.put(containerID, plugins); } this.firePluginEvent(component, containerID, PluginComponentEvent.PLUGIN_COMPONENT_ADDED); } } /** * Implements UIService.addComponent(ContainerID, String, Object) * . * For now this method only invokes addComponent(containerID, component). * * @param containerID The ContainerID of the plugable container. * @param constraint a constraint indicating how the component should be * added to the container. * @param component the component we are adding. * * @see UIService#addComponent(ContainerID, String, Object) * @throws java.lang.ClassCastException if component is not an * instance of a java.awt.Component * @throws java.lang.IllegalArgumentException if no component exists for * the specified container id. */ public void addComponent(ContainerID containerID, String constraint, Object component) throws ClassCastException, IllegalArgumentException { this.addComponent(containerID, component); } /** * Implements UIService.addComponent(ContainerID, String, Object) * . * For now this method only invokes addComponent(containerID, component). * * @param containerID The ContainerID of the plugable container. * @param component the component we are adding. * * @throws java.lang.ClassCastException if component is not an * instance of a java.awt.Component * @throws java.lang.IllegalArgumentException if no component exists for * the specified container id. */ public void addComponent(ContainerID containerID, ContactAwareComponent component) throws ClassCastException, IllegalArgumentException { if (!(component instanceof Component)) { throw new ClassCastException( "The specified plugin is not a valid swing or awt component."); } this.addComponent(containerID, (Component) component); } /** * Implements UIService.addComponent(ContainerID, String, Object) * . * For now this method only invokes addComponent(containerID, component). * * @param containerID The ContainerID of the plugable container. * @param constraint a constraint indicating how the component should be * added to the container. * @param component the component we are adding. * * @throws java.lang.ClassCastException if component is not an * instance of a java.awt.Component * @throws java.lang.IllegalArgumentException if no component exists for * the specified container id. */ public void addComponent(ContainerID containerID, String constraint, ContactAwareComponent component) throws ClassCastException, IllegalArgumentException { this.addComponent(containerID, constraint, component); } /** * Implements UISercie.getSupportedContainers. Returns the * list of supported containers by this implementation . * * @see UIService#getSupportedContainers() * @return an Iterator over all supported containers. */ public Iterator getSupportedContainers() { return Collections.unmodifiableList(supportedContainers).iterator(); } /** * Implements getComponentsForConstraint in UIService interface. * * @param containerID the id of the container whose components we'll be * retrieving. * @see UIService#getComponentsForContainer(ContainerID) * * @return an iterator over all components added in the container with ID * containerID * * @throws java.lang.IllegalArgumentException if containerID does not * correspond to a container used in this implementation. */ public Iterator getComponentsForContainer(ContainerID containerID) throws IllegalArgumentException { if (!supportedContainers.contains(containerID)) throw new IllegalArgumentException( "The container that you specified is not " + "supported by this UIService implementation."); Vector plugins = new Vector(); Object o = registeredPlugins.get(containerID); if (o != null) { plugins = (Vector) o; } return plugins.iterator(); } /** * Not yet implemented. * * @param containerID the ID of the container whose constraints we'll be * retrieving. * * @see UIService#getConstraintsForContainer(ContainerID) * * @return Iterator an Iterator for all constraintes supported by * the container corresponding to containerID. */ public Iterator getConstraintsForContainer(ContainerID containerID) { return null; } /** * Creates the corresponding PluginComponentEvent and notifies all * ContainerPluginListeners that a plugin component is added or * removed from the container. * * @param pluginComponent the plugin component that is added to the * container. * @param containerID the containerID that corresponds to the container * where the component is added. * @param eventID one of the PLUGIN_COMPONENT_XXX static fields indicating * the nature of the event. */ private void firePluginEvent(Object pluginComponent, ContainerID containerID, int eventID) { PluginComponentEvent evt = new PluginComponentEvent(pluginComponent, containerID, eventID); logger.trace("Will dispatch the following plugin component event: " + evt); synchronized (pluginComponentListeners) { Iterator listeners = this.pluginComponentListeners.iterator(); while (listeners.hasNext()) { PluginComponentListener l = (PluginComponentListener) listeners .next(); switch (evt.getEventID()) { case PluginComponentEvent.PLUGIN_COMPONENT_ADDED: l.pluginComponentAdded(evt); break; case PluginComponentEvent.PLUGIN_COMPONENT_REMOVED: l.pluginComponentRemoved(evt); break; default: logger.error("Unknown event type " + evt.getEventID()); } } } } /** * Implements isVisible in the UIService interface. Checks if * the main application window is visible. * * @return true if main application window is visible, * false otherwise * @see UIService#isVisible() */ public boolean isVisible() { if (mainFrame.isVisible()) { if (mainFrame.getExtendedState() == JFrame.ICONIFIED) return false; else return true; } else return false; } /** * Implements setVisible in the UIService interface. Shows or * hides the main application window depending on the parameter * visible. * * @param isVisible true if we are to show the main application frame and * false otherwise. * * @see UIService#setVisible(boolean) */ public void setVisible(boolean isVisible) { this.mainFrame.setVisible(isVisible); if(isVisible) this.mainFrame.toFront(); } /** * Implements minimize in the UIService interface. Minimizes * the main application window. * * @see UIService#minimize() */ public void minimize() { this.mainFrame.setExtendedState(JFrame.ICONIFIED); } /** * Implements maximize in the UIService interface. Maximizes * the main application window. * * @see UIService#maximize() */ public void maximize() { this.mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH); } /** * Implements restore in the UIService interface. Restores * the main application window. * * @see UIService#restore() */ public void restore() { if (mainFrame.isVisible()) { if (mainFrame.getState() == JFrame.ICONIFIED) mainFrame.setState(JFrame.NORMAL); mainFrame.toFront(); } else mainFrame.setVisible(true); } /** * Implements resize in the UIService interface. Resizes the * main application window. * * @param height the new height of tha main application frame. * @param width the new width of the main application window. * * @see UIService#resize(int, int) */ public void resize(int width, int height) { this.mainFrame.setSize(width, height); } /** * Implements move in the UIService interface. Moves the main * application window to the point with coordinates - x, y. * * @param x the value of X where the main application frame is to be placed. * @param y the value of Y where the main application frame is to be placed. * * @see UIService#move(int, int) */ public void move(int x, int y) { this.mainFrame.setLocation(x, y); } /** * Implements the UIService.setExitOnMainWindowClose. Sets a * boolean property, which indicates whether the application should be * exited when the main application window is closed. * * @param exitOnClose specifies if closing the main application window * should also be exiting the application. */ public void setExitOnMainWindowClose(boolean exitOnClose) { this.exitOnClose = exitOnClose; if (exitOnClose) mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); else mainFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); } /** * Implements the UIService.getExitOnMainWindowClose. * Returns the boolean property, which indicates whether the application * should be exited when the main application window is closed. * * @return determines whether the UI impl would exit the application when * the main application window is closed. */ public boolean getExitOnMainWindowClose() { return this.exitOnClose; } /** * Adds all ExportedWindows to the list of application windows, * which could be used from other bundles. Once registered in the * UIService this window could be obtained through the * getExportedWindow(WindowID) method and could be shown, * hidden, resized, moved, etc. */ public void initExportedWindows() { AboutWindow aboutWindow = new AboutWindow(mainFrame); AddContactWizard addContactWizard = new AddContactWizard(mainFrame); exportedWindows.put(aboutWindow.getIdentifier(), aboutWindow); exportedWindows.put(configurationFrame.getIdentifier(), configurationFrame); exportedWindows.put(addContactWizard.getIdentifier(), addContactWizard); } /** * Registers the given ExportedWindow to the list of windows that * could be accessed from other bundles. * * @param window the window to be exported */ public void registerExportedWindow(ExportedWindow window) { exportedWindows.put(window.getIdentifier(), window); } /** * Sets the contact list service to this UI Service implementation. * @param contactList the MetaContactList service */ public void setContactList(MetaContactListService contactList) { this.mainFrame.setContactList(contactList); } public void addPluginComponentListener(PluginComponentListener l) { synchronized (pluginComponentListeners) { pluginComponentListeners.add(l); } } public void removePluginComponentListener(PluginComponentListener l) { synchronized (pluginComponentListeners) { pluginComponentListeners.remove(l); } } /** * Implements getSupportedExportedWindows in the UIService * interface. Returns an iterator over a set of all windows exported by * this implementation. * * @return an Iterator over all windows exported by this implementation of * the UI service. * * @see UIService#getSupportedExportedWindows() */ public Iterator getSupportedExportedWindows() { return Collections.unmodifiableMap(exportedWindows).keySet().iterator(); } /** * Implements the getExportedWindow in the UIService * interface. Returns the window corresponding to the given * WindowID. * * @param windowID the id of the window we'd like to retrieve. * * @return a reference to the ExportedWindow instance corresponding * to windowID. * @see UIService#getExportedWindow(WindowID) */ public ExportedWindow getExportedWindow(WindowID windowID) { if (exportedWindows.containsKey(windowID)) { return (ExportedWindow) exportedWindows.get(windowID); } return null; } /** * Implements the UIService.isExportedWindowSupported method. * Checks if there's an exported component for the given * WindowID. * * @param windowID the id of the window that we're making the query for. * * @return true if a window with the corresponding windowID is exported by * the UI service implementation and false otherwise. * * @see UIService#isExportedWindowSupported(WindowID) */ public boolean isExportedWindowSupported(WindowID windowID) { return exportedWindows.containsKey(windowID); } /** * Implements getPopupDialog in the UIService interface. * Returns a PopupDialog that could be used to show simple * messages, warnings, errors, etc. * * @return a PopupDialog that could be used to show simple * messages, warnings, errors, etc. * * @see UIService#getPopupDialog() */ public PopupDialog getPopupDialog() { return this.popupDialog; } /** * Implements getChat in the UIService interface. If a * chat for the given contact exists already - returns it, otherwise * creates a new one. * * @param contact the contact that we'd like to retrieve a chat window for. * * @return a Chat corresponding to the specified contact. * * @see UIService#getChat(Contact) */ public Chat getChat(Contact contact) { MetaContact metaContact = mainFrame.getContactList() .findMetaContactByContact(contact); ChatWindowManager chatWindowManager = mainFrame.getChatWindowManager(); ChatPanel chatPanel = chatWindowManager.getContactChat(metaContact); return chatPanel; } /** * Returns the selected Chat. * * @return the selected Chat. */ public Chat getCurrentChat() { ChatWindowManager chatWindowManager = mainFrame.getChatWindowManager(); return chatWindowManager.getSelectedChat(); } /** * Implements the UIService.isContainerSupported method. * Checks if the plugable container with the given ContainerID is supported * by this implementation. * * @param containderID the id of the container that we're making the query * for. * * @return true if the container with the specified id is exported by the * implementation of the UI service and false otherwise. * * @see UIService#isContainerSupported(ContainerID) */ public boolean isContainerSupported(ContainerID containderID) { return supportedContainers.contains(containderID); } /** * Implements the UIService.getAccountRegWizardContainer * method. Returns the current implementation of the * AccountRegistrationWizardContainer. * * @see UIService#getAccountRegWizardContainer() * * @return a reference to the currently valid instance of * AccountRegistrationWizardContainer. */ public AccountRegistrationWizardContainer getAccountRegWizardContainer() { return this.wizardContainer; } /** * Implements the UIService.getConfigurationWindow. Returns * the current implementation of the ConfigurationWindow * interface. * * @see UIService#getConfigurationWindow() * * @return a reference to the currently valid instance of * ConfigurationWindow. */ public ConfigurationWindow getConfigurationWindow() { return this.configurationFrame; } public ExportedWindow getAuthenticationWindow( ProtocolProviderService protocolProvider, String realm, UserCredentials userCredentials) { return new AuthenticationWindow(mainFrame, protocolProvider, realm, userCredentials); } /** * Returns the LoginManager. * @return the LoginManager */ public LoginManager getLoginManager() { return loginManager; } /** * Returns the MainFrame. This is the class defining the main * application window. * * @return the MainFrame */ public MainFrame getMainFrame() { return mainFrame; } /** * The RunLogin implements the Runnable interface and is used to * shows the login windows in a seperate thread. */ private class RunLoginGui implements Runnable { public void run() { loginManager.runLogin(mainFrame); } } /** * The RunApplication implements the Runnable interface and is used to * shows the main application window in a separate thread. */ private class RunApplicationGui implements Runnable { public void run() { mainFrame.setVisible(true); } } /** * Sets the look&feel and the theme. */ private void setDefaultThemePack() { SIPCommLookAndFeel lf = new SIPCommLookAndFeel(); SIPCommLookAndFeel.setCurrentTheme(new SIPCommDefaultTheme()); // we need to set the UIDefaults class loader so that it may access // resources packed inside OSGI bundles UIManager.put("ClassLoader", getClass().getClassLoader()); try { UIManager.setLookAndFeel(lf); } catch (UnsupportedLookAndFeelException e) { logger.error("The provided Look & Feel is not supported.", e); } } }