/* * #! * Ontopia Engine * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * !# */ package net.ontopia.topicmaps.utils; import java.util.Collection; import java.util.Iterator; import java.awt.Graphics2D; import java.awt.Font; import java.awt.Rectangle; import java.awt.Color; import java.awt.geom.Line2D; import java.awt.image.BufferedImage; import net.ontopia.utils.StringifierIF; import net.ontopia.topicmaps.core.TopicIF; import net.ontopia.topicmaps.utils.TopicStringifiers; /** * EXPERIMENTAL. * @since 1.2 */ public class TopicTreeRendrer { protected TopicTreeNode root; protected TopicIF current; protected Graphics2D g2d; protected StringifierIF<TopicIF> str; protected String title; protected Collection<TopicIF> bnscope; protected Collection<TopicIF> vnscope; protected int x; protected int y; protected int xmargin; protected int ymargin; protected int xoffset; protected int yoffset; protected int xtextmargin; protected int ytextmargin; protected int height; public TopicTreeRendrer(TopicTreeNode root, TopicIF current) { xmargin = 10; ymargin = 10; xoffset = 40; yoffset = 35; xtextmargin = 15; ytextmargin = 15; height = 25; this.root = root; this.current = current; } public void draw(Graphics2D g2d) { this.g2d = g2d; this.g2d.setBackground(Color.white); this.g2d.clearRect(0, 0, getMaxX() + 100, getMaxY()); this.g2d.setPaint(Color.black); x = 0; y = 0; drawNode(root); } public BufferedImage renderImage() { BufferedImage image = new BufferedImage(getMaxX(), getMaxY(), BufferedImage.TYPE_BYTE_INDEXED); Graphics2D g2d = image.createGraphics(); draw(g2d); return image; } public void setTitle(String title) { this.title = title; } public int getMaxX() { return getMaxX(root, 0) + 25; } public int getMaxY() { return getBottom(getMaxY(root, 0)); } public void setTopicNameScope(Collection<TopicIF> bnscope) { this.bnscope = bnscope; } public void setVariantScope(Collection<TopicIF> vnscope) { this.vnscope = vnscope; } // --- Internal methods protected int drawNode(TopicTreeNode node) { String title = getTitle(node); if (current != null && current.equals(node.getTopic())) g2d.setPaint(Color.red); node.setAttribute("x1", new Integer(getLeft(x))); node.setAttribute("x2", new Integer(getLeft(x) + getWidth(title))); node.setAttribute("y1", new Integer(getTop(y))); node.setAttribute("y2", new Integer(getTop(y) + height)); g2d.drawString(title, getTextStart(x), getTextTop(y)); g2d.draw(new Rectangle(getLeft(x), getTop(y), getWidth(title), height)); g2d.setPaint(Color.black); int thisY = y++; int lasty = 0; x++; Iterator<TopicTreeNode> it = node.getChildren().iterator(); while (it.hasNext()) { TopicTreeNode child = it.next(); g2d.draw(new Line2D.Float(getLeft(x-1) + 10, getMiddle(y), getLeft(x), getMiddle(y))); lasty = drawNode(child); } x--; if (!node.getChildren().isEmpty()) g2d.draw(new Line2D.Float(getLeft(x) + 10, getBottom(thisY), getLeft(x) + 10, getTop(lasty) + (height/2))); return thisY; } protected int getLeft(int x) { return xmargin + x * xoffset; } protected int getRight(int x, String title) { return getLeft(x) + getWidth(title); } protected int getWidth(String title) { if (g2d == null) return title.length()*8 + 30; Font font = g2d.getFont(); int width = (int) font.getStringBounds(title, g2d.getFontRenderContext()).getWidth(); return width + 30; } protected int getTop(int y) { return ymargin + y * yoffset; } protected int getMiddle(int y) { return ymargin + y * yoffset + (height/2); } protected int getBottom(int y) { return ymargin + y * yoffset + height; } protected int getTextStart(int x) { return getLeft(x) + xtextmargin; } protected int getTextTop(int y) { return getTop(y) + ytextmargin; } protected int getMaxX(TopicTreeNode node, int x) { int ourX = getRight(x, getTitle(node)); Iterator<TopicTreeNode> it = node.getChildren().iterator(); while (it.hasNext()) ourX = Math.max(ourX, getMaxX(it.next(), x+1)); return ourX; } protected int getMaxY(TopicTreeNode node, int y) { y++; Iterator<TopicTreeNode> it = node.getChildren().iterator(); while (it.hasNext()) y = getMaxY(it.next(), y); return y; } protected String getTitle(TopicTreeNode node) { TopicIF topic = node.getTopic(); if (str == null) str = TopicStringifiers.getStringifier(bnscope, vnscope); if (topic != null) return str.toString(topic); else if (title != null) return title; else return "<null>"; } }