2013-10-26 19:38:02Morris

[JAVA] 結合套用 UML 模擬 - Composite Object



部落格專用相簿


[JAVA] 結合套用 UML 模擬 - Composite Object




- 增加 Composite Object 操作
- 增加 interface, 減少多餘的 instanceof 判斷
- 增加 區域選區, 採用半透明方式呈現

- 線段調整 function 發生 crash
- 刪除物件功能當前廢除, 下次版本更新




package package1;

public interface AttachToolSelected {
    public String getToolsSelected();
}

package package1;

import javax.swing.event.ListSelectionEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Vector;
import javax.swing.table.DefaultTableModel;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Point;
import java.awt.event.*;
import java.util.*;

public class ClassDiagram extends JPanel implements MouseReceiver,
        MouseSelected, QueryRoot {

    private JTextField className;
    private JTable attributeTable = null;
    private JTable methodTable = null;
    private MTableModel attributeModel = null;
    private MTableModel methodModel = null;
    // private JScrollPane s_pan = null;
    private int mouseState = 0;
    private JToolBar nameMenu;
    private JToolBar tableMenu;

    private ArrayList<Point> attachPoint;
    private ArrayList<Point> relativePoint;
    private ArrayList<Object> sourcePoint;

    private Point mousePt = null;

    ClassDiagram() {
        Font displayFont = new Font("Serif", Font.BOLD, 18);
        PassMouseEventListener pmlistener;
        ResizeBorder rborder = new ResizeBorder(Color.ORANGE, 5);
        DragObjectListener listener = new DragObjectListener();

        attachPoint = new ArrayList<Point>();
        relativePoint = new ArrayList<Point>();
        sourcePoint = new ArrayList<Object>();
        className = new JTextField("Morris");
        className.setBackground(new Color(255, 255, 185));
        className.setFont(displayFont);
        className.setHorizontalAlignment(JTextField.CENTER);
        nameMenu = createNameMenu();
        tableMenu = createTableMenu();

        this.setLayout(new GridBagLayout());
        GridBagConstraints GBC = new GridBagConstraints();
        GBC.insets = new Insets(1, 1, 1, 1);
        GBC.fill = GridBagConstraints.BOTH;
        GBC.anchor = GridBagConstraints.NORTHEAST;
        GBC.gridx = 0;
        GBC.gridy = 0;
        GBC.gridwidth = 1;
        GBC.gridheight = 1;
        GBC.weightx = 30;
        GBC.weighty = 30;
        pmlistener = new PassMouseEventListener();
        className.addMouseListener(pmlistener);
        className.addMouseMotionListener(pmlistener);
        this.add(className, GBC);

        TableColumnModel tcm;
        String[] choose = { "+", "#", "-", "~" };
        JComboBox combx = new JComboBox(choose);

        attributeModel = new MTableModel();
        attributeTable = new JTable(attributeModel);
        attributeTable.setBackground(new Color(255, 255, 185));
        tcm = attributeTable.getColumnModel();
        tcm.getColumn(0).setCellEditor(new DefaultCellEditor(combx));
        tcm.getColumn(0).setPreferredWidth(10);
        tcm.getColumn(1).setPreferredWidth(290);
        GBC = new GridBagConstraints();
        GBC.insets = new Insets(1, 1, 1, 1);
        GBC.fill = GridBagConstraints.BOTH;
        GBC.anchor = GridBagConstraints.NORTHEAST;
        GBC.gridx = 0;
        GBC.gridy = 1;
        GBC.gridwidth = 1;
        GBC.gridheight = 1;
        GBC.weightx = 30;
        GBC.weighty = 30;
        pmlistener = new PassMouseEventListener();
        attributeTable.addMouseListener(pmlistener);
        attributeTable.addMouseMotionListener(pmlistener);
        this.add(attributeTable, GBC);

        methodModel = new MTableModel();
        methodTable = new JTable(methodModel);
        methodTable.setBackground(new Color(255, 255, 185));
        tcm = methodTable.getColumnModel();
        tcm.getColumn(0).setCellEditor(new DefaultCellEditor(combx));
        tcm.getColumn(0).setPreferredWidth(10);
        tcm.getColumn(1).setPreferredWidth(290);
        GBC = new GridBagConstraints();
        GBC.insets = new Insets(1, 1, 1, 1);
        GBC.fill = GridBagConstraints.BOTH;
        GBC.anchor = GridBagConstraints.NORTHEAST;
        GBC.gridx = 0;
        GBC.gridy = 2;
        GBC.gridwidth = 1;
        GBC.gridheight = 5;
        GBC.weightx = 150;
        GBC.weighty = 150;
        pmlistener = new PassMouseEventListener();
        methodTable.addMouseListener(pmlistener);
        methodTable.addMouseMotionListener(pmlistener);
        this.add(methodTable, GBC);

        GBC = new GridBagConstraints();
        GBC.insets = new Insets(1, 1, 1, 1);
        GBC.fill = GridBagConstraints.BOTH;
        GBC.anchor = GridBagConstraints.NORTHEAST;
        GBC.gridx = 0;
        GBC.gridy = 7;
        GBC.gridwidth = 1;
        GBC.gridheight = 1;
        GBC.weightx = 20;
        GBC.weighty = 20;
        this.add(tableMenu, GBC);

        GBC = new GridBagConstraints();
        GBC.insets = new Insets(1, 1, 1, 1);
        GBC.fill = GridBagConstraints.BOTH;
        GBC.anchor = GridBagConstraints.NORTHEAST;
        GBC.gridx = 0;
        GBC.gridy = 8;
        GBC.gridwidth = 1;
        GBC.gridheight = 1;
        GBC.weightx = 20;
        GBC.weighty = 20;
        nameMenu.setFocusable(false);
        this.add(nameMenu, GBC);
        attributeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        attributeTable.addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent e) {
                methodTable.clearSelection();
                if (attributeTable.getSelectedRow() >= 0)
                    tableMenu.setVisible(true);
            }

            public void focusLost(FocusEvent e) {
                tableMenu.setVisible(false);
            }
        });
        methodTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        methodTable.addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent e) {
                attributeTable.clearSelection();
                if (methodTable.getSelectedRow() >= 0)
                    tableMenu.setVisible(true);
                tableMenu.setVisible(true);
            }

            public void focusLost(FocusEvent e) {
                tableMenu.setVisible(false);
            }
        });
        this.setSize(280, 280);
        this.setBorder(rborder);
        this.addMouseListener(listener);
        this.addMouseMotionListener(listener);
        this.setBackground(Color.ORANGE);
        pmlistener = new PassMouseEventListener();
        this.addMouseListener(pmlistener);
        this.addMouseMotionListener(pmlistener);
    }

    public Point convertPointOnRoot(Point pt) {
        return ((QueryRoot) this.getParent()).convertPointOnRoot(SwingUtilities
                .convertPoint(this, pt, this.getParent()));
    }

    public Point getPortXY(int port) {// absolute location.
        int[] dx = { this.getWidth() / 2, this.getWidth(), this.getWidth() / 2,
                0 };
        int[] dy = { 0, this.getHeight() / 2, this.getHeight(),
                this.getHeight() / 2 };
        Point absoluteLoc = convertPointOnRoot(new Point());
        return new Point(absoluteLoc.x + dx[port], absoluteLoc.y + dy[port]);
        // return new Point(this.getX() + dx[port], this.getY() + dy[port]);
    }

    public Point getRelativePortXY(int port) {// absolute location.
        int[] dx = { this.getWidth() / 2, this.getWidth(), this.getWidth() / 2,
                0 };
        int[] dy = { 0, this.getHeight() / 2, this.getHeight(),
                this.getHeight() / 2 };
        return new Point(dx[port], dy[port]);
    }

    public int getNearPortNumber(Point pt) {// pt : absolute location.
        int[] dx = { this.getWidth() / 2, this.getWidth(), this.getWidth() / 2,
                0 };
        int[] dy = { 0, this.getHeight() / 2, this.getHeight(),
                this.getHeight() / 2 };
        int mnDist = 0xfffffff, ret = 0;
        for (int i = 0; i < dx.length; i++) {
            if (Math.abs(this.getX() + dx[i] - pt.x)
                    + Math.abs(this.getY() + dy[i] - pt.y) < mnDist) {
                mnDist = Math.abs(this.getX() + dx[i] - pt.x)
                        + Math.abs(this.getY() + dy[i] - pt.y);
                ret = i;
            }
        }
        /* System.out.println(ret); */
        return ret;
    }

    public void addAttachPoint(Point ap, Point rp, Object obj) {
        /*
         * for (int i = 0; i < attachPoint.size(); i++) { Object o =
         * sourcePoint.get(i); if (o == obj) { relativePoint.remove(i);
         * relativePoint.add(i, rp); return; } }
         */
        attachPoint.add(ap);
        relativePoint.add(rp);
        sourcePoint.add(obj);
        /* System.out.println(attachPoint.size()); */
    }

    public void clearAttachPoint() {
        for (int i = 0; i < attachPoint.size(); i++) {
            Object o = sourcePoint.get(i);
            if (o instanceof LinkSegment) {
                ((LinkSegment) o).clearAttachObject(this);
            }
        }
    }

    public void removeAttachPoint(Object obj) {
        for (int i = 0; i < attachPoint.size(); i++) {
            Object o = sourcePoint.get(i);
            if (o == obj) {
                attachPoint.remove(i);
                relativePoint.remove(i);
                sourcePoint.remove(i);
            }
        }
    }

    public void adjustAttachPoint() {
        if (attachPoint == null)
            return;
        System.out.println("adjuestAttachPoint");
        for (int i = 0; i < attachPoint.size(); i++) {
            Point ap = attachPoint.get(i);
            Point rp = relativePoint.get(i);
            Object o = sourcePoint.get(i);
            if (o instanceof LinkSegment) {
                rp.x = Math.min(rp.x, this.getWidth());
                rp.y = Math.min(rp.y, this.getHeight());
                int portNumber = this.getNearPortNumber(new Point(this.getX()
                        + rp.x, this.getY() + rp.y));
                ((LinkSegment) o).adjustPoint(ap, this.getPortXY(portNumber));
            }
        }
        if (this.getParent() != null)
            ((JPanel) this.getParent()).updateUI();
    }

    public String toString() {
        return className.getText();
    }

    public void setMouseState(int val) {
        mouseState = val;
        /*
         * if (mouseState != 0) { ((PaintPanel)
         * (this.getParent())).setFocusPic(this); } else { ((PaintPanel)
         * (this.getParent())).setFocusPic(null); }
         */
    }

    public int getMouseState() {
        return mouseState;
    }

    void setToolBar(boolean val) {
        nameMenu.setVisible(val);
    }

    public String mouseOnWhere(Point e) {
        int width = (int) getBounds().getWidth();
        int height = (int) getBounds().getHeight();
        Point[] corner = { new Point(0, 0), new Point(width, 0),
                new Point(0, height), new Point(width, height) };
        int cornerIdx = -1;
        for (int i = 0; i < corner.length; i++) {
            if (Math.pow(e.x - corner[i].x, 2) + Math.pow(e.y - corner[i].y, 2) < 30 * 30)
                cornerIdx = i;
        }
        if (cornerIdx == -1)
            return "border";
        else
            return "corner" + cornerIdx;
    }

    private JToolBar createNameMenu() {
        JToolBar ret = new JToolBar();
        ImageIcon newAttrib = new ImageIcon("NewAttrib.png");
        ImageIcon newMethod = new ImageIcon("NewMethod.png");
        ImageIcon del = new ImageIcon("Del.png");
        ImageIcon clr = new ImageIcon("Clear.png");
        JButton btnAttrib = new JButton(newAttrib);
        JButton btnMethod = new JButton(newMethod);
        JButton btnDel = new JButton(del);
        JButton btnClr = new JButton(clr);
        btnAttrib.setBackground(null);
        btnAttrib.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                attributeTable.clearSelection();
                attributeModel.addRow("+", "AttributeName");
                methodTable.clearSelection();
                updateUI();
            }
        });
        btnMethod.setBackground(null);
        btnMethod.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                methodTable.clearSelection();
                methodModel.addRow("+", "MethodName()");
                attributeTable.clearSelection();
                updateUI();
            }
        });
        btnDel.setBackground(null);
        btnDel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int delIdx;
                delIdx = methodTable.getSelectedRow();
                methodModel.removeRow(delIdx);
                delIdx = attributeTable.getSelectedRow();
                attributeModel.removeRow(delIdx);
                updateUI();
            }
        });
        btnClr.setBackground(null);
        btnClr.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                methodTable.clearSelection();
                attributeTable.clearSelection();
                updateUI();
            }
        });
        ret.add(btnAttrib);
        ret.add(btnMethod);
        ret.add(btnDel);
        ret.add(btnClr);
        ret.setBackground(null);
        ret.setFloatable(false);
        ret.setVisible(false);
        return ret;
    }

    private JToolBar createTableMenu() {
        JToolBar ret = new JToolBar();
        ImageIcon publicImg = new ImageIcon("public.png");
        ImageIcon protectImg = new ImageIcon("protected.png");
        ImageIcon privateImg = new ImageIcon("private.png");
        ImageIcon packageImg = new ImageIcon("package.png");
        ImageIcon upImg = new ImageIcon("upitem.png");
        ImageIcon downImg = new ImageIcon("downitem.png");
        JButton btnPublic = new JButton(publicImg);
        JButton btnProtect = new JButton(protectImg);
        JButton btnPrivate = new JButton(privateImg);
        JButton btnPackage = new JButton(packageImg);
        JButton btnUp = new JButton(upImg);
        JButton btnDown = new JButton(downImg);
        btnPublic.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (attributeTable.getSelectedRow() >= 0) {
                    int rowIdx = attributeTable.getSelectedRow();
                    attributeModel.setValueAt("+", rowIdx, 0);
                }
                if (methodTable.getSelectedRow() >= 0) {
                    int rowIdx = methodTable.getSelectedRow();
                    methodModel.setValueAt("+", rowIdx, 0);
                }
            }
        });
        btnPublic.setBackground(null);
        btnProtect.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (attributeTable.getSelectedRow() >= 0) {
                    int rowIdx = attributeTable.getSelectedRow();
                    attributeModel.setValueAt("#", rowIdx, 0);
                }
                if (methodTable.getSelectedRow() >= 0) {
                    int rowIdx = methodTable.getSelectedRow();
                    methodModel.setValueAt("#", rowIdx, 0);
                }
            }
        });
        btnProtect.setBackground(null);
        btnPrivate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (attributeTable.getSelectedRow() >= 0) {
                    int rowIdx = attributeTable.getSelectedRow();
                    attributeModel.setValueAt("-", rowIdx, 0);
                }
                if (methodTable.getSelectedRow() >= 0) {
                    int rowIdx = methodTable.getSelectedRow();
                    methodModel.setValueAt("-", rowIdx, 0);
                }
            }
        });
        btnPrivate.setBackground(null);
        btnPackage.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (attributeTable.getSelectedRow() >= 0) {
                    int rowIdx = attributeTable.getSelectedRow();
                    attributeModel.setValueAt("~", rowIdx, 0);
                }
                if (methodTable.getSelectedRow() >= 0) {
                    int rowIdx = methodTable.getSelectedRow();
                    methodModel.setValueAt("~", rowIdx, 0);
                }
            }
        });
        btnPackage.setBackground(null);
        btnUp.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (attributeTable.getSelectedRow() > 0) {
                    int rowIdx = attributeTable.getSelectedRow();
                    Object obj0, obj1;
                    obj0 = attributeModel.getValueAt(rowIdx, 0);
                    obj1 = attributeModel.getValueAt(rowIdx, 1);
                    attributeModel.removeRow(rowIdx);
                    attributeModel.insertRow(rowIdx - 1, obj0, obj1);
                    attributeTable.setRowSelectionInterval(rowIdx - 1,
                            rowIdx - 1);
                }
                if (methodTable.getSelectedRow() > 0) {
                    int rowIdx = methodTable.getSelectedRow();
                    Object obj0, obj1;
                    obj0 = methodModel.getValueAt(rowIdx, 0);
                    obj1 = methodModel.getValueAt(rowIdx, 1);
                    methodModel.removeRow(rowIdx);
                    methodModel.insertRow(rowIdx - 1, obj0, obj1);
                    methodTable.setRowSelectionInterval(rowIdx - 1, rowIdx - 1);
                }
                updateUI();
            }
        });
        btnUp.setBackground(null);
        btnDown.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (attributeTable.getSelectedRow() < attributeTable
                        .getRowCount() - 1) {
                    int rowIdx = attributeTable.getSelectedRow();
                    if (rowIdx >= 0) {
                        Object obj0, obj1;
                        obj0 = attributeModel.getValueAt(rowIdx, 0);
                        obj1 = attributeModel.getValueAt(rowIdx, 1);
                        attributeModel.removeRow(rowIdx);
                        attributeModel.insertRow(rowIdx + 1, obj0, obj1);
                        attributeTable.setRowSelectionInterval(rowIdx + 1,
                                rowIdx + 1);
                    }
                }
                if (methodTable.getSelectedRow() < methodTable.getRowCount() - 1) {
                    int rowIdx = methodTable.getSelectedRow();
                    if (rowIdx >= 0) {
                        Object obj0, obj1;
                        obj0 = methodModel.getValueAt(rowIdx, 0);
                        obj1 = methodModel.getValueAt(rowIdx, 1);
                        methodModel.removeRow(rowIdx);
                        methodModel.insertRow(rowIdx + 1, obj0, obj1);
                        methodTable.setRowSelectionInterval(rowIdx + 1,
                                rowIdx + 1);
                    }
                }
                updateUI();
            }
        });
        btnDown.setBackground(null);
        ret.add(btnPublic);
        ret.add(btnProtect);
        ret.add(btnPrivate);
        ret.add(btnPackage);
        ret.add(btnUp);
        ret.add(btnDown);
        ret.setBackground(null);
        ret.setFloatable(false);
        ret.setVisible(false);
        return ret;
    }

    public boolean mouseMoved(MouseEvent e, Point pt) {
        return false;
    }

    public boolean mouseDragged(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseDragged(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        if (SwingUtilities.isLeftMouseButton(e)) {
            Component jl = (Component) e.getSource();
            String pos = this.mouseOnWhere(e.getPoint());
            Point newP = SwingUtilities.convertPoint(jl, e.getPoint(),
                    jl.getParent());
            if (pos.equals("border")) {
                System.out.println(newP + ", " + mousePt);
                jl.setLocation(jl.getX() + (newP.x - mousePt.x), jl.getY()
                        + (newP.y - mousePt.y));
                this.adjustAttachPoint();
            } else {
                if (this.getMouseState() == 3) {
                    Point[] XYweight = { new Point(1, 1), new Point(0, 1),
                            new Point(1, 0), new Point(0, 0) };
                    Point[] WHweight = { new Point(-1, -1), new Point(1, -1),
                            new Point(-1, 1), new Point(1, 1) };
                    int cornerIdx = Integer.parseInt(pos.substring(6));
                    int vx = newP.x - mousePt.x, vy = newP.y - mousePt.y;
                    jl.setBounds(jl.getX() + vx * XYweight[cornerIdx].x,
                            jl.getY() + vy * XYweight[cornerIdx].y,
                            jl.getWidth() + vx * WHweight[cornerIdx].x,
                            jl.getHeight() + vy * WHweight[cornerIdx].y);
                    this.adjustAttachPoint();
                }
            }
            mousePt = newP;
        }
        return false;
    }

    public boolean mouseClicked(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseClicked(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        if (SwingUtilities.isLeftMouseButton(e)) {
            if (e.getClickCount() == 2) {
                Component jl = (Component) e.getSource();
                String pos = this.mouseOnWhere(e.getPoint());
                if (pos.equals("border")) {
                } else {
                    /*
                     * this.setMouseState(1); jl.repaint();
                     */
                }
            }
        }
        return false;
    }

    public boolean mouseReleased(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseReleased(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        Component jl = (Component) e.getSource();
        if (this.getMouseState() == 3) {
            this.setMouseState(0);
            this.updateUI();
        }
        mousePt = null;
        return false;
    }

    public boolean mousePressed(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mousePressed(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        /* System.out.println("ssssssss" + pt); */
        if (SwingUtilities.isLeftMouseButton(e)) {
            Component jl = (Component) e.getSource();
            String pos = this.mouseOnWhere(e.getPoint());
            mousePt = SwingUtilities.convertPoint(jl, e.getPoint(),
                    jl.getParent());
            System.out.println(mousePt + "," + jl.getParent().getClass());
            if (!pos.equals("border")) {
                if (this.getMouseState() == 1)
                    this.setMouseState(3);
            }
        }
        return false;
    }

    public boolean mouseEntered(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseEntered(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        Component jl = (Component) e.getSource();
        this.setToolBar(true);
        return false;
    }

    public boolean mouseExited(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseExited(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        Component jl = (Component) e.getSource();
        if (!jl.contains(e.getPoint()))
            this.setToolBar(false);
        return false;
    }
    /*@Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }*/
}

class MTableModel extends AbstractTableModel {

    // private static final long serialVersionUID = -7495940408592595397L;

    private Vector content = null;

    private String[] title_name = { "TYPE", "NAME" };

    public MTableModel() {
        content = new Vector();
    }

    public MTableModel(int count) {
        content = new Vector(count);
    }

    public void insertRow(int row, Object obj0, Object obj1) {
        Vector v = new Vector(2);
        v.add(0, obj0);
        v.add(1, obj1);
        content.add(row, v);
    }

    public void addRow(Object obj0, Object obj1) {
        Vector v = new Vector(2);
        v.add(0, obj0);
        v.add(1, obj1);
        content.add(v);
    }

    public void removeRow(int row) {
        if (row < 0)
            return;
        content.remove(row);
    }

    public void removeRows(int row, int count) {
        for (int i = 0; i < count; i++) {
            if (content.size() > row) {
                content.remove(row);
            }
        }
    }

    public boolean isCellEditable(int rowIndex, int columnIndex) {
        if (columnIndex == 0)
            return false;
        return true;
    }

    public void setValueAt(Object value, int row, int col) {
        ((Vector) content.get(row)).remove(col);
        ((Vector) content.get(row)).add(col, value);
        this.fireTableCellUpdated(row, col);
    }

    public String getColumnName(int col) {
        return title_name[col];
    }

    public int getColumnCount() {
        return title_name.length;
    }

    public int getRowCount() {
        return content.size();
    }

    public Object getValueAt(int row, int col) {
        return ((Vector) content.get(row)).get(col);
    }

    public Class getColumnClass(int col) {
        return getValueAt(0, col).getClass();
    }
}

package package1;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import javax.swing.*;

import java.awt.Color;
import java.awt.Component;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Point;
import java.awt.event.*;
import java.util.*;

public class CompositePanel extends JPanel implements MouseReceiver,
        AttachToolSelected, MouseSelected, QueryRoot {
    private int mouseState = 0;
    private Point mousePt = null;

    CompositePanel(Component c[]) {
        Point lowerLeft, upperRight;
        lowerLeft = c[0].getLocation();
        upperRight = new Point(lowerLeft);
        for (int i = 0; i < c.length; i++) {
            lowerLeft.x = Math.min(lowerLeft.x, c[i].getX());
            lowerLeft.y = Math.min(lowerLeft.y, c[i].getY());
            upperRight.x = Math
                    .max(upperRight.x, c[i].getX() + c[i].getWidth());
            upperRight.y = Math.max(upperRight.y,
                    c[i].getY() + c[i].getHeight());
        }
        lowerLeft.x -= 20;
        lowerLeft.y -= 20;
        upperRight.x += 20;
        upperRight.y += 20;
        this.setLayout(null);
        this.setBounds(lowerLeft.x, lowerLeft.y, upperRight.x - lowerLeft.x,
                upperRight.y - lowerLeft.y);
        for (int i = 0; i < c.length; i++) {
            c[i].setLocation(c[i].getX() - lowerLeft.x, c[i].getY()
                    - lowerLeft.y);
            this.add(c[i]);
        }
        this.setBackground(new Color(39, 40, 34));
        DragObjectListener listener = new DragObjectListener();
        this.addMouseListener(listener);
        this.addMouseMotionListener(listener);
        ResizeBorder rborder = new ResizeBorder(new Color(230, 164, 63), 10);
        this.setBorder(rborder);
    }

    public Point convertPointOnRoot(Point pt) {
        return ((QueryRoot) this.getParent()).convertPointOnRoot(SwingUtilities
                .convertPoint(this, pt, this.getParent()));
    }

    public String getToolsSelected() {
        Component j1 = this.getParent();
        if (j1 instanceof AttachToolSelected)
            return ((AttachToolSelected) j1).getToolsSelected();
        else
            return null;
    }

    public int getMouseState() {
        return mouseState;
    }

    public void setMouseState(int val) {
        mouseState = val;
    }

    public String mouseOnWhere(Point e) {
        int width = (int) getBounds().getWidth();
        int height = (int) getBounds().getHeight();
        if (e.x > 20 && e.x < width - 20 && e.y > 20 && e.y < height - 20)
            return "inside";
        Point[] corner = { new Point(0, 0), new Point(width, 0),
                new Point(0, height), new Point(width, height) };
        int cornerIdx = -1;
        for (int i = 0; i < corner.length; i++) {
            if (Math.pow(e.x - corner[i].x, 2) + Math.pow(e.y - corner[i].y, 2) < 30 * 30)
                cornerIdx = i;
        }
        if (cornerIdx == -1)
            return "border";
        else
            return "corner" + cornerIdx;
    }

    public void adjustAttachPoint() {
        Component c[] = this.getComponents();
        for (int i = 0; i < c.length; i++) {
            if (c[i] instanceof CompositePanel)
                ((CompositePanel) c[i]).adjustAttachPoint();
            if (c[i] instanceof ClassDiagram)
                ((ClassDiagram) c[i]).adjustAttachPoint();
        }
    }

    public boolean mouseDragged(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseDragged(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        if (SwingUtilities.isLeftMouseButton(e)) {
            Component jl = this;
            String pos = this.mouseOnWhere(pt);
            Point newP = SwingUtilities.convertPoint(this, e.getPoint(),
                    this.getParent());
            System.out.println(pos + ", " + pt);
            if (this.getComponentAt(pt) != this)
                return false;
            if (pos.equals("inside")) {

            } else if (pos.equals("border")) {
                if (this.getMouseState() > 0)
                    this.setLocation(this.getX() + (newP.x - mousePt.x),
                            this.getY() + (newP.y - mousePt.y));
                adjustAttachPoint();
            } else {
                if (this.getMouseState() == 3) {
                    Point[] XYweight = { new Point(1, 1), new Point(0, 1),
                            new Point(1, 0), new Point(0, 0) };
                    Point[] WHweight = { new Point(-1, -1), new Point(1, -1),
                            new Point(-1, 1), new Point(1, 1) };
                    int cornerIdx = Integer.parseInt(pos.substring(6));
                    int vx = newP.x - mousePt.x, vy = newP.y - mousePt.y;
                    this.setBounds(jl.getX() + vx * XYweight[cornerIdx].x,
                            jl.getY() + vy * XYweight[cornerIdx].y,
                            jl.getWidth() + vx * WHweight[cornerIdx].x,
                            jl.getHeight() + vy * WHweight[cornerIdx].y);
                    adjustAttachPoint();
                }
            }
            mousePt = newP;
        }
        return false;
    }

    public boolean mouseClicked(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseClicked(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        if (SwingUtilities.isLeftMouseButton(e)) {
            if (e.getClickCount() == 2) {
                if (this.getToolsSelected() == "select") {
                    Component c[] = this.getComponents();
                    for (int i = 0; i < c.length; i++) {
                        if (c[i] instanceof MouseSelected)
                            ((MouseSelected) c[i]).setMouseState(0);
                    }
                    if (this.getComponentAt(pt) != this) {
                        Component cp = this.getComponentAt(pt);
                        if (cp instanceof MouseSelected)
                            ((MouseSelected) cp).setMouseState(1);
                    }
                    this.updateUI();
                }
            }
        }
        return false;
    }

    public boolean mouseMoved(MouseEvent e, Point pt) {
        return false;
    }

    public boolean mouseReleased(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseReleased(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        if (this.getMouseState() == 3) {
            this.setMouseState(0);
            this.updateUI();
        }
        mousePt = null;
        return false;
    }

    public boolean mousePressed(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mousePressed(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        System.out.println("Pressed");
        if (SwingUtilities.isLeftMouseButton(e)) {
            String pos = this.mouseOnWhere(pt);
            mousePt = SwingUtilities.convertPoint(this, e.getPoint(),
                    this.getParent());
            if (pos.indexOf("corner") >= 0) {
                if (this.getMouseState() == 1)
                    this.setMouseState(3);
            }
        }
        return false;
    }

    public boolean mouseEntered(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseEntered(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        return false;
    }

    public boolean mouseExited(MouseEvent e, Point pt) {
        if (this.getParent() instanceof MouseReceiver)
            ((MouseReceiver) this.getParent()).mouseExited(e,
                    SwingUtilities.convertPoint(this, pt, this.getParent()));
        return false;
    }
}

package package1;

import java.awt.Component;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputListener;

/**
 * more explain by Chinese language : http://javapub.iteye.com/blog/739146 &
 * http://hi.baidu.com/wwwpeng584/item/668f6ef7289020db6225d24a
 *
 * @author owner
 *
 */
public class DragObjectListener implements MouseInputListener {

    Point p = new Point(0, 0);

    public DragObjectListener() {

    }

    public void mouseMoved(MouseEvent e) {

    }

    public void mouseDragged(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl instanceof MouseReceiver) {
            ((MouseReceiver) jl).mouseDragged(e, e.getPoint());
        }
    }

    public void mouseReleased(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl instanceof MouseReceiver) {
            ((MouseReceiver) jl).mouseReleased(e, e.getPoint());
        }
    }

    public void mouseEntered(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl instanceof MouseReceiver) {
            ((MouseReceiver) jl).mouseEntered(e, e.getPoint());
        }
    }

    public void mouseExited(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl instanceof MouseReceiver) {
            ((MouseReceiver) jl).mouseExited(e, e.getPoint());
        }
    }

    public void mouseClicked(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl instanceof MouseReceiver) {
            ((MouseReceiver) jl).mouseClicked(e, e.getPoint());
        }
    }

    public void mousePressed(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl instanceof MouseReceiver) {
            ((MouseReceiver) jl).mousePressed(e, e.getPoint());
        }
    }
}

package package1;

import java.util.*;
import java.awt.*;

import javax.swing.*;

public class LinkSegment {
    private ArrayList<Point> segment;
    private boolean selected;
    private Object startPoint = null;
    private Object endPoint = null;
    private int headType;
    private int VHType = 0;

    LinkSegment(Point st, Point ed, int headType) {
        segment = new ArrayList<Point>();
        /* System.out.println("Segment " + st + "   " + ed); */
        segment.add(st);
        segment.add(new Point(st.x, st.y - 50));
        segment.add(new Point(ed.x, st.y - 50));
        segment.add(ed);
        this.headType = headType;
    }

    public void clearAttachObject(Object o) {
        if (startPoint == o)
            startPoint = null;
        if (endPoint == o)
            endPoint = null;
    }

    public void setAttachObject(int index, Object o) {
        if (index == 0) {
            if (startPoint != null) {
                if (startPoint instanceof ClassDiagram) {
                    ((ClassDiagram) startPoint).removeAttachPoint(this);
                }
            }
            startPoint = o;
        } else {
            if (endPoint != null) {
                if (endPoint instanceof ClassDiagram) {
                    ((ClassDiagram) endPoint).removeAttachPoint(this);
                }
            }
            endPoint = o;
        }
    }

    public int getSize() {
        return segment.size();
    }

    public String mouseOnWhere(Point e) {
        for (int i = 0; i < segment.size(); i++) {
            Point pt = segment.get(i);
            if ((pt.x - e.x) * (pt.x - e.x) + (pt.y - e.y) * (pt.y - e.y) < 20 * 20)
                return "point" + i;
        }
        for (int i = 0; i < segment.size(); i++) {
            Point pt = segment.get(i);
            Point nt = null;
            if (i + 1 < segment.size())
                nt = segment.get(i + 1);
            if (nt != null) {
                int area = Math.abs((pt.x - e.x) * (nt.y - e.y) - (pt.y - e.y)
                        * (nt.x - e.x)) / 2;
                double a = Math.hypot(pt.x - nt.x, pt.y - nt.y);
                double b = Math.hypot(pt.x - e.x, pt.y - e.y);
                double c = Math.hypot(e.x - nt.x, e.y - nt.y);
                double h = 2 * area / a;
                if (h < 10 && b * b < a * a + c * c && c * c < b * b + a * a) {
                    // System.out.println("line choose");
                    return "line" + i;
                }
            }
        }
        return "nop";
    }

    public void adjustPoint(Point pt, Point nextPos) {
        int vx = nextPos.x - pt.x;
        int vy = nextPos.y - pt.y;
        for (int i = 0; i < segment.size(); i++) {
            if (segment.get(i) == pt) {
                if ((i + VHType) % 2 == 0) {// on H-V
                    Point prev = null, next = null;
                    if (i - 1 > 0)
                        prev = segment.get(i - 1);
                    if (i + 1 < segment.size() - 1)
                        next = segment.get(i + 1);
                    if (prev != null) {
                        prev.y += vy;
                        pt.y = nextPos.y;
                    } else {
                        if (Math.abs(vy) > 15 && i - 1 >= 0) {// add a new node
                            pt.y = nextPos.y;
                            segment.add(i,
                                    new Point(segment.get(i - 1).x, pt.y));
                            VHType++;
                        }
                    }
                    if (next != null) {
                        next.x += vx;
                        pt.x = nextPos.x;
                    } else {
                        if (Math.abs(vx) > 15 && i + 1 < segment.size()) {
                            pt.x = nextPos.x;
                            segment.add(i + 1,
                                    new Point(pt.x, segment.get(i + 1).y));
                        }
                    }
                    if (i == 0)
                        pt.y = nextPos.y;
                    if (i == segment.size() - 1)
                        pt.x = nextPos.x;
                } else {// on V-H
                    Point prev = null, next = null;
                    if (i - 1 > 0)
                        prev = segment.get(i - 1);
                    if (i + 1 < segment.size() - 1)
                        next = segment.get(i + 1);
                    if (prev != null) {
                        prev.x += vx;
                        pt.x = nextPos.x;
                    } else {
                        if (Math.abs(vx) > 15 && i - 1 >= 0) {// add a new node
                            pt.x = nextPos.x;
                            segment.add(i,
                                    new Point(pt.x, segment.get(i - 1).y));
                            VHType++;
                        }
                    }
                    if (next != null) {
                        next.y += vy;
                        pt.y = nextPos.y;
                    } else {
                        if (Math.abs(vy) > 15 && i + 1 < segment.size()) {
                            pt.x = nextPos.x;
                            segment.add(i + 1, new Point(segment.get(i + 1).x,
                                    pt.y));
                        }
                    }
                    if (i == segment.size() - 1)
                        pt.y = nextPos.y;
                    if (VHType % 2 == 1 && i == 0)
                        pt.x = nextPos.x;
                }
                return;
            }
        }
    }

    public Point getPointAddr(int index) {
        return segment.get(index);
    }

    public boolean getSelected() {
        return selected;
    }

    public void setSelected(boolean val) {
        selected = val;
    }

    public void drawOnGraph(Graphics g) {
        Color color = new Color(253, 247, 217);
        g.setColor(color);
        for (int i = 0; i < segment.size(); i++) {
            Point pt = segment.get(i);
            Point nt = null;
            if (i + 1 < segment.size())
                nt = segment.get(i + 1);
            if (selected) {
                for (int r = 5; r < 10; r++)
                    g.drawOval(pt.x - r, pt.y - r, 2 * r, 2 * r);
            }
            if (nt != null) {
                Graphics2D g2d = (Graphics2D) g;
                g2d.setStroke(new BasicStroke(5.0f));
                if (i == segment.size() - 2) {
                    int mx, my;
                    double nx, ny;
                    nx = (nt.x - pt.x) / Math.hypot(nt.x - pt.x, nt.y - pt.y);
                    ny = (nt.y - pt.y) / Math.hypot(nt.x - pt.x, nt.y - pt.y);
                    int c1x, c1y, c2x, c2y;
                    mx = nt.x - (int) (20 * nx);
                    my = nt.y - (int) (20 * ny);
                    c1x = mx + (int) (15 * (ny));
                    c1y = my + (int) (15 * (-nx));
                    c2x = mx + (int) (15 * (-ny));
                    c2y = my + (int) (15 * (nx));
                    if (headType == 0) {
                        g2d.drawLine(mx, my, nt.x, nt.y);
                    } else if (headType == 1) {
                        g2d.drawLine(c1x, c1y, nt.x, nt.y);
                        g2d.drawLine(c2x, c2y, nt.x, nt.y);
                        g2d.drawLine(c1x, c1y, c2x, c2y);
                    } else if (headType == 2) {
                        mx = nt.x - (int) (35 * nx);
                        my = nt.y - (int) (35 * ny);
                        c1x = (mx + nt.x) / 2 + (int) (10 * (ny));
                        c1y = (my + nt.y) / 2 + (int) (10 * (-nx));
                        c2x = (mx + nt.x) / 2 + (int) (10 * (-ny));
                        c2y = (my + nt.y) / 2 + (int) (10 * (nx));
                        int xP[] = { mx, c1x, nt.x, c2x };
                        int yP[] = { my, c1y, nt.y, c2y };
                        g2d.drawPolygon(xP, yP, xP.length);
                    }
                    g2d.drawLine(pt.x, pt.y, mx, my);
                } else {
                    g2d.drawLine(pt.x, pt.y, nt.x, nt.y);
                }
            }
        }
    }
}

package package1;

import java.awt.*;
import javax.swing.*;

public class MainFrame extends JFrame {
    private static int WIDTH = 1000, HEIGHT = 600;

    MainFrame() {
        this.setTitle("LinkObject");
        WIDTH = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth()*4/5;
        HEIGHT = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight()*4/5;
        this.setSize(WIDTH, HEIGHT);
        //this.setExtendedState(JFrame.MAXIMIZED_BOTH);
        //this.setUndecorated(true);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(new MainPanel());
        this.setVisible(true);
    }

    public static void main(String[] args) {
        new MainFrame();
    }
}

package package1;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;

public class MainPanel extends JPanel implements AttachToolSelected {
    private static int WIDTH = 1000, HEIGHT = 600;
    private DefaultListModel listModel;
    private JList sampleJList;
    private PaintPanel samplePanel;
    private JMenuBar menuBar;

    private JMenuBar createMenuBar() {
        JMenuBar ret = new JMenuBar();
        JMenu menu = new JMenu("File");
        JMenuItem menuItem;
        menu.setMnemonic(KeyEvent.VK_F);
        menu.getAccessibleContext().setAccessibleDescription(
                "Dealing with Files");
        ret.add(menu);
        menuItem = new JMenuItem("New UML ...");
        menuItem.setMnemonic(KeyEvent.VK_U);
        menu.add(menuItem);
        menu = new JMenu("Edit");
        menuItem = new JMenuItem("Group");
        menuItem.setMnemonic(KeyEvent.VK_G);
        menuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                samplePanel.compositeSelectedObject();
            }
        });
        menu.add(menuItem);
        menuItem = new JMenuItem("Change Class Name");
        menu.add(menuItem);
        ret.add(menu);
        return ret;
    }

    MainPanel() {
        Font displayFont = new Font("Serif", Font.BOLD, 28);
        GridBagConstraints GBC;
        listModel = new DefaultListModel();
        listModel.addElement("select");
        listModel.addElement("association");
        listModel.addElement("general");
        listModel.addElement("composition");
        listModel.addElement("class");
        listModel.addElement("usecase");
        listModel.addElement("delete");
        sampleJList = new JList(listModel);
        sampleJList.setCellRenderer(new MRenderer());
        sampleJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        sampleJList.setSelectionBackground(null);
        sampleJList.setBackground(new Color(240, 240, 240));
        sampleJList.setFont(displayFont);
        sampleJList.setSelectedIndex(0);
        sampleJList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent listEvent) {
                boolean adjust = listEvent.getValueIsAdjusting();
                if (adjust == false)
                    return;
                JList list = (JList) listEvent.getSource();
                String selected = list.getSelectedValue().toString();
                if (selected.equals("delete")) {
                    if (samplePanel.getFocusPic() != null) {
                        String delObj = samplePanel.getFocusPic().toString();
                        int cmd = JOptionPane.showConfirmDialog(null, "Delete "
                                + delObj + " ?", "Delete Check",
                                JOptionPane.YES_NO_OPTION);
                        if (cmd == 0) {
                            samplePanel.deleteFocusOnPic();
                        }
                    }
                    list.setSelectedIndex(0);
                }
            }
        });
        this.setLayout(new GridBagLayout());
       
        menuBar = this.createMenuBar();
        this.add(menuBar);
       
        samplePanel = new PaintPanel();
        GBC = new GridBagConstraints();
        GBC.insets = new Insets(10, 10, 10, 10);
        GBC.fill = GridBagConstraints.HORIZONTAL;
        GBC.anchor = GridBagConstraints.NORTHEAST;
        GBC.gridx = 0;
        GBC.gridy = 1;
        GBC.gridwidth = 1;
        GBC.gridheight = 3;
        GBC.weightx = 10;
        GBC.weighty = 10;
        this.add(sampleJList, GBC);
        GBC = new GridBagConstraints();
        GBC.insets = new Insets(10, 10, 10, 10);
        GBC.fill = GridBagConstraints.BOTH;
        GBC.anchor = GridBagConstraints.NORTHEAST;
        GBC.gridx = 1;
        GBC.gridy = 1;
        GBC.gridwidth = 5;
        GBC.gridheight = 3;
        GBC.weightx = 300;
        GBC.weighty = 10;
        this.add(samplePanel, GBC);
    }

    public String getToolsSelected() {
        return sampleJList.getSelectedValue().toString();
    }
}

package package1;

import java.awt.*;
import java.awt.event.MouseEvent;
import javax.swing.*;

public interface MouseReceiver {
    public boolean mouseMoved(MouseEvent e, Point pt);

    public boolean mouseDragged(MouseEvent e, Point pt);

    public boolean mouseClicked(MouseEvent e, Point pt);

    public boolean mouseReleased(MouseEvent e, Point pt);

    public boolean mousePressed(MouseEvent e, Point pt);

    public boolean mouseEntered(MouseEvent e, Point pt);

    public boolean mouseExited(MouseEvent e, Point pt);
}

package package1;

import java.awt.Point;

public interface MouseSelected {
    public int getMouseState();

    public void setMouseState(int val);

    public String mouseOnWhere(Point e);
}

package package1;

import java.awt.*;
import javax.swing.*;
import java.util.*;

public class MRenderer extends DefaultListCellRenderer {
    private Hashtable iconTable = new Hashtable();

    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
        JLabel label = (JLabel) super.getListCellRendererComponent(list, value,
                index, isSelected, false);
        ImageIcon icon = (ImageIcon) iconTable.get(value.toString()
                + isSelected);
        if (icon == null) {
            String fileName = value.toString();
            if (isSelected == true)
                fileName += "1.png";
            else
                fileName += "0.png";
            icon = new ImageIcon(fileName);
            iconTable.put(value.toString() + isSelected, icon);
        }
        label.setIcon(icon);
        label.setText("");
        return label;
    }
}

package package1;

import java.awt.*;
import java.awt.event.MouseEvent;
import javax.swing.*;
import java.util.*;

public class PaintPanel extends JPanel implements MouseReceiver,
        AttachToolSelected, QueryRoot {
    private Component focusPic = null;
    private ArrayList<LinkSegment> linkSegment;
    public Component linkST = null;
    public Component linkED = null;
    public Point linkstPt;
    public Point linkedPt;

    PaintPanel() {
        linkSegment = new ArrayList<LinkSegment>();
        ShowListener listener = new ShowListener();
        this.setBackground(new Color(40, 40, 40));
        this.addMouseListener(listener);
        this.addMouseMotionListener(listener);
        this.setLayout(null);
    }

    public void setLinkTwoComponent(Component cp, Point pt) {
        if (cp == null || cp == this)
            return;
        if (linkST == null || linkST == cp) {
            linkST = cp;
            linkstPt = pt;
        } else {
            linkED = cp;
            linkedPt = pt;
        }
    }

    public String getToolsSelected() {
        Component j1 = this.getParent();
        if (j1 instanceof AttachToolSelected)
            return ((AttachToolSelected) j1).getToolsSelected();
        else
            return null;
    }

    public Point convertPointOnRoot(Point pt) {
        return pt;
    }

    void setFocusPic(Object obj) {
        /*
         * if (obj != focusPic && focusPic != null) ((ClassDiagram)
         * focusPic).setMouseState(0);
         */
        if (obj != null) {
            focusPic = (Component) obj;
        } else {
            focusPic = null;
        }
    }

    Object getFocusPic() {
        String ret = "";
        if (focusPic != null)
            ret += "Class " + focusPic.toString();
        for (int i = 0; i < linkSegment.size(); i++) {
            if (linkSegment.get(i).getSelected()) {
                ret += " & Link";
                break;
            }
        }
        return ret;
    }

    public void deleteFocusOnPic() {
        if (focusPic != null) {
            if (focusPic instanceof ClassDiagram) {
                ((ClassDiagram) focusPic).clearAttachPoint();
            }
            this.remove(focusPic);
            focusPic = null;
        }
        for (int i = 0; i < linkSegment.size(); i++) {
            if (linkSegment.get(i).getSelected()) {
                linkSegment.remove(i);
                break;
            }
        }
        this.updateUI();
    }

    public void addLinkImg(int headType) {
        if (linkST == null || linkED == null) {
            linkST = null;
            linkED = null;
            return;
        }/*
         * System.out.println(this.linkST); System.out.println(this.linkED);
         */
        Point stp, edp, rstp, redp;
        int stPort = ((ClassDiagram) (this.linkST)).getNearPortNumber(linkstPt);
        int edPort = ((ClassDiagram) (this.linkED)).getNearPortNumber(linkedPt);
        stp = ((ClassDiagram) (this.linkST)).getPortXY(stPort);
        edp = ((ClassDiagram) (this.linkED)).getPortXY(edPort);
        rstp = ((ClassDiagram) (this.linkST)).getRelativePortXY(stPort);
        redp = ((ClassDiagram) (this.linkED)).getRelativePortXY(edPort);
        LinkSegment ls = new LinkSegment(stp, edp, headType);
        ((ClassDiagram) (this.linkST)).addAttachPoint(ls.getPointAddr(0), rstp,
                ls);
        ((ClassDiagram) (this.linkED)).addAttachPoint(ls.getPointAddr(3), redp,
                ls);
        ls.setAttachObject(0, linkST);
        ls.setAttachObject(3, linkED);
        linkST = null;
        linkED = null;
        linkSegment.add(ls);
    }

    public boolean hasMouseOnObject(Point pt) {
        boolean ret = false;
        ret = this.getComponentAt(pt) != this;
        for (int i = 0; i < linkSegment.size(); i++) {
            String pos = linkSegment.get(i).mouseOnWhere(pt);
            if (!pos.equals("nop"))
                return true;
        }
        return ret;
    }

    public void setSelectedObject(Point pt) {
        boolean hasSelected = false;
        for (int i = 0; i < linkSegment.size(); i++) {
            if (hasSelected) {
                linkSegment.get(i).setSelected(false);
                continue;
            }
            String pos = linkSegment.get(i).mouseOnWhere(pt);
            if (!pos.equals("nop"))
                hasSelected = true;
            linkSegment.get(i).setSelected(!pos.equals("nop"));
        }
        this.repaint();
    }

    public void setDragBlockSelected(Point st, Point ed) {
        Component c[] = this.getComponents();
        Point lowerLeft = new Point(), upperRight = new Point();
        lowerLeft.x = Math.min(st.x, ed.x);
        lowerLeft.y = Math.min(st.y, ed.y);
        upperRight.x = Math.max(st.x, ed.x);
        upperRight.y = Math.max(st.y, ed.y);
        for (int i = 0; i < c.length; i++) {
            int lx, ly, rx, ry;
            lx = c[i].getX();
            ly = c[i].getY();
            rx = lx + c[i].getWidth();
            ry = ly + c[i].getHeight();
            if (lowerLeft.x < lx && rx < upperRight.x && lowerLeft.y < ly
                    && ry < upperRight.y) {
                if (c[i] instanceof MouseSelected)
                    ((MouseSelected) c[i]).setMouseState(1);
            }
        }
    }

    public void moveSelectedObject(Point pt) {
        for (int i = 0; i < linkSegment.size(); i++) {
            if (linkSegment.get(i).getSelected()) {
                String pos = linkSegment.get(i).mouseOnWhere(pt);
                if (pos.indexOf("point") >= 0) {
                    int index = Integer.parseInt(pos.substring(5));
                    // System.out.println(index);
                    // linkSegment.get(i).setPoint(index, pt);
                    linkSegment.get(i).adjustPoint(
                            linkSegment.get(i).getPointAddr(index), pt);
                    if (index == 0 || index == linkSegment.get(i).getSize() - 1) {
                        Component jl = this.getComponentAt(pt);
                        if (jl != null) {
                            if (jl instanceof ClassDiagram) {
                                Point selectPt = linkSegment.get(i)
                                        .getPointAddr(index);
                                Point nextPos = ((ClassDiagram) jl)
                                        .getPortXY(((ClassDiagram) jl)
                                                .getNearPortNumber(pt));
                                linkSegment.get(i).adjustPoint(selectPt,
                                        nextPos);
                                ((ClassDiagram) jl).addAttachPoint(selectPt,
                                        new Point(nextPos.x - jl.getX(),
                                                nextPos.y - jl.getY()),
                                        linkSegment.get(i));
                                linkSegment.get(i).setAttachObject(index, jl);
                                linkSegment.get(i).setSelected(false);
                            }
                        }
                    }
                    this.repaint();
                }
            }
        }
    }

    public void compositeSelectedObject() {
        Component c[] = this.getComponents();
        Component[] selected;
        int selectedCount = 0;
        for (int i = 0; i < c.length; i++) {
            if (c[i] instanceof MouseSelected) {
                if (((MouseSelected) c[i]).getMouseState() > 0)
                    selectedCount++;
            }
        }
        if (selectedCount > 1) {
            selected = new Component[selectedCount];
            selectedCount = 0;
            for (int i = 0; i < c.length; i++) {
                if (c[i] instanceof MouseSelected) {
                    if (((MouseSelected) c[i]).getMouseState() > 0) {
                        selected[selectedCount] = c[i];
                        selectedCount++;
                        this.remove(c[i]);
                    }
                }
            }
            this.add(new CompositePanel(selected));
            this.updateUI();
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        /* System.out.println("paint"); */
        for (int i = 0; i < linkSegment.size(); i++) {
            linkSegment.get(i).drawOnGraph(g);
        }
        Graphics2D g2d = (Graphics2D) g;
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                0.5f));
        g2d.setColor(new Color(224, 255, 255));
        if (linkstPt != null && linkedPt != null
                && this.getToolsSelected().equals("select")) {
            int mnx, mny;
            int mxx, mxy;
            mnx = Math.min(linkstPt.x, linkedPt.x);
            mny = Math.min(linkstPt.y, linkedPt.y);
            mxx = Math.max(linkstPt.x, linkedPt.x);
            mxy = Math.max(linkstPt.y, linkedPt.y);
            g2d.fillRect(mnx, mny, mxx - mnx, mxy - mny);
        }
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                1.0f));
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        /* System.out.println("paintComponent"); */
    }

    public boolean mouseMoved(MouseEvent e, Point pt) {
        return false;
    }

    public boolean mouseDragged(MouseEvent e, Point pt) {
        if (SwingUtilities.isLeftMouseButton(e)) {
            Component j1 = (Component) e.getSource();
            if (this.getToolsSelected() == "select") {
                this.moveSelectedObject(pt);
                // System.out.println("getComponentAt" +
                // this.getComponentAt(pt));
                if (linkstPt != null) {
                    linkedPt = pt;
                    this.repaint();
                }
            }
            if (this.getToolsSelected() == "association") {
                this.setLinkTwoComponent(this.getComponentAt(pt.x, pt.y), pt);
            }
            if (this.getToolsSelected() == "general") {
                this.setLinkTwoComponent(this.getComponentAt(pt.x, pt.y), pt);
            }
            if (this.getToolsSelected() == "composition") {
                this.setLinkTwoComponent(this.getComponentAt(pt.x, pt.y), pt);
            }
        } else if (SwingUtilities.isRightMouseButton(e)) {

        } else if (SwingUtilities.isMiddleMouseButton(e)) {

        }
        return false;
    }

    public boolean mouseClicked(MouseEvent e, Point pt) {
        /*
         * System.out.println("PaintPanel clicked");
         */
        if (SwingUtilities.isLeftMouseButton(e)) {
            if (e.getClickCount() == 2) {
                if (this.getToolsSelected() == "select") {
                    Component c[] = this.getComponents();
                    for (int i = 0; i < c.length; i++) {
                        if (c[i] instanceof MouseSelected)
                            ((MouseSelected) c[i]).setMouseState(0);
                    }
                    if (this.getComponentAt(pt) != this) {
                        Component cp = this.getComponentAt(pt);
                        if (cp instanceof MouseSelected)
                            ((MouseSelected) cp).setMouseState(1);
                    }
                    this.setSelectedObject(pt);
                    this.updateUI();
                }
            }
        } else if (SwingUtilities.isRightMouseButton(e)) {

        } else if (SwingUtilities.isMiddleMouseButton(e)) {

        }
        return false;
    }

    public boolean mouseReleased(MouseEvent e, Point pt) {
        /* System.out.println("PaintPanel mouseReleased"); */
        Component j1 = (Component) e.getSource();// jl = PaintPanel
        if (this.getToolsSelected().equals("select")) {
            if (linkstPt != null && linkedPt != null) {
                this.setDragBlockSelected(linkstPt, linkedPt);
                this.repaint();
            }
            linkstPt = null;
            linkedPt = null;
        }
        if (this.getToolsSelected().equals("class")) {
            ClassDiagram cd = new ClassDiagram();
            cd.setLocation(pt);
            this.add(cd);
            this.updateUI();
        }
        if (this.getToolsSelected().equals("association")) {
            this.addLinkImg(0);
        }
        if (this.getToolsSelected().equals("general")) {
            this.addLinkImg(1);
        }
        if (this.getToolsSelected().equals("composition")) {
            this.addLinkImg(2);
        }
        this.updateUI();
        return false;
    }

    public boolean mousePressed(MouseEvent e, Point pt) {
        /* System.out.println("PaintPanel pressed"); */
        if (this.getToolsSelected().equals("select")) {
            if (!this.hasMouseOnObject(pt)) {
                linkstPt = pt;
            } else {
                linkstPt = null;
                linkedPt = null;
            }
        }
        return false;
    }

    public boolean mouseEntered(MouseEvent e, Point pt) {
        return false;
    }

    public boolean mouseExited(MouseEvent e, Point pt) {
        return false;
    }
}

package package1;

import java.awt.Component;
import java.awt.event.MouseEvent;

import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputListener;

public class PassMouseEventListener implements MouseInputListener {
    public void mouseMoved(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl.getParent() instanceof MouseReceiver)
            ((MouseReceiver) jl.getParent()).mouseMoved(
                    e,
                    SwingUtilities.convertPoint(jl, e.getPoint(),
                            jl.getParent()));
    }

    public void mouseDragged(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl.getParent() instanceof MouseReceiver)
            ((MouseReceiver) jl.getParent()).mouseDragged(
                    e,
                    SwingUtilities.convertPoint(jl, e.getPoint(),
                            jl.getParent()));
    }

    public void mouseReleased(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl.getParent() instanceof MouseReceiver)
            ((MouseReceiver) jl.getParent()).mouseReleased(
                    e,
                    SwingUtilities.convertPoint(jl, e.getPoint(),
                            jl.getParent()));
    }

    public void mouseEntered(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl.getParent() instanceof MouseReceiver)
            ((MouseReceiver) jl.getParent()).mouseEntered(
                    e,
                    SwingUtilities.convertPoint(jl, e.getPoint(),
                            jl.getParent()));
    }

    public void mouseExited(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl.getParent() instanceof MouseReceiver)
            ((MouseReceiver) jl.getParent()).mouseExited(
                    e,
                    SwingUtilities.convertPoint(jl, e.getPoint(),
                            jl.getParent()));
    }

    public void mouseClicked(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl.getParent() instanceof MouseReceiver)
            ((MouseReceiver) jl.getParent()).mouseClicked(
                    e,
                    SwingUtilities.convertPoint(jl, e.getPoint(),
                            jl.getParent()));
    }

    public void mousePressed(MouseEvent e) {
        Component jl = (Component) e.getSource();
        if (jl.getParent() instanceof MouseReceiver)
            ((MouseReceiver) jl.getParent()).mousePressed(
                    e,
                    SwingUtilities.convertPoint(jl, e.getPoint(),
                            jl.getParent()));
    }
}

package package1;
import java.awt.Point;
public interface QueryRoot {
    public Point convertPointOnRoot(Point pt);
}

package package1;

import javax.swing.border.*;
import javax.swing.event.MouseInputListener;
import javax.swing.*;

import java.awt.*;
import java.awt.event.MouseEvent;

public class ResizeBorder extends LineBorder {
    private int thickness;
    private int selectWH = 10;
    public ResizeBorder(Color color, int thickness) {
        super(color, thickness);
        this.thickness = thickness;
    }
    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width,
            int height) {
        super.paintBorder(c, g, x, y, width, height);
        if (g instanceof Graphics2D) {
            Graphics2D g2d = (Graphics2D) g;
            if (((MouseSelected) c).getMouseState() == 0)
                return;
            /*
             * // left-up corner. g2d.fillRect(x, y, rectWidth, rectHeight);
             * g2d.fillRect(x, y, rectHeight, rectWidth); // right-up corner.
             * g2d.fillRect(width - rectWidth, y, rectWidth, rectHeight);
             * g2d.fillRect(width - rectHeight, y, rectHeight, rectWidth); //
             * left-bottom corner. g2d.fillRect(x, height - rectHeight,
             * rectWidth, rectHeight); g2d.fillRect(x, height - rectWidth,
             * rectHeight, rectWidth); // right-bottom corner.
             * g2d.fillRect(width - rectWidth, height - rectHeight, rectWidth,
             * rectHeight); g2d.fillRect(width - rectHeight, height - rectWidth,
             * rectHeight, rectWidth);
             */
            g2d.setColor(Color.BLACK);
            g2d.fillRect(x + width / 2 - selectWH, y, selectWH, selectWH);
            g2d.fillRect(x, y + height / 2 - selectWH, selectWH, selectWH);
            g2d.fillRect(x + width - selectWH, y + height / 2 - selectWH,
                    selectWH, selectWH);
            g2d.fillRect(x + width / 2 - selectWH, y + height - selectWH,
                    selectWH, selectWH);
        }
    }

    @Override
    public Insets getBorderInsets(Component c) {
        return getBorderInsets(c, new Insets(thickness, thickness, thickness, thickness));
    }

    @Override
    public Insets getBorderInsets(Component c, Insets insets) {
        insets.left = insets.right = insets.bottom = insets.top = thickness;
        return insets;
    }

    @Override
    public boolean isBorderOpaque() {
        return true;
    }
}

package package1;

import java.awt.Component;
import java.awt.Point;
import java.awt.event.MouseEvent;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputListener;

public class ShowListener implements MouseInputListener {
    public void mouseMoved(MouseEvent e) {
    }

    public void mouseDragged(MouseEvent e) {
        Component jl = (Component) e.getSource();
        ((PaintPanel)jl).mouseDragged(e, e.getPoint());
        /*
         * if (SwingUtilities.isLeftMouseButton(e)) { Component j1 = (Component)
         * e.getSource(); ((PaintPanel) j1).moveSelectedObject(e.getPoint()); if
         * (((PaintPanel) j1).getToolsSelected() == "association") {
         *
         * System.out.println(((PaintPanel) j1).linkST);
         * System.out.println(((PaintPanel) j1).linkED); } } else if
         * (SwingUtilities.isRightMouseButton(e)) {
         *
         * } else if (SwingUtilities.isMiddleMouseButton(e)) {
         *
         * }
         */
    }

    public void mouseReleased(MouseEvent e) {
        Component jl = (Component) e.getSource();
        ((PaintPanel)jl).mouseReleased(e, e.getPoint());
        // System.out.println("Paint Panel mouse Released");
        /*Component j1 = (Component) e.getSource();// jl = PaintPanel
        if (((PaintPanel) j1).getToolsSelected() == "class") {
            ClassDiagram cd = new ClassDiagram();
            cd.setLocation(e.getPoint());
            ((PaintPanel) j1).add(cd);
            ((PaintPanel) j1).updateUI();
        }
        if (((PaintPanel) j1).getToolsSelected() == "association") {
            System.out.println(((PaintPanel) j1).linkST);
            System.out.println(((PaintPanel) j1).linkED);
            LinkSegment ls = new LinkSegment(
                    ((ClassDiagram) (((PaintPanel) j1).linkST)).getPortXY(0),
                    ((ClassDiagram) (((PaintPanel) j1).linkED)).getPortXY(0));
            ((ClassDiagram) (((PaintPanel) j1).linkST)).addAttachPoint(
                    ((ClassDiagram) (((PaintPanel) j1).linkST)).getPortXY(0),
                    new Point(0, 0), ls);
            ((PaintPanel) j1).addLinkImg(ls);
            ((PaintPanel) j1).updateUI();
        }*/
    }

    public void mouseEntered(MouseEvent e) {
        // System.out.println("Paint Panel mouse Entered");

    }

    public void mouseExited(MouseEvent e) {
        Component jl = (Component) e.getSource();
        ((PaintPanel)jl).mouseExited(e, e.getPoint());
    }

    public void mouseClicked(MouseEvent e) {
        Component jl = (Component) e.getSource();
        ((PaintPanel)jl).mouseClicked(e, e.getPoint());
    }

    public void mousePressed(MouseEvent e) {
        Component jl = (Component) e.getSource();
        ((PaintPanel)jl).mousePressed(e, e.getPoint());
    }
}