Package vg.modules.desktop

Source Code of vg.modules.desktop.DesktopPanel

package vg.modules.desktop;

import java.awt.BorderLayout;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import vg.core.AUserInterfaceElement;
import vg.core.IGraphView;
import vg.core.VisualGraph;
import vg.core.event.AUIEvent;
import vg.core.event.UIEventChangeView;
import vg.core.event.UIEventCloseTab;
import vg.core.event.UIEventCreateNewConnection;
import vg.core.event.UIEventDeleteConnection;
import vg.core.event.UIEventOpenNewGraph;
import vg.core.event.UIEventOpenNewTab;
import vg.core.plugin.PluginParameter;
import vg.core.request.AUIRequest;
import vg.core.request.EUIRequestType;
import vg.core.request.IUIRequestOwner;
import vg.core.request.UIRequestCloseTab;
import vg.core.request.UIRequestOpenSubGraph;
import vg.core.request.UIRequestReplaceCurrentTab;
import vg.core.request.UIRequestSelectTab;
import vg.core.storableGraph.StorableSubGraph;
import vg.userInterface.core.GraphView;
import vg.userInterface.swingComponents.SimpleTabWithCloseButton;

/**
* This class realizes desktop.
* @author tzolotuhin
*/
public class DesktopPanel extends AUserInterfaceElement {
  private static AtomicInteger counterId = new AtomicInteger(0);
  // Components
  private JPanel view;
  private JTabbedPane tabs;
  // Main data
  private final List<Connection> connections;
  private final PluginParameter parameter;
  private final Map<Integer, String> comTabIdAndTabTitle;
  private Map<Integer, Integer> comTabIdAndTab;
  private final Map<Integer, IGraphView> comTabIdAndGraphView;
  // Additional data
  private final Map<String, ArrayList<Integer>> tabTitleStatistic;//statistic of titles
  // Mutex
  private final Object theMutexObject;
  /**
   * Constructor.
   */
  public DesktopPanel(final PluginParameter param) {   
    super("Desktop", null);
    // init mutex
    this.theMutexObject = new Object();
    // init main data
    this.parameter = param;
    this.connections = new ArrayList<Connection>();
    this.comTabIdAndTabTitle = new HashMap<Integer, String>();
    this.comTabIdAndTab = new HashMap<Integer, Integer>();
    this.comTabIdAndGraphView = new HashMap<Integer, IGraphView>();
    // init additional data
    this.tabTitleStatistic = new HashMap<String, ArrayList<Integer>>();
    // init components
    if(SwingUtilities.isEventDispatchThread()) {
      init();
    } else {
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          synchronized (theMutexObject) {
            init()
          }
        }
      });
    }
  }
  /**
   * This method returns component which represent desktop.
   */
  public void update(Observable o, Object arg) {
    synchronized (this.theMutexObject) {
      if(arg instanceof AUIEvent) {
        AUIEvent event = (AUIEvent)arg;
        switch(event.getType()) {
          case DEF_OPEN_NEW_GRAPH:
          {
            UIEventOpenNewGraph bufEvent = (UIEventOpenNewGraph)event;
            Integer graphId = bufEvent.getGraphId();
            Date d = new Date();
            StorableSubGraph ssg = this.parameter.model.getRootStorableSubGraph(graphId);
            VisualGraph.log.printInfo("[" + this.getClass().getName() + ".update] Root subGraph select time: " + (new Date().getTime() - d.getTime()) / 1000.0 + "sec");
            if(ssg != null) {
              IGraphView graphView =  GraphView.newGraphView(ssg, DesktopPanel.this.parameter.userInterface);
                  addTab(graphView.getTitle(), graphView);                           
            } else {
              VisualGraph.log.printError("[" + this.getClass().getName() + ".update] Desktop. Openning of root subgraph(DEF_OPEN_NEW_GRAPH). GraphId = " + graphId.toString());
            }
            break;
          }
          case DEF_CREATE_NEW_CONNECT:
          {
            UIEventCreateNewConnection bufEvent = (UIEventCreateNewConnection)event;
            addNewConnect(bufEvent.getConnectionId(), bufEvent.getConnectionName(), bufEvent.getGraphId(), bufEvent.getAnchor());
            break;
          }
          case DEF_DELETE_CONNECT:
          {
            UIEventDeleteConnection bufEvent = (UIEventDeleteConnection)event;
            removeConnect(bufEvent.getConnectId());
            break;
          }
          case DEF_CHANGE_UI_STYLE:
          {
            updateUITheme();
            break;
          }
          case DEF_RESET:
          {
            this.connections.clear();
            this.comTabIdAndTabTitle.clear();
            this.comTabIdAndTab.clear();
            this.comTabIdAndGraphView.clear();
            this.tabTitleStatistic.clear();
            this.tabs.removeAll();
           
            break;
          }
        }
      } else if(arg instanceof AUIRequest) {
        AUIRequest request = (AUIRequest)arg;
        switch(request.getType()) {
          case DEF_CLOSE_CURRENT_TAB:
          {
            // call request owner method (PROCESS REQUEST)
            IUIRequestOwner bufOwner = request.getOwner();
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.PROCESS, null) {});
            }
            // execute query
            int index = this.tabs.getSelectedIndex();
            if(index >= 0) {
              for(Integer buf : this.comTabIdAndTab.keySet()) {
                Integer value = this.comTabIdAndTab.get(buf);
                if(value != null && value.equals(index)) {
                  closeTab(buf);
                  break;
                }
              }
            }
            // call request owner method (OK REQUEST)
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.OK, null) {});
            }
            break;
          }
          case DEF_CLOSE_TAB: {
            // call request owner method (PROCESS REQUEST)
            IUIRequestOwner bufOwner = request.getOwner();
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.PROCESS, null) {});
            }
            // execute query
            UIRequestCloseTab req = (UIRequestCloseTab)request;
            Set<Integer>tabSet = req.getTabSet();
            if(tabSet != null) {
              for(Integer buf : tabSet) {
                closeTab(buf);
              }
            }
            // call request owner method (OK REQUEST)
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.OK, null) {});
            }
            break;
          }
          case DEF_OPEN_SUB_GRAPH:
          {
            // call request owner method (PROCESS REQUEST)
            IUIRequestOwner bufOwner = request.getOwner();
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.PROCESS, null) {});
            }
            // execute query
            UIRequestOpenSubGraph req = (UIRequestOpenSubGraph)request;
            final IGraphView igv = req.getSubGraphView();
            SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                if(igv != null) {
                  addTab(igv.getTitle(), igv);
                }         
              }
            });
            // call request owner method (OK REQUEST)
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.OK, null) {});
            }
            break;
          }
          case DEF_SELECT_TAB:
          {
            // call request owner method (PROCESS REQUEST)
            IUIRequestOwner bufOwner = request.getOwner();
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.PROCESS, null) {});
            }
            // execute query
            UIRequestSelectTab req = (UIRequestSelectTab)request;
            final Integer tabId = req.getTabId();
            // find tab
            SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                tabs.setSelectedIndex(DesktopPanel.this.comTabIdAndTab.get(tabId));
              }
            });
            // call request owner method (OK REQUEST)
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.OK, null) {});
            }
            break;
          }
          case DEF_REPLACE_CURRENT_TAB:
          {
            // call request owner method (PROCESS REQUEST)
            IUIRequestOwner bufOwner = request.getOwner();
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.PROCESS, null) {});
            }
            // execute query
            UIRequestReplaceCurrentTab req = (UIRequestReplaceCurrentTab)request;
            int index = this.tabs.getSelectedIndex();
            if(index >= 0) {
              for(Integer buf : this.comTabIdAndTab.keySet()) {
                Integer value = this.comTabIdAndTab.get(buf);
                if(value != null && value.equals(index)) {
                  closeTab(buf);
                  IGraphView igv = req.getSubGraphView();
                  if(igv != null) {
                    addTab(igv.getTitle(), igv);
                  }
                  break;
                }
              }
            }
            // call request owner method (OK REQUEST)
            if(bufOwner != null) {
              bufOwner.callRequestOwner(new AUIRequest(EUIRequestType.OK, null) {});
            }
            break;
          }         
        }
      }
    }
  };
  public JComponent getView() {
    return(this.view);
  }
  ///////////////////////////////////////////////////////////////////////////
  // PRIVATE METHODS
  ///////////////////////////////////////////////////////////////////////////
  /**
   * Init swing components.
   */
  private void init() {
    this.view = new JPanel(new BorderLayout());
    this.tabs = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
    this.view.add(this.tabs, BorderLayout.CENTER);
      this.tabs.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        int index = tabs.getSelectedIndex();
        if(index >= 0) {
          for(Integer buf : comTabIdAndTab.keySet()) {
            if((int)comTabIdAndTab.get(buf) == index) {
              UIEventChangeView event = new UIEventChangeView(buf, comTabIdAndGraphView.get(buf));
              parameter.userInterface.addEvent(event);
              break;
            }
          }   
        } else {
          //if all tabs close
          UIEventChangeView event = new UIEventChangeView(-1, null);
          parameter.userInterface.addEvent(event);         
        }
      }
    });
    // ctrl-tab and ctrl-shift-tab
    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {         
      public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getID() == KeyEvent.KEY_PRESSED &&  e.getKeyCode() == KeyEvent.VK_TAB && e.isControlDown()) {
          int tabcount = tabs.getTabCount();
          if (tabcount > 0) {
            int sel = tabs.getSelectedIndex();
            if (e.isShiftDown()) {
              sel = sel - 1;
              if (sel < 0)
                sel = tabcount - 1;
            } else {
              sel = sel + 1;
              if (sel >= tabcount)
                sel = 0;
            }
            tabs.setSelectedIndex(sel);
          }
          return(true);
        }
        return(false);
      }
    });
  }
  /**
   * This method adds new connect to each graph view.
   */
  private void addNewConnect(final int connectId, final String connectName, final int graphId, final String anchor) {
    for(IGraphView buf : this.comTabIdAndGraphView.values()) {
      buf.addNewConnect(connectId, connectName, anchor, graphId);
    }
    this.connections.add(new Connection(connectId, connectName, graphId, anchor));
  }
  /**
   * This method removes exist connect from each graph view.
   */
  private void removeConnect(final int connectId) {
    for(IGraphView buf : this.comTabIdAndGraphView.values()) {
      buf.removeConnect(connectId);
    }
    for(Connection buf : this.connections) {
      if(buf.getConnectId() == connectId) {
        this.connections.remove(buf);
        break;
      }
    }
  }
  /**
   * This method adds new tab on the desktop.
   * @param title - title of the tab.
   * @param graphView - view of graph, which we want open in new tab.
   */
  private void addTab(final String title, final IGraphView graphView) {
    String localTitle = title;
    ArrayList<Integer>array = DesktopPanel.this.tabTitleStatistic.get(title);
    String renamingTitle = null;
    int renamingId = -1;
    if(array == null) {
      array = new ArrayList<Integer>();
      array.add(0);
      DesktopPanel.this.tabTitleStatistic.put(title, array);
    } else {
      if(array.size() == 1 && array.get(0) == 0) {
        // renaming of existing tab
        array.remove(0);
        for(int i = 0 ; i < this.tabs.getTabCount(); i++) {
          if(this.tabs.getTitleAt(i).equals(title)) {
            renamingTitle = buildTabTitle(title, 1);
            renamingId = i;
            break;
          }
        }
        array.add(1);
      }
      // find free index
      int index = 1; // without zero
      for(int i = 0 ; i < array.size() ; i++) {
        if(!array.contains(index)) {
          break;
        }
        index++;
      }
      array.add(index);
      localTitle = buildTabTitle(localTitle, index);
    }
    // add connections
    for(Connection buf : DesktopPanel.this.connections) {
      graphView.addNewConnect(buf.getConnectId(), buf.getConnectName(), buf.getAnchor(), buf.getGraphId());
    }
    // add information about new tab to data
    int tabId = getNextId(); // get new id
    this.comTabIdAndGraphView.put(tabId, graphView);
    this.comTabIdAndTab.put(tabId, this.tabs.getTabCount());
    this.comTabIdAndTabTitle.put(tabId, title);
    // send event
    UIEventOpenNewTab event = new UIEventOpenNewTab(tabId, localTitle, graphView);
    this.parameter.userInterface.addEvent(event);
    // update ui and add new component
    if(SwingUtilities.isEventDispatchThread()) {
      localAddTab(renamingTitle, renamingId, localTitle, graphView.getGraphRepresentation());
    } else {
      final String finalTitle = localTitle;
      final int finalRenamingId = renamingId;
      final String finalRenamingTitle = renamingTitle;
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          synchronized (theMutexObject) {
            localAddTab(finalRenamingTitle, finalRenamingId, finalTitle, graphView.getGraphRepresentation());
          }
        }
      });
    }
  }
  private void localAddTab(String renamingTitle, int renamingId, String title, JComponent graphRepresentation) {
    if(renamingTitle != null) {
      this.tabs.setTitleAt(renamingId, renamingTitle);
    }
    this.tabs.addTab(title, graphRepresentation);
    // add close button
    this.tabs.setTabComponentAt(DesktopPanel.this.tabs.getTabCount() - 1, new SimpleTabWithCloseButton(tabs, new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        synchronized (theMutexObject) {
          int index = tabs.indexOfTabComponent((SimpleTabWithCloseButton)e.getSource());
          if(index >= 0) {
            for(Integer buf : comTabIdAndTab.keySet()) {
              Integer value = comTabIdAndTab.get(buf);
              if(value != null && value.equals(index)) {
                closeTab(buf);
                break;
              }
            }
          }
        }
      }
    }));
    this.tabs.setSelectedIndex(this.tabs.getTabCount() - 1);   
  }
  /**
   * This method closes tab.
   * @param id - id of tab.
   */
  private void closeTab(int id) {
    final int index = comTabIdAndTab.get(id);
    if(index < 0) return;
    String shortFileName = this.comTabIdAndTabTitle.get(id);
    String tabTitle = this.tabs.getTitleAt(index);
    // clear tab statistic
    ArrayList<Integer>array = this.tabTitleStatistic.get(shortFileName);
    if(array != null) {
      for(Integer bufInner : array) {
        String title = buildTabTitle(shortFileName, bufInner);
        if(title.equals(tabTitle)) {
          array.remove(bufInner);
          break;
        }
      }
      if(array.size() == 0) {
        this.tabTitleStatistic.remove(shortFileName);
      }
    }
    // clear compositions
    this.comTabIdAndTabTitle.remove(id);
    this.comTabIdAndGraphView.remove(id);
    this.comTabIdAndTab.remove(id);
    // change next tab index
    Map<Integer, Integer>bufMap = new HashMap<Integer, Integer>();
    for(Integer bufInner : DesktopPanel.this.comTabIdAndTab.keySet()) {
      Integer val = DesktopPanel.this.comTabIdAndTab.get(bufInner);
      if((int)val > index) {
        bufMap.put(bufInner, val - 1);
      } else {
        bufMap.put(bufInner, val);
      }
    }
    this.comTabIdAndTab = bufMap;
    // create and send event
    if(this.parameter != null && this.parameter.userInterface != null) {
      UIEventCloseTab event = new UIEventCloseTab(id);
      this.parameter.userInterface.addEvent(event);
    }
    // update ui
    if(SwingUtilities.isEventDispatchThread()) {
      this.tabs.remove(index);     
      this.view.updateUI();
    } else {
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          synchronized (theMutexObject) {
            tabs.remove(index);
            view.updateUI();           
          }
        }
      });     
    }
  }
  private void updateUITheme() {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        synchronized (DesktopPanel.this.theMutexObject) {         
          SwingUtilities.updateComponentTreeUI(DesktopPanel.this.view);
        }
      }
    });
  }
  private String buildTabTitle(final String title, final int number) {
    if(number <= 0) return(title);
    return(title + ":" + number);
  }
  /**
   * This method returns next id for tab.
   */
  private int getNextId() {
    int a = counterId.incrementAndGet();
    return(a);
  }
  ///////////////////////////////////////////////////////////////////////////
  // PRIVATE CLASSES
  ///////////////////////////////////////////////////////////////////////////
  /**
   * Bean, witch contains information about connection of graph and AIF.
   */
  private static class Connection {
    private final int connectId;
    private final String connectName;
    private final String anchor;
    private final int graphId;
    /**
     * Constructor.
     */
    public Connection(final int connectId, final String connectName, final int graphId, final String anchor) {
      this.connectId = connectId;
      this.connectName = connectName;
      this.anchor = anchor;
      this.graphId = graphId;
    }
    public String getAnchor() {
      return(this.anchor);
    }
    public int getConnectId() {
      return(this.connectId);
    }
    public String getConnectName() {
      return(this.connectName);
    }
    public int getGraphId() {
      return(this.graphId);
    }
  }
}
TOP

Related Classes of vg.modules.desktop.DesktopPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.