package graphmatcher.gui;
import graphmatcher.graph.Edge;
import graphmatcher.graph.Graph;
import graphmatcher.graph.Vertex;
import graphmatcher.matcher.MatchingResult;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JPanel;
public class MatchingPanel extends JPanel implements Observer {
private static boolean showGraphsWithVirtualEdges = true;
private Graph pattern, template, deformedPattern;
private int[] matching;
private Point templateOffset = new Point(0, 0);
private Point patternOffset = new Point(0, 0);
private Point pressedPoint, movePoint, oldPatternOffset;
private double zoom = 1;
private boolean move = false;
private boolean showMatchingEdges = true, showIndices = true, showModifiedGraphs = true;
public MatchingPanel() {
setPreferredSize(new Dimension(600, 400));
setBackground(Color.WHITE);
setCursor(new Cursor(Cursor.MOVE_CURSOR));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
oldPatternOffset = patternOffset;
pressedPoint = e.getPoint();
move = true;
}
}
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
pressedPoint = null;
move = false;
}
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if (move) {
movePoint = e.getPoint();
Point newPoint = new Point(oldPatternOffset.x + movePoint.x - pressedPoint.x,
oldPatternOffset.y + movePoint.y - pressedPoint.y);
patternOffset = newPoint;
repaint();
}
}
});
addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getWheelRotation() > 0) {
zoom += 0.1;
} else {
zoom -= 0.1;
}
repaint();
}
});
}
public void setOptions(boolean showMatchingEdges, boolean showIndices, boolean showTransformedPattern) {
this.showMatchingEdges = showMatchingEdges;
this.showIndices = showIndices;
this.showModifiedGraphs = showTransformedPattern;
repaint();
}
public void setMatchingResult(MatchingResult matchingResult) {
pattern = matchingResult.getPattern();
template = matchingResult.getTemplate();
matching = matchingResult.getMatching();
deformedPattern = matchingResult.getDeformedPattern();
repaint();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D gr = (Graphics2D) g;
gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (pattern == null) {
return;
}
gr.scale(zoom, zoom);
gr.translate(0, 400);
// TemplateGraph
paintGraph(gr, Color.GREEN, template, templateOffset, false, showIndices, false);
// Matching Kanten
if (showMatchingEdges) {
g.setColor(Color.BLUE);
for (int i = 0; i < matching.length; i++) {
if (matching[i] < 0) {
continue;
}
Point v1 = pattern.vertices()[i].toPoint();
Point v2 = template.vertices()[matching[i]].toPoint();
gr.drawLine(v1.x + patternOffset.x, -v1.y + patternOffset.y, v2.x + templateOffset.x, -v2.y
+ templateOffset.y);
}
}
// PatternGraph
paintGraph(gr, Color.RED, pattern, patternOffset, false, showIndices, false);
if (showModifiedGraphs && deformedPattern != null) {
// Template und DeformedPattern
if (showGraphsWithVirtualEdges) {
Point templateOffset2 = new Point(templateOffset.x + 250, templateOffset.y);
paintGraph(gr, Color.GREEN, template, templateOffset2, false, showIndices, true);
if (showMatchingEdges) {
g.setColor(Color.BLUE);
for (int i = 0; i < matching.length; i++) {
if (matching[i] < 0) {
continue;
}
Point v1 = deformedPattern.vertices()[i].toPoint();
Point v2 = template.vertices()[matching[i]].toPoint();
gr.drawLine(v1.x + patternOffset.x + 250, -v1.y + patternOffset.y, v2.x
+ templateOffset.x + 250, -v2.y + templateOffset.y);
}
}
Point deformedpatternOffset = new Point(patternOffset.x + 250, patternOffset.y);
if (deformedPattern != null) {
paintGraph(gr, Color.LIGHT_GRAY, deformedPattern, deformedpatternOffset, false,
showIndices, true);
}
}
}
}
private void paintGraph(Graphics g, Color color, Graph graph, Point offset, boolean showRadiusBins,
boolean showIndices, boolean showVirtualEdges) {
// Kanten zeichnen
g.setColor(color);
Vertex[] vertices = graph.vertices();
if (!showVirtualEdges) {
for (Edge edge : graph.edges()) {
Point vertex1 = vertices[edge.vertex1].toPoint();
Point vertex2 = vertices[edge.vertex2].toPoint();
g.drawLine(vertex1.x + offset.x, -vertex1.y + offset.y, vertex2.x + offset.x, -vertex2.y
+ offset.y);
}
} else {
for (Edge edge : graph.virtualEdges()) {
Point vertex1 = vertices[edge.vertex1].toPoint();
Point vertex2 = vertices[edge.vertex2].toPoint();
g.drawLine(vertex1.x + offset.x, -vertex1.y + offset.y, vertex2.x + offset.x, -vertex2.y
+ offset.y);
}
}
// Schwerpunkt zeichnen
Point center2 = graph.getCenter();
g.fillOval(center2.x + offset.x, -center2.y + offset.y, 6, 6);
// Point center = graph.getCenterOfVertices();
// g.fillOval(center.x + offset.x, -center.y + offset.y, 4, 4);
// Knoten mit Nummer zeichnen
g.setColor(Color.BLACK);
for (int i = 0; i < graph.vertices().length; i++) {
Vertex vertex = graph.vertices()[i];
int x = vertex.x + offset.x;
int y = -vertex.y + offset.y;
g.drawOval(x, y, 1, 1);
if (showIndices) {
g.drawString("" + i, x + 2, y + 2);
}
}
}
@Override
public void update(Observable o, Object arg) {
System.out.println("update");
repaint();
}
}