Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 9b60aa3fb32c6c63757ebe748e0a115e804e8678 Mon Sep 17 00:00:00 2001
- From: Uli Schlachter <uli.schlachter@informatik.uni-oldenburg.de>
- Date: Mon, 30 May 2016 17:31:48 +0200
- Subject: [PATCH] WIP: Implement GraphvizLayout
- Signed-off-by: Uli Schlachter <uli.schlachter@informatik.uni-oldenburg.de>
- ---
- .../uniol/aptgui/editor/layout/GraphvizLayout.java | 168 +++++++++++++++++++++
- .../uniol/aptgui/mainwindow/menu/MenuViewImpl.java | 4 +
- .../aptgui/swing/actions/GraphvizLayoutAction.java | 61 ++++++++
- 3 files changed, 233 insertions(+)
- create mode 100644 src/main/java/uniol/aptgui/editor/layout/GraphvizLayout.java
- create mode 100644 src/main/java/uniol/aptgui/swing/actions/GraphvizLayoutAction.java
- diff --git a/src/main/java/uniol/aptgui/editor/layout/GraphvizLayout.java b/src/main/java/uniol/aptgui/editor/layout/GraphvizLayout.java
- new file mode 100644
- index 0000000..248f2f9
- --- /dev/null
- +++ b/src/main/java/uniol/aptgui/editor/layout/GraphvizLayout.java
- @@ -0,0 +1,168 @@
- +/*-
- + * APT - Analysis of Petri Nets and labeled Transition systems
- + * Copyright (C) 2016 Jonas Prellberg
- + * Copyright (C) 2016 Uli Schlachter
- + *
- + * This program 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.
- + *
- + * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
- + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- + */
- +
- +package uniol.aptgui.editor.layout;
- +
- +import java.io.*;
- +import java.nio.charset.StandardCharsets;
- +
- +import java.awt.Point;
- +
- +import org.apache.commons.collections4.BidiMap;
- +import org.apache.commons.collections4.bidimap.DualHashBidiMap;
- +
- +import uniol.apt.adt.IGraph;
- +import uniol.apt.adt.IEdge;
- +
- +import uniol.aptgui.editor.document.Document;
- +import uniol.aptgui.editor.document.graphical.GraphicalElement;
- +import uniol.aptgui.editor.document.graphical.nodes.GraphicalNode;
- +
- +/**
- + * Simple layout algorithm that uses Graphviz to layout items.
- + * randomly scatters nodes across the layout area.
- + */
- +public class GraphvizLayout implements Layout {
- +
- + private static final String nodeProperties = "fixedsize=true, width=60, height=60";
- +
- + private static BidiMap<GraphicalNode, String> collectNodes(Document<?> document) {
- + int counter = 0;
- + BidiMap<GraphicalNode, String> nodes = new DualHashBidiMap<>();
- + for (GraphicalElement elem : document.getGraphicalElements()) {
- + // Only nodes are positioned directly.
- + if (elem instanceof GraphicalNode) {
- + GraphicalNode node = (GraphicalNode) elem;
- + String id = String.format("s%d", counter++);
- + nodes.put(node, id);
- + }
- + }
- + return nodes;
- + }
- +
- + private static void writeDot(Writer writer, Document document, IGraph<?, ?, ?> graph, BidiMap<GraphicalNode, String> nodes) throws IOException {
- + writer.append("digraph G {\nnode [" + nodeProperties + "];\n");
- + // Write out all IDs of nodes
- + for (String node : nodes.values()) {
- + System.out.println(String.format("Printing node %s (%s) to graphviz", nodes.getKey(node), node));
- + writer.append("\"");
- + writer.append(node);
- + writer.append("\";\n");
- + }
- + // Write out all edges
- + for (IEdge<?, ?, ?> edge : graph.getEdges()) {
- + String source = nodes.get(document.getGraphicalExtension(edge.getSource()));
- + String target = nodes.get(document.getGraphicalExtension(edge.getTarget()));
- + if (source != null && target != null) {
- + System.out.println(String.format("Printing edge %s to graphviz", edge));
- + writer.append("\"");
- + writer.append(source);
- + writer.append("\" -> \"");
- + writer.append(target);
- + writer.append("\";\n");
- + }
- + else
- + System.out.println(String.format("Skipping edge %s because %s %s %s %s", edge, edge.getSource(), source, edge.getTarget(), target));
- + }
- + // Done!
- + writer.append("}");
- + }
- +
- + private static void doLayout(Document<?> document, BidiMap<GraphicalNode, String> nodes) throws IOException {
- + Process graphviz = new ProcessBuilder("dot", "-Tplain").start();
- + try {
- + IGraph<?, ?, ?> graph = (IGraph<?, ?, ?>) document.getModel();
- + try (OutputStream stream = graphviz.getOutputStream();
- + Writer osw = new OutputStreamWriter(stream, StandardCharsets.UTF_8);
- + Writer buf = new BufferedWriter(osw)) {
- + writeDot(buf, document, graph, nodes);
- + buf.close();
- + }
- + try (InputStream stream = graphviz.getInputStream();
- + Reader isr = new InputStreamReader(stream, StandardCharsets.UTF_8);
- + BufferedReader buf = new BufferedReader(isr)) {
- + String line;
- + do {
- + line = buf.readLine();
- + if (line != null)
- + System.out.println("read a line: " + line);
- + else
- + line = "stop";
- + String[] words = line.split(" ");
- + if (words.length >= 4 && words[0].equals("node")) {
- + String node = words[1];
- + double x, y;
- + try {
- + x = Double.parseDouble(words[2]);
- + y = Double.parseDouble(words[3]);
- + } catch (NumberFormatException e) {
- + // TODO: Should I do something nice here?
- + throw e;
- + }
- + GraphicalNode graphical = nodes.getKey(node);
- + if (graphical != null)
- + {
- + System.out.println(String.format("Setting %s %s to %d %d", node, graphical, (int)x, (int)y));
- + graphical.setCenter(new Point((int) x, (int) y));
- + }
- + }
- + } while (line != null && !line.equals("stop"));
- + System.out.println("done");
- + }
- + try (InputStream stream = graphviz.getErrorStream();
- + Reader isr = new InputStreamReader(stream, StandardCharsets.UTF_8);
- + BufferedReader buf = new BufferedReader(isr)) {
- + String line;
- + do {
- + line = buf.readLine();
- + if (line != null)
- + System.out.println("read an error line: " + line);
- + } while (line != null && !line.equals("stop"));
- + System.out.println("done");
- + }
- + } finally {
- + graphviz.destroy();
- + try {
- + graphviz.waitFor();
- + } catch (InterruptedException e) {
- + // Just re-interrupt the thread and return
- + Thread.currentThread().interrupt();
- + }
- + }
- + }
- +
- + @Override
- + public void applyTo(Document<?> document, int x0, int y0, int x1, int y1) {
- + try {
- + doLayout(document, collectNodes(document));
- + } catch (IOException e) {
- + // TODO
- + throw new RuntimeException(e);
- + }
- + }
- +
- + @Override
- + public String getName() {
- + return "Graphviz";
- + }
- +
- +}
- +
- +// vim: ft=java:noet:sw=8:sts=8:ts=8:tw=120
- diff --git a/src/main/java/uniol/aptgui/mainwindow/menu/MenuViewImpl.java b/src/main/java/uniol/aptgui/mainwindow/menu/MenuViewImpl.java
- index 641d5da..19b5a2a 100644
- --- a/src/main/java/uniol/aptgui/mainwindow/menu/MenuViewImpl.java
- +++ b/src/main/java/uniol/aptgui/mainwindow/menu/MenuViewImpl.java
- @@ -45,6 +45,7 @@ import uniol.aptgui.swing.actions.NewPetriNetAction;
- import uniol.aptgui.swing.actions.NewTransitionSystemAction;
- import uniol.aptgui.swing.actions.OpenAction;
- import uniol.aptgui.swing.actions.RandomLayoutAction;
- +import uniol.aptgui.swing.actions.GraphvizLayoutAction;
- import uniol.aptgui.swing.actions.RedoAction;
- import uniol.aptgui.swing.actions.RenameDocumentAction;
- import uniol.aptgui.swing.actions.SaveAction;
- @@ -88,6 +89,7 @@ public class MenuViewImpl extends JMenuBarView<MenuPresenter> implements MenuVie
- private final JMenu documentMenu;
- private final JMenuItem renameDocument;
- private final JMenuItem layoutRandom;
- + private final JMenuItem layoutGraphviz;
- private final JMenu moduleMenu;
- private final JMenuItem moduleBrowser;
- @@ -134,6 +136,7 @@ public class MenuViewImpl extends JMenuBarView<MenuPresenter> implements MenuVie
- documentMenu = new JMenu("Document");
- renameDocument = new JMenuItem(injector.getInstance(RenameDocumentAction.class));
- layoutRandom = new JMenuItem(injector.getInstance(RandomLayoutAction.class));
- + layoutGraphviz = new JMenuItem(injector.getInstance(GraphvizLayoutAction.class));
- // Modules
- moduleMenu = new JMenu("Modules");
- @@ -203,6 +206,7 @@ public class MenuViewImpl extends JMenuBarView<MenuPresenter> implements MenuVie
- documentMenu.add(renameDocument);
- documentMenu.add(layoutRandom);
- + documentMenu.add(layoutGraphviz);
- }
- diff --git a/src/main/java/uniol/aptgui/swing/actions/GraphvizLayoutAction.java b/src/main/java/uniol/aptgui/swing/actions/GraphvizLayoutAction.java
- new file mode 100644
- index 0000000..9f3e468
- --- /dev/null
- +++ b/src/main/java/uniol/aptgui/swing/actions/GraphvizLayoutAction.java
- @@ -0,0 +1,61 @@
- +/*-
- + * APT - Analysis of Petri Nets and labeled Transition systems
- + * Copyright (C) 2016 Jonas Prellberg
- + * Copyright (C) 2016 Uli Schlachter
- + *
- + * This program 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.
- + *
- + * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
- + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- + */
- +
- +package uniol.aptgui.swing.actions;
- +
- +import java.awt.event.ActionEvent;
- +import java.awt.event.KeyEvent;
- +
- +import com.google.common.eventbus.EventBus;
- +import com.google.inject.Inject;
- +
- +import uniol.aptgui.Application;
- +import uniol.aptgui.commands.ApplyLayoutCommand;
- +import uniol.aptgui.editor.document.Document;
- +import uniol.aptgui.editor.layout.GraphvizLayout;
- +import uniol.aptgui.swing.Resource;
- +import uniol.aptgui.swing.actions.base.DocumentAction;
- +
- +@SuppressWarnings("serial")
- +public class GraphvizLayoutAction extends DocumentAction {
- +
- + @Inject
- + public GraphvizLayoutAction(Application app, EventBus eventBus) {
- + super(app, eventBus);
- + String name = "Graphviz Layout";
- + putValue(NAME, name);
- + putValue(SHORT_DESCRIPTION, name);
- + putValue(SMALL_ICON, Resource.getIconLayout());
- + putValue(MNEMONIC_KEY, KeyEvent.VK_R);
- + setEnabled(false);
- + eventBus.register(this);
- + }
- +
- + @Override
- + public void actionPerformed(ActionEvent e) {
- + Document<?> document = app.getActiveDocument();
- + if (document != null) {
- + app.getHistory().execute(new ApplyLayoutCommand(document, new GraphvizLayout()));
- + }
- + }
- +
- +}
- +
- +// vim: ft=java:noet:sw=8:sts=8:ts=8:tw=120
- --
- 2.5.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement