/* * Licensed Materials - Property of Perforce Software, Inc. * © Copyright Perforce Software, Inc. 2014, 2021 * © Copyright IBM Corp. 2009, 2014 * © Copyright ILOG 1996, 2009 * All Rights Reserved. * * Note to U.S. Government Users Restricted Rights: * The Software and Documentation were developed at private expense and * are "Commercial Items" as that term is defined at 48 CFR 2.101, * consisting of "Commercial Computer Software" and * "Commercial Computer Software Documentation", as such terms are * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4, * as applicable. */ package ganttviewer.viewer; import ganttviewer.viewer.event.CurrentViewChangedEvent; import ganttviewer.viewer.event.CurrentViewListener; import ganttviewer.viewer.exceptions.AttachModelException; import ganttviewer.viewer.exceptions.ViewException; import ganttviewer.views.ResourceUsageView; import ilog.views.gantt.IlvTimeInterval; import ilog.views.gantt.util.event.IlvHashedEventService; import ilog.views.util.event.IlvEventListenerCollection; import ilog.views.util.event.IlvEventListenerSet; import java.awt.CardLayout; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.JPanel; import javax.swing.SwingUtilities; /** * <code>Viewer</code> is used by the demo to display several views. */ SuppressWarnings("serial") public class Viewer extends JPanel { /** * Action instances */ private final Map<String, ViewerAbstractAction> actions = new HashMap<String, ViewerAbstractAction>(); /** * Views. */ private final Map<String, View> views = new HashMap<String, View>(); /** * Views list (to preserve the order) */ private final List<View> viewList = new ArrayList<View>(); /** * Current view. */ private View currentView = null; /** * The model. */ private Object model = null; /** * The event service. */ private IlvHashedEventService eventService; /** * The view listener(s). */ private IlvEventListenerCollection<CurrentViewListener> currentViewListeners; /** * Indicates whether selection is synchronized or not. */ private boolean synchronizedSelection = true; /** * Builds a <code>Viewer</code> */ public Viewer() { super(new CardLayout()); initEventService(); setOpaque(false); } /** * Registers an action. * @param action The action. */ public void registerAction(ViewerAbstractAction action) { actions.put(action.getID(), action); } /** * Unregisters an action. * @param action The action. */ public void unregisterAction(ViewerAbstractAction action) { actions.remove(action.getID()); } /** * Returns an action. * @param actionID The action ID. * @return The action. */ public ViewerAbstractAction getAction(String actionID) { if (!actions.containsKey(actionID)) { return null; } return actions.get(actionID); } /** * Sets the model. * @param model The model. */ public void setModel(Object model) throws AttachModelException { // disables the synchronized selection setSynchronizedSelection(false); deSelectAll(); this.model = model; for (View view : views()) { try { view.setModel(model); } catch (Exception e) { throw new AttachModelException(e); } } // reactivates the synchronized selection setSynchronizedSelection(true); } /** * Internal selection (with view synchronization). * @param obj The object to (de)select. * @param selected The selection status. * @param caller The view at the origin of this call. */ void setSelected(Object obj, boolean selected, View caller) { if (model != null && this.isSynchronizedSelection()) { for (View view : views()) { if ((caller != null) && caller.getID().equals(view.getID())) { continue; } view.setSelected(obj, selected); } } } /** * Activates or disables the synchronized selection. * @param enabled A boolean indicating whether this should be enabled or not. */ private void setSynchronizedSelection(boolean enabled) { synchronizedSelection = enabled; } /** * Indicates whether the synchronized selection is enabled or not. * @return A boolean indicating whether it is enabled or not. */ private boolean isSynchronizedSelection() { return synchronizedSelection; } /** * Selects or deselects an object. * @param obj The object to (de)select. * @param selected The selection status. */ public void setSelected(Object obj, boolean selected) { setSelected(obj, selected, null); } /** * Deselects all objects. * @param caller The view at the origin of this call. */ void deSelectAll(View caller) { if (model != null && isSynchronizedSelection()) { for (View view : views()) { if ((caller != null) && caller.getID().equals(view.getID())) { continue; } view.deSelectAll(); } } } /** * Deselects all objects. * */ public void deSelectAll() { deSelectAll(null); } /** * Returns the model. * @return The model. */ public Object getModel() { return model; } /** * Initializes the event services. */ private void initEventService() { eventService = new IlvHashedEventService(); currentViewListeners = new IlvEventListenerSet<CurrentViewListener>(); } /** * Adds the specified listener to receive notifications when the current view * has been changed. * @param listener The listener that will be subscribed to subsequent view-change event. * @see #removeCurrentViewListener */ public void addCurrentViewListener(CurrentViewListener listener) { currentViewListeners.addListener(listener); } /** * Removes the specified listener to receive notifications when the current * view has been changed. * @param listener The listener that will be unsubscribed from receiving view-change events. * @see #addCurrentViewListener */ public void removeCurrentViewListener(CurrentViewListener listener) { currentViewListeners.removeListener(listener); } /** * Returns the current view. * @return The current view. */ public View getCurrentView() { return currentView; } /** * Indicates whether the given view is set as current. * @param view The view. * @return A boolean indicating whether the view is set as the current one. */ public boolean isCurrentView(View view) { if (getCurrentView() == null) { return false; } return getCurrentView().getID().equals(view.getID()); } /** * Registers a view. * @param view The view. */ void registerView(View view) { if (!views.containsKey(view.getID())) { views.put(view.getID(), view); viewList.add(view); } if (viewList.size() == 1) { // affects a current view currentView = view; } } /** * Sets the current view and notifies listeners * @param currentView The current view. */ public void setCurrentView(View currentView) { View previousView = getCurrentView(); if (currentView == null) { throw new ViewException("Null view set as current"); } // update current view this.currentView = currentView; if (!views.containsKey(currentView.getID())) { throw new ViewException("View " + currentView.getID() + " not registered"); } // Fix JV-6642 SwingUtilities.invokeLater(new Runnable() { Override public void run() { View currentView = getCurrentView(); if (currentView instanceof ResourceUsageView) { ResourceUsageView view = (ResourceUsageView)currentView; IlvTimeInterval chartInterval = view.getScheduleChart().getTimeScale().getVisibleInterval(); IlvTimeInterval sheetInterval = view.getScheduleChart().getGanttSheet().getVisibleInterval(); if (!sheetInterval.equals(chartInterval)) view.getScheduleChart().getGanttSheet().setVisibleInterval(chartInterval.getStart(), chartInterval.getDuration()); } } }); // makes the current view visible ((CardLayout) getLayout()).show(this, currentView.getID()); fireCurrentViewChanged(previousView); currentView.setAsCurrentView(); } /** * Fires a <code>CurrentViewChanged</code> event. * @param previousView The previous view. */ protected void fireCurrentViewChanged(View previousView) { CurrentViewChangedEvent e = new CurrentViewChangedEvent(this, previousView, getCurrentView()); eventService.publish(e); for (Iterator<CurrentViewListener> it = currentViewListeners.getListeners(); it.hasNext();) { CurrentViewListener listener = it.next(); listener.currentViewChanged(e); } } /** * Returns views. * @return The views. */ public Collection<View> views() { return Collections.unmodifiableCollection(this.viewList); } /** * Returns the view identified by this ID. * @param iD The ID. * @return The view or <code>null</code>. */ public View getView(String iD) { if (views.containsKey(iD)) { return views.get(iD); } return null; } }