⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphconstructionpanel.java

📁 基于MPEG 7 标准,符合未来语义网架构,很值得参考
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * This file is part of Caliph & Emir.
 *
 * Caliph & Emir is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Caliph & Emir 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Caliph & Emir; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Copyright statement:
 * --------------------
 * (c) 2002-2005 by Mathias Lux (mathias@juggle.at)
 * http://www.juggle.at, http://caliph-emir.sourceforge.net
 */
package at.lux.fotoretrieval.panels;

import at.knowcenter.caliph.objectcatalog.graphics.Arrow;
import at.lux.fotoretrieval.EmirConfiguration;
import at.lux.fotoretrieval.RetrievalFrame;
import at.lux.fotoretrieval.lucene.Node;
import at.lux.fotoretrieval.retrievalengines.LuceneRetrievalEngine;
import at.lux.fotoretrieval.retrievalengines.RetrievalEngineFacotry;
import at.lux.graphviz.LabeledEdge;
import at.lux.graphviz.LabeledNode;
import at.lux.graphviz.SpringEmbedder;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;

/**
 * Date: 04.01.2005
 * Time: 17:32
 *
 * @author Mathias Lux, mathias@juggle.at
 */

public class GraphConstructionPanel extends JPanel implements MouseListener, MouseMotionListener, ActionListener {
    private LinkedList<LabeledNode> semanticObjects = new LinkedList<LabeledNode>();
    private LinkedList<LabeledEdge> semanticRelations = new LinkedList<LabeledEdge>();
    private HashMap<String, LabeledNode> label2Node = new HashMap<String, LabeledNode>();
    private SpringEmbedder embedder = new SpringEmbedder(semanticObjects, semanticRelations);
    private HashMap<Point2D.Double, LabeledNode> point2node = new HashMap<Point2D.Double, LabeledNode>();
    private HashMap<Arrow, LabeledEdge> shape2edge = new HashMap<Arrow, LabeledEdge>();

    private static Color BACKGROUND_COLOR = new Color(152, 181, 255);
    public static final Color ARROW_COLOR = new Color(36, 74, 200);
    public static final Color NODE_COLOR = Color.green;

    private double OFFSET_X = EmirConfiguration.getInstance().getDouble("GraphConstructionPanel.EdgeOffset.x");
    private double OFFSET_Y = EmirConfiguration.getInstance().getDouble("GraphConstructionPanel.EdgeOffset.y");

    private String lastClickedLabel = null;
    private Point2D.Double lastClickedPoint = null;
    private Line2D.Double lastDraggedLine = null;
    private EmbedderThread embedderThread = null;

    private String[] relationArray;
    private static final int HELP_STRING_OFFSET_X = 6;
    private LuceneRetrievalEngine retrievalEngine;

    private LabeledNode currentNode;


    /**
     * Creates a new <code>JPanel</code> with a double buffer
     * and a flow layout.
     */
    public GraphConstructionPanel() {
        addMouseListener(this);
        addMouseMotionListener(this);
        LinkedList<String> relations = new LinkedList<String>();
        relations.add("* any relation");
        relations.add("membershipFunction");
        for (Iterator<String> iterator = LuceneRetrievalEngine.relationMapping.keySet().iterator(); iterator.hasNext();) {
            String relation = iterator.next();
            String inverse = LuceneRetrievalEngine.relationMapping.get(relation);
            relations.add(relation);
            relations.add(inverse);
        }
        Collections.sort(relations);
        relationArray = new String[1];
        relationArray = relations.toArray(relationArray);
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        HashMap<LabeledNode, Point.Double> nodeLocation = new HashMap<LabeledNode, Point.Double>();

        // draw background:
        g2.setColor(BACKGROUND_COLOR);
        g2.fillRect(0, 0, getWidth(), getHeight());

        g2.setColor(Color.black);
        Font font = g2.getFont();
        Font nFont = new Font("Verdana", Font.ITALIC, 9);
        g2.setFont(nFont);
        g2.drawString("Help:", HELP_STRING_OFFSET_X, getHeight() - 28);
        g2.drawString("<Alt> + right mouse click on object to remove node or edge.", HELP_STRING_OFFSET_X, getHeight() - 18);
        g2.drawString("Left mouse click on nodes and drag to other nodes to create edges.", HELP_STRING_OFFSET_X, getHeight() - 8);
        g2.setFont(nFont.deriveFont(Font.PLAIN));

        double maxWidth = getWidth() - 2d * OFFSET_X;
        double maxHeight = getHeight() - 2d * OFFSET_Y;

        double xMin = 1.0, xMax = 0.0, yMin = 1.0, yMax = 0.0;
        for (Iterator<LabeledNode> iterator = semanticObjects.iterator(); iterator.hasNext();) {
            LabeledNode node = iterator.next();
            if (node.getX() < xMin) xMin = node.getX();
            if (node.getX() > xMax) xMax = node.getX();
            if (node.getY() < yMin) yMin = node.getY();
            if (node.getY() > yMax) yMax = node.getY();
        }
//        System.out.println("(" + xMin + "," + yMin + ") - (" + xMax + "," + yMax + ")");
        if (semanticObjects.size() == 1) {
            LabeledNode node = semanticObjects.getFirst();
            Point.Double point = new Point.Double(0, 0);
            point.x = (getWidth() / 2);
            point.y = (getHeight() / 2);
            nodeLocation.put(node, point);
        } else if (semanticObjects.size() == 2) {
            LabeledNode node = semanticObjects.get(0);
            Point.Double point = new Point.Double(0, 0);
            point.x = (OFFSET_X);
            point.y = (getHeight() / 2);
            nodeLocation.put(node, point);

            node = semanticObjects.get(1);
            point = new Point.Double(0, 0);
            point.x = (getWidth() - OFFSET_X);
            point.y = (getHeight() / 2);
            nodeLocation.put(node, point);
        } else if (semanticObjects.size() == 3) {
            LabeledNode node = semanticObjects.get(0);
            Point.Double point = new Point.Double(0, 0);
            point.x = (OFFSET_X);
            point.y = (OFFSET_Y);
            nodeLocation.put(node, point);

            node = semanticObjects.get(1);
            point = new Point.Double(0, 0);
            point.x = (getWidth() - OFFSET_X);
            point.y = (OFFSET_Y);
            nodeLocation.put(node, point);

            node = semanticObjects.get(2);
            point = new Point.Double(0, 0);
            point.x = (getWidth() / 2);
            point.y = (getHeight() - OFFSET_Y);
            nodeLocation.put(node, point);
        } else {
            for (Iterator<LabeledNode> iterator = semanticObjects.iterator(); iterator.hasNext();) {
                LabeledNode node = iterator.next();
                double x = (((node.getX() - xMin) / (xMax - xMin)) * maxWidth + OFFSET_X);
                double y = (((node.getY() - yMin) / (yMax - yMin)) * maxHeight + OFFSET_Y);
                Point.Double point = new Point.Double(x, y);
                nodeLocation.put(node, point);
            }
        }
        shape2edge = new HashMap<Arrow, LabeledEdge>(semanticRelations.size());
        for (Iterator<LabeledEdge> iterator = semanticRelations.iterator(); iterator.hasNext();) {
            LabeledEdge edge = iterator.next();
            Point.Double src = nodeLocation.get(edge.getStartNode());
            Point.Double tgt = nodeLocation.get(edge.getEndNode());
            drawEdge(g2, edge, src, tgt);
            double moveX = tgt.x - src.x;
            double moveY = tgt.y - src.y;
            moveX *= .5;
            moveY *= .5;
            Point2D.Double lPoint = new Point2D.Double(src.x + moveX, src.y + moveY);
            drawLabel(g2, edge.getLabel(), lPoint, ARROW_COLOR);
        }
        for (Iterator<LabeledNode> iterator = nodeLocation.keySet().iterator(); iterator.hasNext();) {
            LabeledNode labeledNode = iterator.next();
            drawNode(g2, labeledNode, nodeLocation.get(labeledNode));
        }
        point2node = new HashMap<Point2D.Double, LabeledNode>(nodeLocation.keySet().size());
        for (Iterator<LabeledNode> iterator = nodeLocation.keySet().iterator(); iterator.hasNext();) {
            LabeledNode node = iterator.next();
            point2node.put(nodeLocation.get(node), node);
        }

        // draw dragged line:
        if (lastDraggedLine != null) {
            g2.setColor(Color.gray);
            g2.draw(lastDraggedLine);
        }
    }

    private void drawEdge(Graphics2D g2, LabeledEdge edge, Point2D.Double src, Point2D.Double tgt) {
        g2.setColor(ARROW_COLOR);
        double moveX = tgt.x - src.x;
        double moveY = tgt.y - src.y;
        double length = Math.sqrt(moveX * moveX + moveY * moveY);
        moveX *= 10 / length;
        moveY *= 10 / length;
        Point2D.Double target = new Point2D.Double(tgt.x - moveX, tgt.y - moveY);
        Line2D line = new Line2D.Double(src, target);
        Arrow arrow = new Arrow(line, 4d);
        shape2edge.put(arrow, edge);
        g2.fill(arrow);
        g2.setColor(Color.black);
    }

    private void drawNode(Graphics2D g2, LabeledNode node, Point.Double point) {
        int x = (int) (point.x - 10);
        int y = (int) (point.y - 10);
//        System.out.println(x + ", " + y);
        g2.setColor(NODE_COLOR);
        g2.fillOval(x, y, 20, 20);
        g2.setColor(ARROW_COLOR);
        g2.drawOval(x, y, 20, 20);
        Point2D.Double labelPoint;

        if ((getHeight() - point.y) > point.y)
            labelPoint = new Point2D.Double(point.x, point.y - 13);
        else
            labelPoint = new Point2D.Double(point.x, point.y + 13 + g2.getFontMetrics().getHeight());
        drawLabel(g2, node.getLabel(), labelPoint);
    }

    // draws the label inside an alpha blended box ...
    private void drawLabel(Graphics2D g2, String label, Point.Double point) {
        drawLabel(g2, label, point, Color.white);
    }

    private void drawLabel(Graphics2D g2, String label, Point.Double point, Color boxColor) {
        Composite comp = g2.getComposite();
        float alpha = 0.45f;
        int type = AlphaComposite.SRC_OVER;
        AlphaComposite composite = AlphaComposite.getInstance(type, alpha);
        g2.setComposite(composite);

        g2.setColor(boxColor);
        Rectangle2D bounds = g2.getFontMetrics().getStringBounds(label, g2);
        int fillRectX = (int) point.x - (((int) bounds.getWidth()) >> 1) - 4;
        int fillRectY = (int) point.y - ((int) bounds.getHeight() + 1);
        int fillRectWidth = (int) bounds.getWidth() + 8;
        int fillRectHeight = (int) bounds.getHeight() + 2;
        RoundRectangle2D.Double labelBackGround = new RoundRectangle2D.Double(fillRectX, fillRectY, fillRectWidth, fillRectHeight, 12.0, 12.0);
        g2.fill(labelBackGround);
//        g2.fillRect(fillRectX, fillRectY, fillRectWidth, fillRectHeight);

        g2.setComposite(comp);
        g2.setColor(Color.black);
        int x = (int) point.x - ((int) bounds.getWidth() >> 1);
        g2.drawString(label, x, (int) point.y - 2);
    }

    public void addNode(String label) {
        if (!label2Node.keySet().contains(label)) {
            try {
                if (embedderThread != null) {
                    embedderThread.stopEmbedding();
                    embedderThread.join();
                }
                LabeledNode node = new LabeledNode(Math.random(), Math.random(), label);
                semanticObjects.add(node);
                label2Node.put(label, node);
                embedder = new SpringEmbedder(semanticObjects, semanticRelations);
                embedGraph();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void removeNode(String label) {
        try {
            if (embedderThread != null) {
                embedderThread.stopEmbedding();
                embedderThread.join();
                embedderThread = null;
            }
            LabeledNode node = label2Node.get(label);
            semanticObjects.remove(node);
            label2Node.remove(label);
            LinkedList<LabeledEdge> toRemove = new LinkedList<LabeledEdge>();
            for (Iterator<LabeledEdge> iterator = semanticRelations.iterator(); iterator.hasNext();) {
                LabeledEdge edge = iterator.next();
                if (edge.getEndNode().equals(node) || edge.getStartNode().equals(node)) {
                    toRemove.add(edge);
                }
            }
            for (Iterator<LabeledEdge> iterator = toRemove.iterator(); iterator.hasNext();) {
                LabeledEdge edge = iterator.next();
                removeEdge(edge);
            }
            embedder = new SpringEmbedder(semanticObjects, semanticRelations);
            embedGraph();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * Use to stop embedder, remove an edge and start embedder :)
     *
     * @param edge
     */
    public void removeRelation(LabeledEdge edge) {
        try {
            // stop the thread and join it until it dies :)
            // dirty but synchronized :)
            if (embedderThread != null) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -