123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- package ui.view.outliner;
- import java.awt.BorderLayout;
- import java.awt.Component;
- import java.awt.Dimension;
- import java.awt.datatransfer.DataFlavor;
- import java.awt.datatransfer.Transferable;
- import java.awt.datatransfer.UnsupportedFlavorException;
- import java.awt.event.MouseAdapter;
- import java.awt.event.MouseEvent;
- import java.io.IOException;
- import javax.swing.AbstractCellEditor;
- import javax.swing.DropMode;
- import javax.swing.Icon;
- import javax.swing.ImageIcon;
- import javax.swing.JCheckBoxMenuItem;
- import javax.swing.JComponent;
- import javax.swing.JLabel;
- import javax.swing.JMenuItem;
- import javax.swing.JPanel;
- import javax.swing.JPopupMenu;
- import javax.swing.JTextField;
- import javax.swing.JTree;
- import javax.swing.SwingUtilities;
- import javax.swing.ToolTipManager;
- import javax.swing.TransferHandler;
- import javax.swing.tree.DefaultMutableTreeNode;
- import javax.swing.tree.DefaultTreeCellRenderer;
- import javax.swing.tree.TreeCellEditor;
- import javax.swing.tree.TreePath;
- import javax.swing.tree.TreeSelectionModel;
- import classes.Holon;
- import classes.HolonElement;
- import ui.controller.Control;
- import utility.ImageImport;
- /**
- * An Outliner Tab.
- * A high level view on the Model with respect to the Holon Structure.
- * @author Tom
- *
- */
- public class HolonView extends JPanel{
- private Control control;
- private JTree holonTree;
- private DefaultMutableTreeNode root;
- private boolean showHolonElementsInTree = true;
-
-
-
- public HolonView(Outliner parent, Control control) {
- this.control = control;
- this.setLayout(new BorderLayout());
- initilizePanel();
- parent.outlinerUpdate.addListener(() -> updateTreeStructure());
- }
- private void initilizePanel() {
- holonTree = generateTree();
- holonTree.setCellRenderer(new HolonJtreeRenderer());
- holonTree.setDragEnabled(true);
- holonTree.setDropMode(DropMode.ON_OR_INSERT);
- holonTree.setTransferHandler(new HolonTransferHandler());
- holonTree.getSelectionModel().setSelectionMode(
- TreeSelectionModel.SINGLE_TREE_SELECTION);
- ToolTipManager.sharedInstance().registerComponent(holonTree);
- TreeUtils.expand(holonTree);
- holonTree.setRootVisible(true);
- holonTree.addMouseListener(new HolonMouseListener());
- holonTree.setEditable(true);
- holonTree.setCellEditor(new HolonNodeEditor());
- this.add(TreeUtils.makePanelFromTree(holonTree));
- }
-
-
- private JTree generateTree() {
- root = generateFromHolon(control.getModel().getStateHolon());
- return new JTree(root);
- }
-
- private DefaultMutableTreeNode generateFromHolon(Holon holon) {
- DefaultMutableTreeNode node = new DefaultMutableTreeNode(new HolonInfo(holon));
- for(Holon child : holon.getChildView()) {
- node.add(generateFromHolon(child));
- }
- if(this.showHolonElementsInTree) {
- for(HolonElement ele : holon.getElementView()) {
- node.add(new DefaultMutableTreeNode(new ElementInfo(ele)));
- }
- }
- return node;
- }
- private void updateTreeStructure() {
- holonTree.clearSelection();
- root.removeAllChildren();
- Holon holon = control.getModel().getStateHolon();
- for(Holon child : holon.getChildView()) {
- root.add(generateFromHolon(child));
- }
- if(this.showHolonElementsInTree) {
- for(HolonElement ele : holon.getElementView()) {
- root.add(new DefaultMutableTreeNode(new ElementInfo(ele)));
- }
- }
- holonTree.updateUI();
- TreeUtils.expand(holonTree);
- }
-
- interface HolonNode{
- public Transferable getTransferable(HolonTransferHandler handler);
- public Icon getIcon();
- public String getToolTip();
- public void SetName(String name);
- }
- static final Icon elementIcon = new ImageIcon(ImageImport.loadImage("/Button_Images/element.png",16,16));
- static final String elementToolTip = "Element";
- class ElementInfo implements HolonNode{
- private HolonElement element;
- ElementInfo(HolonElement element){
- this.element = element;
- }
- @Override
- public String toString(){
- return element.getName();
- }
-
- public HolonElement getElement()
- {
- return element;
- }
- @Override
- public Transferable getTransferable(HolonTransferHandler handler) {
- return handler.new ElementTransferable(element);
- }
- @Override
- public Icon getIcon() {
- return elementIcon;
- }
- @Override
- public String getToolTip() {
- return elementToolTip;
- }
- @Override
- public void SetName(String name) {
- element.setEleName(name);
- }
- }
- static final Icon holonIcon = new ImageIcon(ImageImport.loadImage("/Button_Images/holon.png",16,16));
- static final String holonToolTip = "Holon";
- class HolonInfo implements HolonNode{
- private Holon holon;
- HolonInfo(Holon holon){
- this.holon = holon;
- }
- @Override
- public String toString(){
- return holon.name;
- }
-
- public Holon getElement()
- {
- return holon;
- }
-
- public void AddElement(HolonElement element) {
- if(element.holon != null) {
- element.holon.removeElement(element);
- }
- holon.addElement(element);
- }
- public void AddHolon(Holon holon) {
- holon.removeFromParent();
- this.holon.addChild(holon);
- }
- @Override
- public Transferable getTransferable(HolonTransferHandler handler) {
- return handler.new HolonTransferable(holon);
- }
- @Override
- public Icon getIcon() {
- return holonIcon;
- }
- @Override
- public String getToolTip() {
- return holonToolTip;
- }
- @Override
- public void SetName(String name) {
- holon.name = name;
- }
-
- }
-
-
-
-
- //Context Menu
- class HolonMouseListener extends MouseAdapter{
-
- JPopupMenu menu = new JPopupMenu ();
- JCheckBoxMenuItem showElements = new JCheckBoxMenuItem("Show Elements");
- JMenuItem newHolonAsParentItem = new JMenuItem("Create new Holon as Parent.");
- JMenuItem newHolonAsChildItem = new JMenuItem("Create new Holon as Child.");
-
- public HolonMouseListener() {
- //Initialize MenuItems
-
- showElements.setState(showHolonElementsInTree);
- showElements.addActionListener(clicked -> {
- showHolonElementsInTree = showElements.getState();
- updateTreeStructure();
- });
-
- newHolonAsParentItem.addActionListener(clicked -> {
- TreePath path = holonTree.getSelectionPath();
- HolonInfo info = getInfoFromPath(path);
- if(info == null) return;
- Holon parent = info.holon.getParent();
- parent.removeChildHolon(info.holon);
- Holon newHolon = new Holon("New Holon");
- newHolon.addChild(info.holon);
- parent.addChild(newHolon);
- updateTreeStructure();
- });
- newHolonAsChildItem.addActionListener(clicked -> {
- TreePath path = holonTree.getSelectionPath();
- HolonInfo info = getInfoFromPath(path);
- if(info == null) return;
- info.holon.addChild(new Holon("New Holon"));
- updateTreeStructure();
- });
-
-
- //CreateMenu
- menu.add(showElements);
- menu.addSeparator();
- menu.add(newHolonAsParentItem);
- menu.add(newHolonAsChildItem);
- }
-
- public void mousePressed ( MouseEvent e )
- {
- if (!SwingUtilities.isRightMouseButton(e))
- {
- return;
- }
- TreePath path = holonTree.getSelectionPath();
- boolean pathIsViable = (path != null);
- newHolonAsParentItem.setVisible(pathIsViable);
- newHolonAsChildItem.setVisible(pathIsViable);
- menu.show(holonTree, e.getX(), e.getY());
- }
-
- HolonInfo getInfoFromPath(TreePath path) {
- if(path == null) {
- return null;
- }
- DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
- if(!(node.getUserObject() instanceof HolonInfo)) {
- return null;
- }
- return (HolonInfo)node.getUserObject();
- }
- }
-
-
- //Drag and Drop
- //Make drag and drop von Holons possible.
- //Implement HolonElement drag and drop too, but its disabled.
- class HolonTransferHandler extends TransferHandler{
- DataFlavor holonFlavor;
- DataFlavor[] holonFlavorArray = new DataFlavor[1];
- DataFlavor elementFlavor;
- DataFlavor[] elementFlavorArray = new DataFlavor[1];
- boolean allowHolonElementDragAndDrop = false;
- HolonTransferHandler(){
- try {
- String mimeType = DataFlavor.javaJVMLocalObjectMimeType +
- ";class=\"" +
- classes.Holon.class.getName() +
- "\"";
- holonFlavor = new DataFlavor(mimeType);
- holonFlavorArray[0] = holonFlavor;
- mimeType = DataFlavor.javaJVMLocalObjectMimeType +
- ";class=\"" +
- classes.HolonElement.class.getName() +
- "\"";
- elementFlavor = new DataFlavor(mimeType);
- elementFlavorArray[0] = elementFlavor;
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- @Override
- public boolean canImport(TransferHandler.TransferSupport support) {
- if(!support.isDrop()) {
- return false;
- }
- support.setShowDropLocation(true);
- //Only accept Element and Holon as Drop
- if(!support.isDataFlavorSupported(holonFlavor) && !support.isDataFlavorSupported(elementFlavor)) {
- return false;
- }
-
- JTree.DropLocation location = (JTree.DropLocation)support.getDropLocation();
- TreePath pathDrop = location.getPath();
- DefaultMutableTreeNode node = (DefaultMutableTreeNode) pathDrop.getLastPathComponent();
- //Element cannot be parent of a holon
- if(!(node.getUserObject() instanceof HolonInfo)) {
- return false;
- }
-
- JTree tree = (JTree) support.getComponent();
- TreePath pathDrag = tree.getSelectionPath();
- //Dont allow Cycles
- if(pathDrag.isDescendant(pathDrop)) {
- return false;
- }
-
- //Check physical connected
- try {
- Holon dropHolon = ((HolonInfo) node.getUserObject()).holon;
- Holon dragHolon = (Holon) support.getTransferable().getTransferData(holonFlavor);
- boolean physicalConnected = dropHolon.checkHolonArePhysicalConnected(dragHolon, control);
- boolean isAllStateHolon = dropHolon.getLayer() == 0;
- return physicalConnected || isAllStateHolon;
- } catch (UnsupportedFlavorException | IOException e) {
- e.printStackTrace();
- return false;
- }
- }
- @Override
- public boolean importData(TransferHandler.TransferSupport support) {
- if(!canImport(support)) {
- return false;
- }
- JTree.DropLocation location = (JTree.DropLocation)support.getDropLocation();
- TreePath path = location.getPath();
- DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
- if(node.getUserObject() instanceof HolonInfo) {
-
- HolonInfo info = (HolonInfo) node.getUserObject();
- try {
- if(support.isDataFlavorSupported(holonFlavor)) {
- info.AddHolon((Holon) support.getTransferable().getTransferData(holonFlavor));
- }else if (support.isDataFlavorSupported(elementFlavor)){
- info.AddElement((HolonElement) support.getTransferable().getTransferData(elementFlavor));
- }
-
- } catch (UnsupportedFlavorException | IOException e) {
- e.printStackTrace();
- }
- }
- return false;
- }
- protected void exportDone(JComponent source,
- Transferable data,
- int action) {
- updateTreeStructure();
- }
-
- @Override
- public int getSourceActions(JComponent c) {
- return MOVE;
- }
- @Override
- protected Transferable createTransferable(JComponent c) {
- JTree tree = (JTree)c;
- TreePath path = tree.getSelectionPath();
- if(path != null) {
- DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
- Object userObject = node.getUserObject();
- //Only allow Hollon to move
- if(this.allowHolonElementDragAndDrop) {
- //Both
- if(userObject instanceof HolonNode) {
- return ((HolonNode) userObject).getTransferable(this);
- }
- }
- else {
- //Only Holons
- if(userObject instanceof HolonInfo) {
- return ((HolonInfo) userObject).getTransferable(this);
- }
- }
- }
- return null;
- }
-
- public class HolonTransferable implements Transferable{
- Holon holon;
-
-
- public HolonTransferable(Holon holon) {
- this.holon = holon;
- }
- @Override
- public DataFlavor[] getTransferDataFlavors() {
- return holonFlavorArray;
- }
- @Override
- public boolean isDataFlavorSupported(DataFlavor flavor) {
- return holonFlavor.equals(flavor);
- }
- @Override
- public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
- if(!isDataFlavorSupported(flavor))
- throw new UnsupportedFlavorException(flavor);
- return holon;
- }
-
- }
- public class ElementTransferable implements Transferable{
- HolonElement element;
-
-
- public ElementTransferable(HolonElement element) {
- this.element = element;
- }
- @Override
- public DataFlavor[] getTransferDataFlavors() {
- return elementFlavorArray;
- }
- @Override
- public boolean isDataFlavorSupported(DataFlavor flavor) {
- return elementFlavor.equals(flavor);
- }
- @Override
- public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
- if(!isDataFlavorSupported(flavor))
- throw new UnsupportedFlavorException(flavor);
- return element;
- }
-
- }
- }
-
- //Cell Display
- class HolonJtreeRenderer extends DefaultTreeCellRenderer {
-
- public Component getTreeCellRendererComponent(
- JTree tree,
- Object value,
- boolean isSelected,
- boolean expanded,
- boolean leaf,
- int row,
- boolean hasFocus) {
- super.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, hasFocus);
- DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
- HolonNode Node = (HolonNode) node.getUserObject();
- if(row != 0) {
- this.setIcon(Node.getIcon());
- this.setToolTipText(Node.getToolTip());
- }
- return this;
- }
- }
-
- //Edit Names of Nodes
- class HolonNodeEditor extends AbstractCellEditor implements TreeCellEditor{
- private HolonNode holonNode;
- private JTextField tf= new JTextField(){
- @Override
- public Dimension getPreferredSize() {
- Dimension dim = super.getPreferredSize();
- int length = getText().length();
- dim.width = Math.max(300, dim.width + length * 10) ;
- return dim;
- }
- };
- public HolonNodeEditor() {
- super();
- }
- @Override
- public Object getCellEditorValue() {
- holonNode.SetName(tf.getText());
- return tf.getText();
- }
-
- @Override
- public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded,
- boolean leaf, int row) {
- JLabel newString = (JLabel) holonTree.getCellRenderer().getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, leaf);
- DefaultMutableTreeNode default_node = (DefaultMutableTreeNode) value;
- holonNode = (HolonNode)default_node.getUserObject();
- tf.setText(newString.getText());
- return tf;
- }
-
- }
- }
|