pax_global_header00006660000000000000000000000064124771500650014521gustar00rootroot0000000000000052 comment=6e8e7b70de4b235ced01213ff5a208910f0781bd mdock-mdock-2.0.1/000077500000000000000000000000001247715006500137115ustar00rootroot00000000000000mdock-mdock-2.0.1/.gitignore000066400000000000000000000001551247715006500157020ustar00rootroot00000000000000# Maven target/ # Eclipse .classpath .project .settings/ META-INF/ #intelliJ *.iws *.ipr .idea *.iml build/mdock-mdock-2.0.1/LICENSE000066400000000000000000000167211247715006500147250ustar00rootroot00000000000000GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. mdock-mdock-2.0.1/README.md000066400000000000000000000000551247715006500151700ustar00rootroot00000000000000# mdock A lightweight Java docking framework mdock-mdock-2.0.1/pom.xml000066400000000000000000000101411247715006500152230ustar00rootroot00000000000000 4.0.0 org.sonatype.oss oss-parent 7 bundle com.googlecode.mdock mdock 2.0.1 mdock A lightweight Java component nesting and docking system http://mdock.googlecode.com GNU Lesser General Public License (LGPL) http://www.gnu.org/licenses/lgpl.html repo matthewhorridge Matthew Horridge matthew.horridge@gmail.com scm:git:git@github.com:matthewhorridge/mdock.git scm:git:git@github.com:matthewhorridge/mdock.git https://github.com/matthewhorridge/mdock GitHub https://github.com/matthewhorridge/mdock/issues junit junit 4.9 test maven-compiler-plugin 3.2 1.7 1.7 org.apache.maven.plugins maven-source-plugin 2.1.2 attach-sources jar org.apache.maven.plugins maven-javadoc-plugin 2.8.1 attach-javadocs jar org.apache.felix maven-bundle-plugin true 2.5.3 org.coode.mdock org.apache.maven.plugins maven-gpg-plugin 1.6 sign-artifacts verify sign mdock-mdock-2.0.1/src/000077500000000000000000000000001247715006500145005ustar00rootroot00000000000000mdock-mdock-2.0.1/src/main/000077500000000000000000000000001247715006500154245ustar00rootroot00000000000000mdock-mdock-2.0.1/src/main/java/000077500000000000000000000000001247715006500163455ustar00rootroot00000000000000mdock-mdock-2.0.1/src/main/java/org/000077500000000000000000000000001247715006500171345ustar00rootroot00000000000000mdock-mdock-2.0.1/src/main/java/org/coode/000077500000000000000000000000001247715006500202255ustar00rootroot00000000000000mdock-mdock-2.0.1/src/main/java/org/coode/mdock/000077500000000000000000000000001247715006500213225ustar00rootroot00000000000000mdock-mdock-2.0.1/src/main/java/org/coode/mdock/ColumnPanel.java000066400000000000000000000127001247715006500244020ustar00rootroot00000000000000package org.coode.mdock; import javax.swing.*; import java.util.*; import java.util.List; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.ActionEvent; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Author: Matthew Horridge * The University Of Manchester * Bio-Health Informatics Group * Date: 09-Aug-2007 */ public class ColumnPanel extends JPanel { private NodePanel columns; private VerticalSplitterNode node; private int defaultColumnWidth = 180; private JPanel holderPanel; private JScrollPane sp; private LinkedHashMap componentNodeMap; public ColumnPanel(JComponent initialComponent) { componentNodeMap = new LinkedHashMap(); ComponentNode firstComponentNode = new ComponentNode(); firstComponentNode.add(initialComponent, "Component"); ArrayList nodes = new ArrayList(); nodes.add(firstComponentNode); ArrayList splits = new ArrayList(); splits.add(1.0); componentNodeMap.put(initialComponent, firstComponentNode); node = new VerticalSplitterNode(nodes, splits); columns = new NodePanel(node) { public Dimension getPreferredSize() { return new Dimension(node.getVisibleChildren().size() * defaultColumnWidth, 10); } }; setLayout(new BorderLayout()); holderPanel = new JPanel(new BorderLayout()); holderPanel.add(columns, BorderLayout.WEST); add(sp = new JScrollPane(holderPanel)); } public void ensureVisible(JComponent component) { component.scrollRectToVisible(new Rectangle(component.getSize().width, 10)); } // // public void addColumn(JComponent content) { // // // // } public void removeColumnsAfter(JComponent columnContent) { boolean remove = false; for (Iterator it = componentNodeMap.keySet().iterator(); it.hasNext();) { JComponent comp = it.next(); Node curNode = componentNodeMap.get(comp); if (comp.equals(columnContent)) { remove = true; } else if (remove) { it.remove(); node.removeChild(curNode); } } columns.rebuild(); columns.validate(); } public void addColumn(JComponent content, JComponent after) { JComponent focusedComponent = null; for(JComponent c : componentNodeMap.keySet()) { if(c.isFocusOwner()) { focusedComponent = c; break; } } List visibleChildren = node.getVisibleChildren(); List widths = new ArrayList(); int total = 0; for (Node childNode : visibleChildren) { int childWidth = Util.getWidth(childNode, columns, false); widths.add(childWidth); total += childWidth; } widths.add(defaultColumnWidth); removeColumnsAfter(after); visibleChildren = node.getVisibleChildren(); ComponentNode cn = new ComponentNode(); cn.add(content, ""); componentNodeMap.put(content, cn); if(!visibleChildren.isEmpty()) { node.insertNodeAfter(cn, visibleChildren.get(visibleChildren.size() - 1), SplitterNode.VERTICAL_SPLITTER); } else { node.addChild(cn, 0, 1.0); } visibleChildren = node.getVisibleChildren(); int currentIndex = 0; for (Node nn : visibleChildren) { node.setSplit(nn, widths.get(currentIndex) * 1.0 / total); currentIndex++; } columns.rebuild(); holderPanel.setPreferredSize(new Dimension(node.getVisibleChildren().size() * defaultColumnWidth, 10)); sp.validate(); sp.getHorizontalScrollBar().setValue(Integer.MAX_VALUE); if(focusedComponent != null) { System.out.println("Refocusing"); focusedComponent.requestFocus(); } else { content.requestFocus(); } // addColumn(content); } public static void main(String[] args) { JButton button = new JButton("Test"); ColumnPanel pan = new ColumnPanel(button); JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(new Dimension(300, 400)); f.setContentPane(pan); f.setVisible(true); } }mdock-mdock-2.0.1/src/main/java/org/coode/mdock/ComponentFactory.java000066400000000000000000000034441247715006500254640ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import java.util.Map; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 26-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * Creates components that get placed in the node panel. This is used for * reanimation of a node panel. */ public interface ComponentFactory { /** * Given a set of properties, creates a component that can be * placed in the node panel. * @param properties The properties which provide information * about the component to be created. * @return The component */ public JComponent createComponent(Map properties); } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/ComponentNode.java000066400000000000000000000146311247715006500247420ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import javax.swing.plaf.TabbedPaneUI; import java.awt.*; import java.util.*; import java.util.List; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * Represents a node that contains one or more user components. If there * are multiple user components then they appear to be stacked via the use * of a tabbed pane. */ public class ComponentNode extends Node { private final JTabbedPane tabbedPane; private final List components; private final Map component2LabelMap; private final JComponent baseComponent; public ComponentNode() { baseComponent = new JPanel(new BorderLayout()) { public void remove(Component comp) { ComponentNode.this.remove((JComponent) comp); } public void remove(int index) { super.remove(index); } public void removeAll() { super.removeAll(); } }; components = new ArrayList<>(); component2LabelMap = new HashMap<>(); TabbedPaneUI tabbedPaneUI = UIComponentFactory.getInstance().createComponentNodeTabbedPaneUI(); tabbedPane = new JTabbedPane() { @Override public void remove(Component component) { ComponentNode.this.remove((JComponent) component); } }; tabbedPane.setUI(tabbedPaneUI); baseComponent.setBorder(UIComponentFactory.getInstance().createComponentNodeBorder()); } /** * Adds a component to this node. If there are multiple components * they will be "stacked" in a tabbed pane. * * @param component The component to be added * @param label The label for the selection tab which brings the component * to the front if there are multiple components. */ public void add(JComponent component, String label) { components.add(component); component2LabelMap.put(component, label); if (components.size() == 1) { baseComponent.add(component); } else if (components.size() > 1) { baseComponent.removeAll(); for (JComponent c : components) { tabbedPane.add(component2LabelMap.get(c), c); } baseComponent.add(tabbedPane); } // tabbedPane.add(label, component); if (component instanceof NodeComponent) { // Notify the component that it was added to us ((NodeComponent) component).addedToNode(this); } } /** * Gets the label for the specified component. * * @param component The component whose label is to be * retrieved * @return The label of the specified component, or an * empty string if the component isn't held by this component node. */ public String getLabel(JComponent component) { String label = component2LabelMap.get(component); if (label != null) { return label; } else { return ""; } } public void remove(JComponent component) { component2LabelMap.remove(component); components.remove(component); baseComponent.removeAll(); tabbedPane.removeAll(); if (components.size() == 1) { baseComponent.add(components.get(0)); } else if (components.size() > 1) { for (JComponent c : components) { tabbedPane.add(component2LabelMap.get(c), c); } baseComponent.add(tabbedPane); } removeFromParentIfEmpty(); notifyStateChange(); } private void removeFromParentIfEmpty() { if (getComponentCount() == 0) { baseComponent.getParent().remove(baseComponent); remove(); } } /** * Gets the root component (most likely a tabbed pane) * * @return The root component */ public JComponent getComponent() { return baseComponent; } /** * Gets the number of user components held by this component node. * * @return The number of components */ public int getComponentCount() { return components.size(); } /** * Determines if this node is visible. A component node is defined to * be visible if it holds at least one component, otherwise, it is * not visible. * * @return The visibility */ public boolean isVisible() { return getComponentCount() != 0; } public double getGloballyNormalisedXLocation(Node child) { if (getParent() == null) { return 1.0; } else { // Ask our parent return getParent().getGloballyNormalisedYLocation(); } } public double getGloballyNormalisedYLocation(Node child) { return 0; } protected void stateChanged() { } public void accept(NodeVisitor visitor) { visitor.visit(this); } /** * Gets a list of the component that are held by this component node. * * @return The components. */ public List getComponents() { return Collections.unmodifiableList(components); } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/ComponentNodeTabbedPane.java000066400000000000000000000034311247715006500266440ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import javax.swing.plaf.TabbedPaneUI; import java.awt.*; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 26-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public class ComponentNodeTabbedPane extends JTabbedPane { public ComponentNodeTabbedPane() { // setUI(new ComponentNodeTabbedPaneUIDelegate(getUI())); setBorder(null); // setTabPlacement(JTabbedPane.BOTTOM); setFocusable(false); setFont(new Font("sans-serif", Font.PLAIN, 10)); } public void updateUI() { // Deliberately commented out! super.updateUI(); } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/ComponentNodeTabbedPaneUI.java000066400000000000000000000175771247715006500271220ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import javax.swing.plaf.basic.BasicTabbedPaneUI; import java.awt.*; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 26-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public class ComponentNodeTabbedPaneUI extends BasicTabbedPaneUI { private static final int TAB_HEIGHT = 16; protected void installDefaults() { super.installDefaults(); tabAreaInsets.left = 0; selectedTabPadInsets = new Insets(0, 0, 0, 0); tabInsets = selectedTabPadInsets; tabPane.setFont(tabPane.getFont().deriveFont(Font.PLAIN, 10.0f)); } /** * Paints the tabs in the tab area. * Invoked by paint(). * The graphics parameter must be a valid Graphics * object. Tab placement may be either: * JTabbedPane.TOP, JTabbedPane.BOTTOM, * JTabbedPane.LEFT, or JTabbedPane.RIGHT. * The selected index must be a valid tabbed pane tab index (0 to * tab count - 1, inclusive) or -1 if no tab is currently selected. * The handling of invalid parameters is unspecified. * @param g the graphics object to use for rendering * @param tabPlacement the placement for the tabs within the JTabbedPane * @param selectedIndex the tab index of the selected component * @since 1.4 */ protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) { super.paintTabArea(g, tabPlacement, selectedIndex); } public void paint(Graphics g, JComponent c) { super.paint(g, c); } protected void paintText(Graphics g, int tabPlacement, Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected) { if (isSelected) { g.setColor(Color.DARK_GRAY.darker()); } else { g.setColor(Color.GRAY); } g.drawString(title, textRect.x, textRect.y + metrics.getAscent()); //super.paintText(g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected); } protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect) { super.paintTab(g, tabPlacement, rects, tabIndex, iconRect, textRect); } protected Insets getContentBorderInsets(int tabPlacement) { return new Insets(0, 0, 0, 0); } protected Insets getTabInsets(int tabPlacement, int tabIndex) { return new Insets(0, 0, 0, 0); } protected Insets getSelectedTabPadInsets(int tabPlacement) { return new Insets(0, 0, 0, 0); } protected Insets getTabAreaInsets(int tabPlacement) { return new Insets(1, 1, 1, 1); } protected int getTabLabelShiftX(int tabPlacement, int tabIndex, boolean isSelected) { Rectangle tabRect = rects[tabIndex];//return super.getTabLabelShiftX(tabPlacement, tabIndex, isSelected); return tabRect.width % 2; } protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) { return 0; } // // /** // * Returns the bounds of the specified tab index. The bounds are // * with respect to the JTabbedPane's coordinate space. // */ // public Rectangle getTabBounds(JTabbedPane pane, int i) { // Rectangle r = new Rectangle(TAB_WIDTH * i, 0, TAB_WIDTH, TAB_HEIGHT); // return r; // } /** * this function draws the border around each tab * note that this function does now draw the background of the tab. * that is done elsewhere */ protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { //super.paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected); if (isSelected) { g.setColor(Color.GRAY); } else { g.setColor(Color.LIGHT_GRAY); } g.drawRect(x + 1, y + 1, w - 2, h - 2); } protected void paintFocusIndicator(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) { //super.paintFocusIndicator(g, tabPlacement, rects, tabIndex, iconRect, textRect, isSelected); } /** * Returns the bounds of the specified tab index. The bounds are * with respect to the JTabbedPane's coordinate space. */ public Rectangle getTabBounds(JTabbedPane pane, int i) { return super.getTabBounds(pane, i); } protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) { if (tabPane.getComponentCount() > 1) { return TAB_HEIGHT; } else { return 0; } } protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) { return super.calculateTabWidth(tabPlacement, tabIndex, metrics) + 3; } protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { // if(isSelected) { // g.setColor(Color.LIGHT_GRAY); // g.fillRect(x + 1, y + 1, w - 2, h - 2); // } //super.paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected); } protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) { //super.paintContentBorder(g, tabPlacement, selectedIndex); } protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { //super.paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h); } protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { //super.paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h); } protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { //super.paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h); } protected void paintContentBorderRightEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { //super.paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h); } // protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) { // return TAB_WIDTH; // } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/ComponentPropertiesFactory.java000066400000000000000000000031021247715006500275300ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import java.util.Map; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 26-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * Given a component, provides a map of properties which can be * persisted and used to recreate the component at a later stage. */ public interface ComponentPropertiesFactory { public Map getProperties(JComponent component); } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/DynamicConfigPanel.java000066400000000000000000000266061247715006500256710ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Arrays; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 25-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * Provides a way of dynamically adding components to a node panel * (via drag and drop like actions). */ public class DynamicConfigPanel extends JPanel { private JComponent component; private NodePanel nodePanel; private JComponent currentComponent; private String currentLabel; private Color lineColor = new Color(139, 178, 212); public DynamicConfigPanel(JComponent component) { this.component = component; this.nodePanel = null; setOpaque(false); addMouseMotionListener(new MouseMotionAdapter() { public void mouseMoved(MouseEvent e) { updateNodePanel(); repaint(); } }); addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { handleMouseClicked(e); } }); } private void handleMouseClicked(MouseEvent e) { if(nodePanel == null) { return; } setVisible(false); // Insert the new node Point nodePanelPt = SwingUtilities.convertPoint(this, e.getPoint(), nodePanel); Node n = Util.getDeepestNode(nodePanel.getRootNode(), nodePanel, nodePanelPt); if(n == null) { return; } AddMode mode = getAddMode(n, nodePanelPt); mode.doAdd(currentComponent, currentLabel); currentComponent = null; nodePanel.rebuild(); } public void setCurrentComponent(JComponent currentComponent, String label) { this.currentComponent = currentComponent; this.currentLabel = label; } private void updateNodePanel() { Container contentPane = getRootPane().getContentPane(); // Find the deepest node panel Point pt = getMousePosition(); if(pt == null) { return; } pt = SwingUtilities.convertPoint(this, pt, contentPane); Component c = SwingUtilities.getDeepestComponentAt(contentPane, pt.x, pt.y); if(c instanceof NodePanel) { nodePanel = (NodePanel) c; return; } NodePanel np = (NodePanel) SwingUtilities.getAncestorOfClass(NodePanel.class, c); if(np != null) { nodePanel = np; } } public void activate() { if(currentComponent == null) { throw new IllegalStateException("No component is set!"); } if(currentComponent.getParent() != null) { throw new IllegalStateException("Current component already has a parent!"); } component.getRootPane().setGlassPane(this); setVisible(true); } protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Point pt = getMousePosition(); // Paint target - this can be quite useful in a complex UI (or on a slow machine), // where repaints are slow. if (pt != null) { g2.fillOval(pt.x - 4, pt.y - 4, 8, 8); g2.drawOval(pt.x - 6, pt.y - 6, 12, 12); } Point mousePos = getMousePosition(); if (mousePos != null && nodePanel != null) { // Draw a box round the deepest node that the mouse is over mousePos = SwingUtilities.convertPoint(this, mousePos, nodePanel); Node n = Util.getDeepestNode(nodePanel.getRootNode(), nodePanel, mousePos); if (n != null) { AddMode addMode = getAddMode(n, mousePos); addMode.paintRect(g); } } } private AddMode getAddMode(Node node, Point mousePoint) { if(node.getParent() == null) { // Root node return new CentreAddMode(node); } Rectangle bounds = Util.getBounds(node, nodePanel, false); // bounds = SwingUtilities.convertRectangle(nodePanel, bounds, this); bounds.grow(-6, -6); int xMargin = (int) (bounds.width * 0.3); int yMargin = (int) (bounds.height * 0.3); if(mousePoint.y < (bounds.y + yMargin)) { return new TopAddMode(node); } else if(mousePoint.y > bounds.y + bounds.height - yMargin) { return new BottomAddMode(node); } else if(mousePoint.x < bounds.x + xMargin) { return new LeftAddMode(node); } else if(mousePoint.x > bounds.x + bounds.width - xMargin) { return new RightAddMode(node); } else { return new CentreAddMode(node); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Split mode stuff private abstract class AddMode { public final Stroke stroke = new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); public final Stroke thinStroke = new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); public static final int ARROW_DIM = 20; private Node node; private Rectangle bounds; public AddMode(Node node) { this.node = node; bounds = Util.getBounds(node, nodePanel, false); bounds = SwingUtilities.convertRectangle(nodePanel, bounds, DynamicConfigPanel.this); } protected Node getNode() { return node; } public abstract void doAdd(JComponent component, String label); public abstract Rectangle getRect(); public Rectangle getBounds() { return bounds; } public Rectangle getInnerBounds() { Rectangle smallBounds = new Rectangle(bounds); smallBounds.grow(-6, -6); return smallBounds; } public void paintRect(Graphics g) { Stroke oldStroke = ((Graphics2D) g).getStroke(); Graphics2D g2 = ((Graphics2D) g); g2.setStroke(stroke); Color oldColor = g.getColor(); g.setColor(lineColor); Rectangle smallBounds = getInnerBounds(); g.drawRect(smallBounds.x, smallBounds.y, smallBounds.width, smallBounds.height); Rectangle posRect = getRect(); posRect.grow(-6, -6); currentComponent.setBounds(posRect); currentComponent.validate(); Composite oldComp = g2.getComposite(); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); SwingUtilities.paintComponent(g, currentComponent, DynamicConfigPanel.this, posRect); g2.setComposite(oldComp); g2.setStroke(oldStroke); g.drawRect(posRect.x, posRect.y, posRect.width, posRect.height); g.setColor(oldColor); g2.setStroke(oldStroke); } } private class TopAddMode extends AddMode { public TopAddMode(Node node) { super(node); } public void doAdd(JComponent component, String label) { SplitterNode parentNode = getNode().getParent(); // Create the new node ComponentNode cn = new ComponentNode(); cn.add(component, label); // Now add the new node before the existing node. We require a horizontal // splitter! parentNode.insertNodeBefore(cn, getNode(), SplitterNode.HORIZONTAL_SPLITTER); } public Rectangle getRect() { Rectangle rect = getInnerBounds(); rect.height = rect.height / 2; return rect; } } private class BottomAddMode extends AddMode { public BottomAddMode(Node node) { super(node); } public Rectangle getRect() { Rectangle rect = getInnerBounds(); rect.height = rect.height / 2; rect.y = rect.y + rect.height; return rect; } public void doAdd(JComponent component, String label) { SplitterNode parentNode = getNode().getParent(); ComponentNode cn = new ComponentNode(); cn.add(component, label); parentNode.insertNodeAfter(cn, getNode(), SplitterNode.HORIZONTAL_SPLITTER); } } private class LeftAddMode extends AddMode { public LeftAddMode(Node node) { super(node); } public Rectangle getRect() { Rectangle rect = getInnerBounds(); rect.width = rect.width / 2; return rect; } public void doAdd(JComponent component, String label) { ComponentNode cn = new ComponentNode(); cn.add(component, label); SplitterNode parentNode = getNode().getParent(); parentNode.insertNodeBefore(cn, getNode(), SplitterNode.VERTICAL_SPLITTER); } } private class RightAddMode extends AddMode { public RightAddMode(Node node) { super(node); } public void doAdd(JComponent component, String label) { SplitterNode parentNode = getNode().getParent(); ComponentNode cn = new ComponentNode(); cn.add(component, label); parentNode.insertNodeAfter(cn, getNode(), SplitterNode.VERTICAL_SPLITTER); } public Rectangle getRect() { Rectangle rect = getInnerBounds(); rect.width = rect.width / 2; rect.x = rect.x + rect.width; return rect; } } private class CentreAddMode extends AddMode { public CentreAddMode(Node node) { super(node); } public void doAdd(JComponent component, String label) { if(getNode() instanceof ComponentNode) { ((ComponentNode) getNode()).add(component, label); } else { ComponentNode cn = new ComponentNode(); cn.add(component, label); ((SplitterNode) getNode()).addChild(cn, 0, 1.0); } Util.bringToFront(component); } public Rectangle getRect() { return getInnerBounds(); } } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/HorizontalSplitter.java000066400000000000000000000055261247715006500260550ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 24-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public class HorizontalSplitter extends Splitter { public HorizontalSplitter(SplitterNode node, Node child0, Node child1) { super(node, child0, child1); } public void resetBounds() { // Set the bounds int x = Util.getX(getChild1(), getParent(), false) + SPLITTER_WIDTH / 2 + 1; int y = Util.getY(getChild1(), getParent(), false) - SPLITTER_WIDTH / 2 + 1; int w = Util.getWidth(getChild1(), getParent(), false) - SPLITTER_WIDTH - 2; int h = Splitter.SPLITTER_WIDTH - 2; setBounds(x, y, w, h); } public Point getMaxLocation() { int x = Util.getX(getChild1(), getParent(), false) + SPLITTER_WIDTH / 2; int y = Util.getY(getChild1(), getParent(), false) - SPLITTER_WIDTH; int h = Util.getHeight(getChild1(), getParent(), false); return new Point(x, y + h); } public Point getMinLocation() { int x = Util.getX(getChild0(), getParent(), false) + SPLITTER_WIDTH / 2; int y = Util.getY(getChild0(), getParent(), false); return new Point(x, y); } protected int getSpan(Node child, Component parent, boolean includingSplitter) { return Util.getHeight(child, parent, includingSplitter); } protected int convertToLocation(Point pt) { return pt.y; } protected void setSplitterCursor() { setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)); } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/HorizontalSplitterNode.java000066400000000000000000000056531247715006500266640ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import java.util.List; import java.util.Arrays; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * A node which contains child nodes that are split by horizontal splitters. */ public class HorizontalSplitterNode extends SplitterNode { public HorizontalSplitterNode(List children, List splits) { super(children, splits); } protected double getGloballyNormalisedHeight(Node child) { // We affect the height of our children return getGloballyNormalisedHeight() * getNormalisedSplit(child); } public double getGloballyNormalisedYLocation(Node child) { // We affect the y location of our children double yLoc = getGloballyNormalisedYLocation(); for(Node curChild : getVisibleChildren()) { if(curChild == child) { return yLoc; } else { yLoc += getGloballyNormalisedHeight(curChild); } } return 0.0; } public boolean isSplitterDirection(int direction) { return direction == HORIZONTAL_SPLITTER; } public Splitter createSplitter(Node child0, Node child1) { return new HorizontalSplitter(this, child0, child1); } public SplitterNode pushDown(Node existingChild, List children) { VerticalSplitterNode vsn = new VerticalSplitterNode(children, Arrays.asList(0.5, 0.5)); replaceChild(existingChild, vsn); return vsn; } protected SplitterNode createPerpendicularSplitterNode(List children, List splits) { return new VerticalSplitterNode(children, splits); } public void accept(NodeVisitor visitor) { visitor.visit(this); } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/Node.java000066400000000000000000000107561247715006500230630ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import org.w3c.dom.Element; import org.w3c.dom.Document; import java.io.Writer; import java.io.IOException; import java.io.PrintWriter; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public abstract class Node { private SplitterNode parent; private boolean visible = true; protected void setParent(SplitterNode node) { this.parent = node; } /** * Gets the parent node of this node. * @return The parent node, or null * if there is no parent node */ public SplitterNode getParent() { return parent; } protected double getGloballyNormalisedHeight(Node child) { if(parent != null) { // Ask out parent return parent.getGloballyNormalisedHeight(this); } else { // We are a root, so, by definition our normalised // height is 1.0 return 1.0; } } protected double getGloballyNormalisedWidth(Node child) { if(parent != null) { // Ask our parent return parent.getGloballyNormalisedWidth(this); } else { return 1.0; } } public double getGloballyNormalisedXLocation() { if(parent == null) { return 0.0; } else { return parent.getGloballyNormalisedXLocation(this); } } public double getGloballyNormalisedXLocation(Node child) { if(parent == null) { return 0.0; } else { return parent.getGloballyNormalisedXLocation(this); } } public double getGloballyNormalisedYLocation() { if(parent == null) { return 0.0; } else { return parent.getGloballyNormalisedYLocation(this); } } public double getGloballyNormalisedYLocation(Node child) { if(parent == null) { return 0.0; } else { return parent.getGloballyNormalisedYLocation(this); } } public double getGloballyNormalisedHeight() { if(parent == null) { // Root node, so our global height is 1.0 return 1.0; } else { // We need to ask our parent return parent.getGloballyNormalisedHeight(this); } } public double getGloballyNormalisedWidth() { if(parent == null) { // Root node, so our global width is 1.0 return 1.0; } else { // We need to ask out parent return parent.getGloballyNormalisedWidth(this); } } final public void setVisible(boolean visible) { this.visible = visible; notifyStateChange(); } public boolean isVisible() { return visible; } protected void notifyStateChange() { stateChanged(); if(parent != null) { parent.stateChanged(); // Apply recursively parent.notifyStateChange(); } } public void remove() { SplitterNode parent = getParent(); if(parent != null) { parent.removeChild(this); notifyStateChange(); } } protected abstract void stateChanged(); public abstract void accept(NodeVisitor visitor); } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/NodeComponent.java000066400000000000000000000025511247715006500247400ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 26-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public interface NodeComponent { void addedToNode(ComponentNode node); } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/NodeLayout.java000066400000000000000000000061071247715006500242540ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import java.awt.*; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public class NodeLayout implements LayoutManager2 { private Node rootNode; private int preferredWidth = 800; private int preferredHeight = 600; public NodeLayout(Node rootNode) { this.rootNode = rootNode; } public void addLayoutComponent(Component comp, Object constraints) { } public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } public float getLayoutAlignmentX(Container target) { return 0; } public float getLayoutAlignmentY(Container target) { return 0; } public void invalidateLayout(Container target) { } public void addLayoutComponent(String name, Component comp) { } public void removeLayoutComponent(Component comp) { } public Dimension preferredLayoutSize(Container parent) { return new Dimension(preferredWidth, preferredHeight); } public Dimension minimumLayoutSize(Container parent) { return new Dimension(10, 10); } public void layoutContainer(Container parent) { layoutNode(rootNode, parent); } private void layoutNode(Node node, Container parent) { if(node instanceof ComponentNode) { ComponentNode componentNode = (ComponentNode) node; JComponent comp = componentNode.getComponent(); comp.setBounds(Util.getBounds(node, parent, true)); } else { SplitterNode splitterNode = (SplitterNode) node; for(Splitter splitter : splitterNode.getSplitters()) { splitter.resetBounds(); } for(Node curChild : splitterNode.getVisibleChildren()) { layoutNode(curChild, parent); } } } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/NodePanel.java000066400000000000000000000047231247715006500240400ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import java.awt.*; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * A NodePanel is a JPanel which comprises a tree map layout of * Nodes. The leaf nodes contain one or more components. */ public class NodePanel extends JPanel { private Node rootNode; public NodePanel(Node rootNode) { this.rootNode = rootNode; setLayout(new NodeLayout(rootNode)); rebuild(); } public Node getRootNode() { return rootNode; } public void rebuild() { Component focusedComponent = FocusManager.getCurrentManager().getFocusOwner(); removeAll(); addNode(rootNode); revalidate(); if (focusedComponent != null) { focusedComponent.requestFocus(); } } private void addNode(Node node) { if (node instanceof ComponentNode) { add(((ComponentNode) node).getComponent()); } else { for (Splitter splitter : ((SplitterNode) node).getSplitters()) { add(splitter); } for (Node curChildNode : ((SplitterNode) node).getVisibleChildren()) { addNode(curChildNode); } } } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/NodeReanimator.java000066400000000000000000000212241247715006500250750ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import org.xml.sax.SAXException; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.ParserConfigurationException; import javax.swing.*; import java.io.IOException; import java.io.Reader; import java.util.*; import java.util.List; import java.awt.*; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 25-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * Creates a tree of Nodes from a given node descriptor (node XML file). */ public class NodeReanimator extends DefaultHandler { private ComponentFactory componentFactory; private Stack elementStack; private ComponentElement currentComponentElement; private SplitterNode rootNode; /** * Creates a NodeReanimator which will read an XML node * descriptor from a given reader. * @param is The reader which a node descriptor will be read from * @param componentFactory The component factory which should be used * to create the components that are contained in component nodes. This * factory is application specific. */ public NodeReanimator(Reader is, ComponentFactory componentFactory) { this.componentFactory = componentFactory; elementStack = new Stack(); try { SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); saxParser.parse(new InputSource(is), this); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public SplitterNode getRootNode() { return rootNode; } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.equals(Vocabulary.COMPONENT_NODE)) { NodeElement element = new ComponentNodeElement(); elementStack.push(element); } else if(qName.equals(Vocabulary.HORIZONTAL_SPLITTER_NODE)) { NodeElement element = new HorizontalSplitterElement(getSplits(attributes)); elementStack.push(element); } else if(qName.equals(Vocabulary.VERTICAL_SPLITTER_NODE)) { NodeElement element = new VerticalSplitterElement(getSplits(attributes)); elementStack.push(element); } else if(qName.equals(Vocabulary.COMPONENT)) { currentComponentElement = new ComponentElement(attributes.getValue(Vocabulary.LABEL)); } else if(qName.equals(Vocabulary.PROPERTY)) { currentComponentElement.putProperty(attributes.getValue(Vocabulary.ID), attributes.getValue(Vocabulary.VALUE)); } } public void endElement(String uri, String localName, String qName) throws SAXException { if(qName.equals(Vocabulary.COMPONENT_NODE)) { NodeElement element = elementStack.pop(); elementStack.peek().addChildNodeElement(element); } else if(qName.equals(Vocabulary.HORIZONTAL_SPLITTER_NODE)) { NodeElement element = elementStack.pop(); if(elementStack.isEmpty()) { // Root rootNode = (SplitterNode) element.createNode(); } else { elementStack.peek().addChildNodeElement(element); } } else if(qName.equals(Vocabulary.VERTICAL_SPLITTER_NODE)) { NodeElement element = elementStack.pop(); if(elementStack.isEmpty()) { // Root rootNode = (SplitterNode) element.createNode(); } else { elementStack.peek().addChildNodeElement(element); } } else if(qName.equals(Vocabulary.COMPONENT)) { ComponentNodeElement element = (ComponentNodeElement) elementStack.peek(); element.addComponentElement(currentComponentElement); } } private static List getSplits(Attributes attributes) { String splits = attributes.getValue(Vocabulary.SPLITS); if(splits != null) { return parseSplits(splits); } else { return Collections.EMPTY_LIST; } } private static List parseSplits(String splits) { List list = new ArrayList(); StringTokenizer tokenizer = new StringTokenizer(splits.trim(), " "); while(tokenizer.hasMoreTokens()) { String curTok = tokenizer.nextToken(); list.add(Double.parseDouble(curTok)); } return list; } private abstract class NodeElement { private List children; public NodeElement() { this.children = new ArrayList(); } public void addChildNodeElement(NodeElement child) { children.add(child); } public abstract Node createNode(); public List createChildNodes() { List childNodes = new ArrayList(); for(NodeElement element : children) { childNodes.add(element.createNode()); } return childNodes; } } private class ComponentNodeElement extends NodeElement { private List componentElements; public ComponentNodeElement() { componentElements = new ArrayList(); } public void addComponentElement(ComponentElement componentElement) { componentElements.add(componentElement); } public Node createNode() { ComponentNode cn = new ComponentNode(); for(ComponentElement element : componentElements) { cn.add(element.createComponent(), element.getLabel()); } return cn; } } private abstract class SplitterElement extends NodeElement { private List splits; protected SplitterElement(List splits) { this.splits = splits; } public List getSplits() { return splits; } } private class HorizontalSplitterElement extends SplitterElement { public HorizontalSplitterElement(List splits) { super(splits); } public Node createNode() { return new HorizontalSplitterNode(createChildNodes(), getSplits()); } } private class VerticalSplitterElement extends SplitterElement { public VerticalSplitterElement(List splits) { super(splits); } public Node createNode() { return new VerticalSplitterNode(createChildNodes(), getSplits()); } } private class ComponentElement { private String label; private Map properties; public ComponentElement(String label) { this.label = label; properties = new HashMap(); } public String getLabel() { return label; } public Map getProperties() { return properties; } public void putProperty(String id, String val) { properties.put(id, val); } public JComponent createComponent() { return componentFactory.createComponent(properties); } } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/NodeSerialiser.java000066400000000000000000000057131247715006500251030ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import java.io.Writer; import java.io.IOException; import com.sun.org.apache.xml.internal.serialize.OutputFormat; import com.sun.org.apache.xml.internal.serialize.XMLSerializer; import org.w3c.dom.Document; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 26-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * Given a node tree, a NodeSerialiser saves the node tree to * an node descriptor XML format. */ public class NodeSerialiser { private Node node; private ComponentPropertiesFactory factory; private Writer writer; /** * Serialises the specified node to a node descriptor using the specified writet. * @param node The node to be serialised. * @param factory The ComponentPropertiesFactory which should be used to * generate a set of properties for a given component which can be used to reanimate the * component as the descriptor is read from a Reader. * @param writer The Writer which the node descriptor should be written to. */ public NodeSerialiser(Node node, ComponentPropertiesFactory factory, Writer writer) { this.node = node; this.factory = factory; this.writer = writer; } public void serialise() throws ParserConfigurationException, IOException { OutputFormat of = new OutputFormat(); of.setIndent(4); Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); SerialisationNodeVisitor visitor = new SerialisationNodeVisitor(doc, factory); node.accept(visitor); XMLSerializer serializer = new XMLSerializer(writer, of); serializer.serialize(doc); } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/NodeVisitor.java000066400000000000000000000027721247715006500244420ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 25-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public interface NodeVisitor { public void visit(ComponentNode componentNode); public void visit(VerticalSplitterNode verticalSplitterNode); public void visit(HorizontalSplitterNode horizontalSplitterNode); } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/SerialisationNodeVisitor.java000066400000000000000000000102031247715006500271550ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import org.w3c.dom.Element; import org.w3c.dom.Document; import javax.swing.*; import java.util.List; import java.util.Stack; import java.util.Map; import java.awt.*; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 25-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public class SerialisationNodeVisitor extends TraversalNodeVisitor { private Document doc; private Stack elementStack; private ComponentPropertiesFactory componentPropertiesFactory; public SerialisationNodeVisitor(Document doc, ComponentPropertiesFactory factory) { this.doc = doc; this.componentPropertiesFactory = factory; elementStack = new Stack(); Element element = doc.createElement("layout"); doc.appendChild(element); elementStack.push(element); } public void visit(ComponentNode componentNode) { super.visit(componentNode); Element element = doc.createElement(Vocabulary.COMPONENT_NODE); elementStack.peek().appendChild(element); for(JComponent component : componentNode.getComponents()) { Element componentElement = doc.createElement(Vocabulary.COMPONENT); element.appendChild(componentElement); componentElement.setAttribute(Vocabulary.LABEL, componentNode.getLabel(component)); Map properties = getProperties(component); for(String key : properties.keySet()) { Element propertyElement = doc.createElement(Vocabulary.PROPERTY); componentElement.appendChild(propertyElement); propertyElement.setAttribute(Vocabulary.ID, key); propertyElement.setAttribute(Vocabulary.VALUE, properties.get(key)); } } } public void visit(VerticalSplitterNode verticalSplitterNode) { Element element = doc.createElement(Vocabulary.VERTICAL_SPLITTER_NODE); element.setAttribute(Vocabulary.SPLITS, getSplitAttributeValue(verticalSplitterNode.getSplits())); elementStack.peek().appendChild(element); elementStack.push(element); super.visit(verticalSplitterNode); elementStack.pop(); } public void visit(HorizontalSplitterNode horizontalSplitterNode) { Element element = doc.createElement(Vocabulary.HORIZONTAL_SPLITTER_NODE); element.setAttribute(Vocabulary.SPLITS, getSplitAttributeValue(horizontalSplitterNode.getSplits())); elementStack.peek().appendChild(element); elementStack.push(element); super.visit(horizontalSplitterNode); elementStack.pop(); } protected Map getProperties(JComponent component) { return componentPropertiesFactory.getProperties(component); } private String getSplitAttributeValue(List splits) { StringBuilder sb = new StringBuilder(); for(double d : splits) { sb.append(d); sb.append(" "); } return sb.toString().trim(); } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/Splitter.java000066400000000000000000000117741247715006500240050ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * The base class of horizontal and vertical splitters */ public abstract class Splitter extends JPanel { public static final int SPLITTER_WIDTH = 6; private SplitterNode node; private Node child0; private Node child1; Point startPoint; Point endPoint; private boolean mouseDown; private Cursor defaultCursor; protected Splitter(SplitterNode node, Node child0, Node child1) { this.node = node; this.child0 = child0; this.child1 = child1; setOpaque(true); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { setBackground(Color.GRAY); mouseDown = true; startDragging(e.getPoint()); } public void mouseReleased(MouseEvent e) { setBackground(null); mouseDown = false; endDragging(e.getPoint()); if(getMousePosition() == null) { restoreDefaultCursor(); } } public void mouseEntered(MouseEvent e) { defaultCursor = getCursor(); setSplitterCursor(); } public void mouseExited(MouseEvent e) { if (!mouseDown) { restoreDefaultCursor(); } } }); addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { Point p = SwingUtilities.convertPoint(Splitter.this, e.getPoint(), getParent()); setLocation(p); } }); } protected abstract void setSplitterCursor(); protected void restoreDefaultCursor() { setCursor(defaultCursor); } public void setLocation(int x, int y) { Point minLoc = getMinLocation(); Point maxLoc = getMaxLocation(); if(x < minLoc.x) { x = minLoc.x; } if(y < minLoc.y) { y = minLoc.y; } if(x > maxLoc.x) { x = maxLoc.x; } if(y > maxLoc.y) { y = maxLoc.y; } super.setLocation(x, y); } public SplitterNode getNode() { return node; } public Node getChild0() { return child0; } public Node getChild1() { return child1; } public abstract void resetBounds(); public abstract Point getMaxLocation(); public abstract Point getMinLocation(); public void startDragging(Point pt) { startPoint = getLocation(); } protected abstract int convertToLocation(Point pt); protected abstract int getSpan(Node child, Component parent, boolean includingSplitter); public void endDragging(Point pt) { endPoint = getLocation(); // Work out the new child splits int delta = convertToLocation(endPoint) - convertToLocation(startPoint); // Normalise the delta against the total height out the children int totalChildSpan = getSpan(getChild0(), getParent(), false) + getSpan(getChild1(), getParent(), false); double span = getNode().getSplit(getChild0()) + getNode().getSplit(getChild1()); double splitterDelta = (span * delta) / (totalChildSpan); double split0 = (getNode().getSplit(getChild0()) + splitterDelta); double split1 = (getNode().getSplit(getChild1()) - splitterDelta); getNode().setSplit(getChild0(), split0); getNode().setSplit(getChild1(), split1); getParent().validate(); } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/SplitterNode.java000066400000000000000000000252351247715006500246100ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import java.util.*; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * A splitter node contains zero or more child nodes. The child nodes * are split in either a vertical or horizontal direction by splitters * (splitters are the components that can be dragged about in the UI). * Each child node has a particular split value, which is used to determine * the proportion of the parent node which the child node takes up. The * split value is not a percentage of the parent, rather it is a weighting and the percentage * is determined from the total child weighting. For example if a node had three children * with splits of 2.0, 2.0 and 4.0 then the child nodes would occupy 0.25, 0.25 and 0.5 * of the parent space respectively. */ public abstract class SplitterNode extends Node { private List children; private Map nodeSplits; private List splitters; public static final int HORIZONTAL_SPLITTER = 0; public static final int VERTICAL_SPLITTER = 1; /** * Creates a splitter node that contains the specified children. * @param children The children. * @param splits The splits of the children. The number of splits must * be equal to the number of children. It is not required that the sum of the splits * is a particular value. * @throws IllegalArgumentException if the number of splits is not equal to * the number of children. */ public SplitterNode(List children, List splits) { if (children.size() != splits.size()) { throw new IllegalArgumentException("The number of splits must correspond to the number of children"); } this.children = new ArrayList(children); nodeSplits = new IdentityHashMap(); int index = 0; for (Node node : children) { node.setParent(this); nodeSplits.put(node, splits.get(index)); index++; } createSplitters(); } /** * Gets the split of the specified node. This node * must be a child node. * @param node The Node. * @return The split. * */ public double getSplit(Node node) { return nodeSplits.get(node); } /** * Gets the child node splits. * @return A list of child node splits */ public List getSplits() { List splits = new ArrayList(); for (Node curNode : getVisibleChildren()) { splits.add(nodeSplits.get(curNode)); } return splits; } /** * Sets the split of a particular child node. * @param node The child node whose split should be set. * @param split The value of the split. */ public void setSplit(Node node, double split) { nodeSplits.put(node, split); } /** * Gets the split of the specified node, normalised * against the span of the visible children. * @param node The node whose normalised split it * to be obtained. * @return The normalised split of the specified node */ public double getNormalisedSplit(Node node) { double split = nodeSplits.get(node); return split / getChildSpan(); } /** * Gets the sum of the visible child node splits. * @return The sum of the splits */ public double getChildSpan() { double span = 0.0; for (Node node : getVisibleChildren()) { span += nodeSplits.get(node); } return span; } /** * Gets a list of visible child nodes. * @return The list of children. */ public List getVisibleChildren() { List visibleChildren = new ArrayList(); for (Node curChild : children) { if (curChild.isVisible()) { visibleChildren.add(curChild); } } return visibleChildren; } /** * Determines if this node is visible. A splitter node is * deemed to be visible if at least one child is visible. * @return true if this splitter node is visible * or false if it is not visible. */ public boolean isVisible() { // We are visible if at least one of our children is visible for (Node node : children) { if (node.isVisible()) { return true; } } return false; } private void createSplitters() { splitters = new ArrayList(); splitters.clear(); List visibleChildren = getVisibleChildren(); for (int i = 0; i < visibleChildren.size() - 1; i++) { Node child0 = visibleChildren.get(i); Node child1 = visibleChildren.get(i + 1); splitters.add(createSplitter(child0, child1)); } } /** * Creates a splitter of the type (horizontal or vertical) that * is appropriate for this type of splitter node. * @param child0 The left/top child * @param child1 The right/bottom child * @return A splitter node which splits the left/top with the right/bottom */ public abstract Splitter createSplitter(Node child0, Node child1); public final List getSplitters() { if (splitters == null) { createSplitters(); } return splitters; } /** * Adds a child of this node. * @param child The child node to be added * @param index The position of the child node. * @param split The amount/weighting of parent node that the child node should * receive */ protected void addChild(Node child, int index, double split) { children.add(index, child); nodeSplits.put(child, split); child.setParent(this); } public void addChild(Node child, double split) { children.add(child); nodeSplits.put(child, split); child.setParent(this); notifyStateChange(); } public void removeChild(Node child) { children.remove(child); nodeSplits.remove(child); child.setParent(null); if (children.isEmpty()) { remove(); } notifyStateChange(); } public abstract boolean isSplitterDirection(int direction); /** * Inserts a node before (left of or top of) a given node by splitting the inserted * node with the given node. * @param insert The node to be inserted * @param before The node that the inserted node will be split with. * @param direction The direction of the split */ public void insertNodeBefore(Node insert, Node before, int direction) { if (isSplitterDirection(direction)) { double split = getSplit(before) / 2; setSplit(before, split); addChild(insert, children.indexOf(before), split); } else { pushDown(before, insert, before); } notifyStateChange(); } /** * Inserts a node after (right of or bottom of) a given node by splitting the inserted * node with the given node. * @param insert The node to be inserted * @param after The node that the inserted node will be split with. * @param direction The direction of the split */ public void insertNodeAfter(Node insert, Node after, int direction) { if (isSplitterDirection(direction)) { double split = getSplit(after) / 2; setSplit(after, split); addChild(insert, children.indexOf(after) + 1, split); } else { pushDown(after, after, insert); } notifyStateChange(); } /** * Inserts a node after (right of or bottom of) a given node by splitting the inserted * node with the given node. * @param insert The node to be inserted * @param after The node that the inserted node will be split with. * @param split The weight */ public void insertNodeAfter(Node insert, Node after, double split) { addChild(insert, children.indexOf(after) + 1, split); notifyStateChange(); } /** * Inserts a node after (right of or bottom of) a given node by splitting the inserted * node with the given node. * @param insert The node to be inserted. * @param index The index * @param split The split */ public void insertNodeAt(Node insert, int index, double split) { addChild(insert, index, split); notifyStateChange(); } protected void stateChanged() { splitters = null; } /** * Replaces a child node with another node * @param current The child node which should be replaced * @param with The node that the child node should be replaced with */ public void replaceChild(Node current, Node with) { double currentSplit = nodeSplits.get(current); int index = children.indexOf(current); children.remove(current); addChild(with, index, currentSplit); notifyStateChange(); } protected abstract SplitterNode createPerpendicularSplitterNode(List children, List splits); private SplitterNode pushDown(Node existingChild, Node node0, Node node1) { double split = getSplit(existingChild) / 2; SplitterNode sn = createPerpendicularSplitterNode(Arrays.asList(node0, node1), Arrays.asList(split, split)); replaceChild(existingChild, sn); return sn; } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/TraversalNodeVisitor.java000066400000000000000000000034331247715006500263210ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 25-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public class TraversalNodeVisitor implements NodeVisitor { public void visit(ComponentNode componentNode) { } public void visit(VerticalSplitterNode verticalSplitterNode) { for(Node curChild : verticalSplitterNode.getVisibleChildren()) { curChild.accept(this); } } public void visit(HorizontalSplitterNode horizontalSplitterNode) { for(Node curChild : horizontalSplitterNode.getVisibleChildren()) { curChild.accept(this); } } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/UIComponentFactory.java000066400000000000000000000047711247715006500257260ustar00rootroot00000000000000package org.coode.mdock; import javax.swing.*; import javax.swing.border.Border; import javax.swing.plaf.TabbedPaneUI; import javax.swing.plaf.basic.BasicTabbedPaneUI; import java.awt.*; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Author: Matthew Horridge * The University Of Manchester * Bio-Health Informatics Group * Date: 01-May-2007 */ public class UIComponentFactory { private static UIComponentFactory instance; public static synchronized UIComponentFactory getInstance() { if(instance == null) { instance = new UIComponentFactory(); } return instance; } /** * Creates the tabbed pane which is used to stack multiple components * within a single node. The default implementation returns an instance * of ComponentNodeTabbedPane. * @return The tabbed pane. */ public TabbedPaneUI createComponentNodeTabbedPaneUI() { return new BasicTabbedPaneUI(); } /** * Creates the border which surrounds component nodes. By default, * this is a light gray line border. * @return The border, or null if there shouldn't be a * border around component nodes. */ public Border createComponentNodeBorder() { return BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(Color.LIGHT_GRAY), BorderFactory.createEmptyBorder(3, 3, 3, 3)); } public static synchronized void setInstance(UIComponentFactory factory) { instance = factory; } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/Util.java000066400000000000000000000110061247715006500231000ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import javax.swing.*; import java.awt.*; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 24-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public class Util { public static int getX(Node node, Component c, boolean includeSplitter) { int x = (int) Math.round((node.getGloballyNormalisedXLocation() * c.getWidth())); if(includeSplitter) { x = x + Splitter.SPLITTER_WIDTH / 2; } return x; } public static int getY(Node node, Component c, boolean includeSplitter) { int y = (int) Math.round((node.getGloballyNormalisedYLocation() * c.getHeight())); if(includeSplitter) { y = y + Splitter.SPLITTER_WIDTH / 2; } return y; } public static int getWidth(Node node, Component c, boolean includeSplitter) { int w = (int) Math.round((node.getGloballyNormalisedWidth() * c.getWidth())); if(includeSplitter) { w = w - Splitter.SPLITTER_WIDTH; } return w; } public static int getHeight(Node node, Component c, boolean includeSplitter) { int h = (int) Math.round((node.getGloballyNormalisedHeight() * c.getHeight())); if(includeSplitter) { h = h - Splitter.SPLITTER_WIDTH; } return h; } public static Rectangle getBounds(Node node, Component c, boolean includeSplitter) { return new Rectangle(getX(node, c, includeSplitter), getY(node, c, includeSplitter), getWidth(node, c, includeSplitter), getHeight(node, c, includeSplitter)); } public static SplitterNode getDeepestSplitterNode(SplitterNode rootNode, Component c, Point pt) { SplitterNode deepestNode = null; Rectangle bounds = getBounds(rootNode, c, false); if(bounds.contains(pt)) { deepestNode = rootNode; for(Node curChild : rootNode.getVisibleChildren()) { if (curChild instanceof SplitterNode) { SplitterNode n = getDeepestSplitterNode((SplitterNode) curChild, c, pt); if(n != null) { return n; } } } } else { return null; } return deepestNode; } public static Node getDeepestNode(Node rootNode, Component c, Point pt) { Node deepestNode = null; Rectangle bounds = getBounds(rootNode, c, false); if(bounds.contains(pt)) { deepestNode = rootNode; if (rootNode instanceof SplitterNode) { for(Node curChild : ((SplitterNode) rootNode).getVisibleChildren()) { Node n = getDeepestNode(curChild, c, pt); if(n != null) { return n; } } } } return deepestNode; } public static void bringToFront(JComponent component) { Component parent = component.getParent(); Component child = component; while(parent != null) { if(parent instanceof JTabbedPane) { ((JTabbedPane) parent).setSelectedComponent(child); } child = parent; parent = parent.getParent(); } } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/VerticalSplitter.java000066400000000000000000000053151247715006500254710ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import java.awt.*; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 24-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) */ public class VerticalSplitter extends Splitter { public VerticalSplitter(SplitterNode node, Node child0, Node child1) { super(node, child0, child1); } public void resetBounds() { // Set the bounds int x = Util.getX(getChild1(), getParent(), false) - SPLITTER_WIDTH / 2 + 1; int y = Util.getY(getChild1(), getParent(), false) + SPLITTER_WIDTH / 2 + 1; int h = Util.getHeight(getChild1(), getParent(), false) - SPLITTER_WIDTH - 2; int w = Splitter.SPLITTER_WIDTH - 2; setBounds(x, y, w, h); } public Point getMaxLocation() { int x = Util.getX(getChild1(), getParent(), false) - SPLITTER_WIDTH / 2; int y = Util.getY(getChild1(), getParent(), false) + SPLITTER_WIDTH / 2; int w = Util.getWidth(getChild1(), getParent(), false); return new Point(x + w, y); } public Point getMinLocation() { int x = Util.getX(getChild0(), getParent(), false); int y = Util.getY(getChild0(), getParent(), false) + SPLITTER_WIDTH / 2; return new Point(x, y); } protected int convertToLocation(Point pt) { return pt.x; } protected int getSpan(Node child, Component parent, boolean includingSplitter) { return Util.getWidth(child, parent, includingSplitter); } protected void setSplitterCursor() { setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/VerticalSplitterNode.java000066400000000000000000000062011247715006500262720ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import java.util.List; import java.util.Arrays; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * A nod which contains child nodes which are split with vertical splitters */ public class VerticalSplitterNode extends SplitterNode { public VerticalSplitterNode(List children, List splits) { super(children, splits); } protected double getGloballyNormalisedWidth(Node child) { // We affect the width of our children. The globally normalised // width of one of our children, is our globally normalised width // multiplied by the normalised split of the child return getGloballyNormalisedWidth() * getNormalisedSplit(child); } public double getGloballyNormalisedXLocation(Node child) { // We affect the X location of our child nodes // Calculate the child positions relative to ours double xLoc = getGloballyNormalisedXLocation(); for(Node curChild : getVisibleChildren()) { if (curChild == child) { return xLoc; } else { xLoc += getGloballyNormalisedWidth(curChild); } } return 0.0; } public boolean isSplitterDirection(int direction) { return VERTICAL_SPLITTER == direction; } public Splitter createSplitter(Node child0, Node child1) { return new VerticalSplitter(this, child0, child1); } protected SplitterNode createPerpendicularSplitterNode(List children, List splits) { return new HorizontalSplitterNode(children, splits); } public SplitterNode pushDown(Node existingChild, List children) { HorizontalSplitterNode vsn = new HorizontalSplitterNode(children, Arrays.asList(0.5, 0.5)); replaceChild(existingChild, vsn); return vsn; } public void accept(NodeVisitor visitor) { visitor.visit(this); } } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/Vocabulary.java000066400000000000000000000046571247715006500243100ustar00rootroot00000000000000package org.coode.mdock; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 25-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * Vocabulary used for serialising descriptions of node panels */ public interface Vocabulary { /** * Represents an element containing information about a component node */ public static final String COMPONENT_NODE = "CNode"; /** * Represents an element containing information about a vertical splitter node */ public static final String VERTICAL_SPLITTER_NODE = "VSNode"; /** * Represents an element containing information about a horrizontal splitter node */ public static final String HORIZONTAL_SPLITTER_NODE = "HSNode"; /** * Represents an element containing information about a component that resides in a component node */ public static final String COMPONENT = "Component"; /** * Represents a list of splits */ public static final String SPLITS = "splits"; /** * An attribute that hold information about the label for a component in a component node. */ public static final String LABEL = "label"; public static final String PROPERTY = "Property"; public static final String VALUE = "value"; public static final String ID = "id"; } mdock-mdock-2.0.1/src/main/java/org/coode/mdock/examples/000077500000000000000000000000001247715006500231405ustar00rootroot00000000000000mdock-mdock-2.0.1/src/main/java/org/coode/mdock/examples/ExampleFrame.java000066400000000000000000000136051247715006500263560ustar00rootroot00000000000000package org.coode.mdock.examples; /* * Copyright (C) 2007, University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship * of the modifications may be determined from the ChangeLog placed at * the end of this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import org.coode.mdock.*; import javax.swing.*; import javax.xml.parsers.ParserConfigurationException; import java.util.*; import java.awt.event.*; import java.io.IOException; import java.io.StringWriter; import java.io.StringReader; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm * * Developed as part of the CO-ODE project (http://www.co-ode.org) * * Provides a very simple example of how to use a node panel * and a dynamic config panel to create and arrange components * in the node panel. */ public class ExampleFrame extends JFrame { private JMenu menu; private NodePanel nodePanel; private SplitterNode rootNode; /** * The panel which is used to configure components in the * node panel. */ private DynamicConfigPanel dynamicConfigPanel; public ExampleFrame() { createMenuBar(); // The node which will be the root of the node panel. In this case, we // simply want an empty node. rootNode = new VerticalSplitterNode(new ArrayList(), new ArrayList()); // The component that contains the "tree map" layout of the various // components nodePanel = new NodePanel(rootNode); setContentPane(nodePanel); // The panel which will handle the "drag and drop" of new nodes. dynamicConfigPanel = new DynamicConfigPanel(nodePanel); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private void createMenuBar() { menu = new JMenu("Nodes"); JMenuBar menuBar = new JMenuBar(); menuBar.add(menu); setJMenuBar(menuBar); menu.add(new AbstractAction("Add...") { public void actionPerformed(ActionEvent e) { addNewComponent(); } }); menu.add(new AbstractAction("Dump") { public void actionPerformed(ActionEvent e) { dumpAndReanimate(); } }); } private void dumpAndReanimate() { try { StringWriter sw = new StringWriter(); NodeSerialiser serialiser = new NodeSerialiser(rootNode, new ComponentPropertiesFactory() { public Map getProperties(JComponent component) { Map map = new HashMap(); map.put("class", component.getClass().getName()); return map; } }, sw); serialiser.serialise(); System.out.println(sw.getBuffer().toString()); StringReader sr = new StringReader(sw.getBuffer().toString()); NodeReanimator reanimator = new NodeReanimator(sr, new ComponentFactory() { public JComponent createComponent(Map properties) { String cls = properties.get("class"); try { return (JComponent) Class.forName(cls).newInstance(); } catch (InstantiationException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } return new JButton("Error"); } }); SplitterNode sn = reanimator.getRootNode(); NodePanel np = new NodePanel(sn); JFrame f = new JFrame(); f.setContentPane(np); f.setVisible(true); } catch (ParserConfigurationException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } private void addNewComponent() { final JComponent comp = createDummyComponent(); final JMenuItem item = new JMenuItem(new AbstractAction("Remove " + comp.hashCode()) { public void actionPerformed(ActionEvent e) { comp.getParent().remove(comp); nodePanel.rebuild(); setEnabled(false); } }); menu.add(item); dynamicConfigPanel.setCurrentComponent(comp, "Text Area"); dynamicConfigPanel.activate(); } private static JComponent createDummyComponent() { final JTextArea textArea = new JTextArea(); final JScrollPane sp = new JScrollPane(textArea); for (int i = 0; i < 30; i++) { textArea.append("wfukhwe w erlfjh jwhegr fhyyg werr\n"); } return sp; } public static void main(String[] args) { JFrame f = new ExampleFrame(); f.setSize(800, 600); f.setVisible(true); } } mdock-mdock-2.0.1/src/test/000077500000000000000000000000001247715006500154575ustar00rootroot00000000000000mdock-mdock-2.0.1/src/test/java/000077500000000000000000000000001247715006500164005ustar00rootroot00000000000000mdock-mdock-2.0.1/src/test/java/org/000077500000000000000000000000001247715006500171675ustar00rootroot00000000000000mdock-mdock-2.0.1/src/test/java/org/coode/000077500000000000000000000000001247715006500202605ustar00rootroot00000000000000mdock-mdock-2.0.1/src/test/java/org/coode/mdock/000077500000000000000000000000001247715006500213555ustar00rootroot00000000000000mdock-mdock-2.0.1/src/test/java/org/coode/mdock/RootNodeTestCase.java000066400000000000000000000112501247715006500254040ustar00rootroot00000000000000package org.coode.mdock; import org.junit.Test; import javax.swing.*; import java.util.Arrays; import static junit.framework.Assert.assertEquals; /** * Author: Matthew Horridge * The University Of Manchester * Medical Informatics Group * Date: 23-Sep-2006 * * matthew.horridge@cs.man.ac.uk * www.cs.man.ac.uk/~horridgm */ public class RootNodeTestCase { @Test public void testComponentNode() { ComponentNode node = new ComponentNode(); assertEquals(node.getGloballyNormalisedWidth(), 1.0); assertEquals(node.getGloballyNormalisedHeight(), 1.0); } @Test public void testVerticslSplitter() { ComponentNode child0 = new ComponentNode(); child0.add(new JButton("Child0"), "Child0"); ComponentNode child1 = new ComponentNode(); child1.add(new JButton("Child1"), "Child1"); ComponentNode child2 = new ComponentNode(); child2.add(new JButton("Child2"), "Child2"); VerticalSplitterNode verticalSplitterNode = new VerticalSplitterNode( Arrays.asList(child0, child1, child2), Arrays.asList(0.5, 1.5, 2.0)); assertEquals(verticalSplitterNode.getGloballyNormalisedWidth(), 1.0); assertEquals(verticalSplitterNode.getGloballyNormalisedHeight(), 1.0); assertEquals(verticalSplitterNode.getSplit(child0), 0.5); assertEquals(verticalSplitterNode.getSplit(child1), 1.5); assertEquals(verticalSplitterNode.getSplit(child2), 2.0); assertEquals(verticalSplitterNode.getChildSpan(), 4.0); assertEquals(verticalSplitterNode.getNormalisedSplit(child0), (0.5 / 4.0)); assertEquals(verticalSplitterNode.getNormalisedSplit(child1), (1.5 / 4.0)); assertEquals(verticalSplitterNode.getNormalisedSplit(child2), (2.0 / 4.0)); } @Test public void testHorizontalSplitter() { ComponentNode child0 = new ComponentNode(); child0.add(new JButton("Child0"), "Child0"); ComponentNode child1 = new ComponentNode(); child1.add(new JButton("Child1"), "Child1"); ComponentNode child2 = new ComponentNode(); child2.add(new JButton("Child2"), "Child2"); HorizontalSplitterNode horizontalSplitterNode = new HorizontalSplitterNode( Arrays.asList(child0, child1, child2), Arrays.asList(0.5, 1.5, 2.0)); assertEquals(horizontalSplitterNode.getGloballyNormalisedWidth(), 1.0); assertEquals(horizontalSplitterNode.getGloballyNormalisedHeight(), 1.0); assertEquals(horizontalSplitterNode.getSplit(child0), 0.5); assertEquals(horizontalSplitterNode.getSplit(child1), 1.5); assertEquals(horizontalSplitterNode.getSplit(child2), 2.0); assertEquals(horizontalSplitterNode.getChildSpan(), 4.0); assertEquals(horizontalSplitterNode.getNormalisedSplit(child0), (0.5 / 4.0)); assertEquals(horizontalSplitterNode.getNormalisedSplit(child1), (1.5 / 4.0)); assertEquals(horizontalSplitterNode.getNormalisedSplit(child2), (2.0 / 4.0)); } @Test public void testNestedNodes() { ComponentNode child0 = new ComponentNode(); child0.add(new JButton("Child0"), "Child0"); ComponentNode child1 = new ComponentNode(); child1.add(new JButton("Child1"), "Child1"); ComponentNode child2 = new ComponentNode(); child2.add(new JButton("Child2"), "Child2"); VerticalSplitterNode vNode0 = new VerticalSplitterNode(Arrays.asList(child0, child1), Arrays.asList(0.4, 1.6)); assertEquals(vNode0.getGloballyNormalisedWidth(), 1.0); assertEquals(vNode0.getGloballyNormalisedHeight(), 1.0); assertEquals(child0.getGloballyNormalisedWidth(), 0.2); assertEquals(child0.getGloballyNormalisedHeight(), 1.0); assertEquals(child1.getGloballyNormalisedWidth(), 0.8); assertEquals(child1.getGloballyNormalisedHeight(), 1.0); HorizontalSplitterNode hNode0 = new HorizontalSplitterNode(Arrays.asList(vNode0, child2), Arrays.asList(0.5, 1.0)); assertEquals(hNode0.getGloballyNormalisedWidth(), 1.0); assertEquals(hNode0.getGloballyNormalisedHeight(), 1.0); assertEquals(vNode0.getGloballyNormalisedWidth(), 1.0); assertEquals(vNode0.getGloballyNormalisedHeight(), 1.0 / 3.0); assertEquals(child0.getGloballyNormalisedWidth(), 0.2); assertEquals(child0.getGloballyNormalisedHeight(), 1.0 / 3.0); assertEquals(child1.getGloballyNormalisedWidth(), 0.8); assertEquals(child1.getGloballyNormalisedHeight(), 1.0 / 3.0); assertEquals(child2.getGloballyNormalisedWidth(), 1.0); assertEquals(child2.getGloballyNormalisedHeight(), 2.0 / 3.0); } }