org.semantictools.graphics.ArcEnd Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of semantictools-context-renderer Show documentation
Show all versions of semantictools-context-renderer Show documentation
A library used to generate documentation for media types associated with a JSON-LD context
The newest version!
/*******************************************************************************
* Copyright 2012 Pearson Education
*
* 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 org.semantictools.graphics;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
public class ArcEnd implements Widget {
public static final Shape DIAMOND = createDiamond();
public static final Shape TRIANGLE = createTriangle();
private static Shape createDiamond() {
int height = 4;
int width = 22;
int center = width/2;
int x[] = new int[] {0, center, width, center};
int y[] = new int[] {0, -height, 0, height};
return new Polygon(x, y, 4);
}
private static Shape createTriangle() {
int x[] = new int[] {0, 20, 20};
int y[] = new int[] {0, -8, 8};
return new Polygon(x, y, 3);
}
private Arc arc;
private Shape shape;
private boolean filled;
private int tipX;
private int tipY;
private int arcX;
private int arcY;
private Edge edge;
private String title;
private String subtitle;
private int titleX;
private int titleY;
private int subtitleX;
private int subtitleY;
private Style style;
private Rect bounds = new BaseRect();
private Widget attachedWidget;
public ArcEnd(String title, String subtitle, Style style) {
this.title = title;
this.subtitle = subtitle;
this.style = style;
}
/**
* Returns the shape that represents this end point (e.g. arrow, diamond, etc.)
*/
public Shape getShape() {
return shape;
}
/**
* Sets the shape that represents this end point (e.g. arrow, diamond, etc.)
*/
public void setShape(Shape shape) {
this.shape = shape;
}
/**
* Returns a value specifying whether the shape (arrow head, diamond, etc.) representing this end point
* is filled.
*/
public boolean isFilled() {
return filled;
}
/**
* Set the value specifying whether the shape (arrow head, diamond, etc.) representing this end point
* is filled.
*/
public void setFilled(boolean filled) {
this.filled = filled;
}
/**
* Returns the x-coordinate of the point where the arc joins this ArcEnd.
*/
public int getArcX() {
return arcX;
}
/**
* Returns the y-coordinate of the point where the arc joins this ArcEnd.
*/
public void setArcX(int arcX) {
this.arcX = arcX;
}
public int getArcY() {
return arcY;
}
public void setArcY(int arcY) {
this.arcY = arcY;
}
public Style getStyle() {
return style;
}
public void setStyle(Style style) {
this.style = style;
}
public int getX() {
return tipX;
}
public void setX(int x) {
this.tipX = x;
}
public int getY() {
return tipY;
}
public void setY(int y) {
this.tipY = y;
}
public String getTitle() {
return title;
}
public String getSubtitle() {
return subtitle;
}
public Arc getArc() {
return arc;
}
public void setArc(Arc arc) {
this.arc = arc;
}
/**
* Returns the amount of space reserved above the arc for text or decorators
* (like arrows or diamonds).
*/
public int getAscent() {
int result = 0;
if (title != null) {
int padTop = style.getPadTop();
int padBottom = style.getPadBottom();
int ascent = style.getMetrics().getMaxAscent();
result += padBottom + ascent + padTop;
}
return result;
}
/**
* Returns the amount of space reserved below the arc for text or decorators
* (like an arrow or diamond).
*/
public int getDescent() {
int result = 0;
if (subtitle != null) {
int padTop = style.getPadTop();
int padBottom = style.getPadBottom();
int ascent = style.getMetrics().getMaxAscent();
result += padBottom + ascent + padTop;
}
return result;
}
public void attachAt(int x, int y) {
this.tipX = x;
this.tipY = y;
Edge edge = getEdge();
switch (edge) {
case RIGHT : attachRight(); break;
case LEFT : attachLeft(); break;
case TOP : attachTop(); break;
case BOTTOM: attachBottom(); break;
}
}
public Widget getAttachedWidget() {
return attachedWidget;
}
public void attachTo(Widget attachedWidget) {
this.attachedWidget = attachedWidget;
}
/**
* Attach this ArcEnd to the left edge of the attachedWidget
*/
private void attachLeft() {
FontMetrics metrics = style.getMetrics();
int shapeWidth = 0;
int width = 0;
int top = tipY;
int bottom = tipY;
arcX = tipX;
arcY = tipY;
if (shape != null) {
Rectangle2D bounds = shape.getBounds2D();
shapeWidth = (int) bounds.getWidth();
int height = (int)(bounds.getHeight()/2);
top = tipY - height - style.getPadTop();
bottom = tipY + height + style.getPadBottom();
arcX = tipX - shapeWidth;
}
if (title != null) {
int textWidth = metrics.stringWidth(title);
titleX = arcX - style.getPadRight() - textWidth;
titleY = arcY - style.getPadBottom();
width = textWidth;
top = Math.min(top, titleY - metrics.getMaxAscent() - style.getPadTop());
}
if (subtitle != null) {
int textWidth = metrics.stringWidth(subtitle);
subtitleX = arcX - style.getPadRight() - textWidth;
subtitleY = arcY + style.getPadTop() + metrics.getMaxAscent();
width = Math.max(width, textWidth);
bottom = Math.max(bottom, subtitleY + metrics.getMaxDescent() + style.getPadBottom());
}
width = shapeWidth + width + style.getPadLeft() + style.getPadRight();
int height = bottom - top;
bounds.setTop(top);
bounds.setLeft(tipX);
bounds.setHeight(height);
bounds.setWidth(width);
}
/**
* Attach this ArcEnd to the top edge of the parent widget
*/
private void attachTop() {
arcX = tipX;
arcY = tipY;
bounds.setPosition(tipX, tipY);
bounds.setWidth(0);
bounds.setHeight(0);
}
/**
* Attach this ArcEnd to the top edge of the parent widget
*/
private void attachBottom() {
arcX = tipX;
arcY = tipY;
bounds.setPosition(tipX, tipY);
bounds.setWidth(0);
bounds.setHeight(0);
if (shape != null) {
int width = (int) shape.getBounds2D().getHeight();
int height = (int) shape.getBounds2D().getWidth();
arcY += height;
bounds.setHeight(height);
bounds.setWidth(width);
}
}
public void translate(int dx, int dy) {
arcX += dx;
arcY += dy;
bounds.setPosition(bounds.getLeft()+dx, bounds.getTop()+dy);
subtitleX += dx;
subtitleY += dy;
tipX += dx;
tipY += dy;
titleX += dx;
titleY += dy;
}
/**
* Attach this ArcEnd to the right edge of the attachedWidget
*/
private void attachRight() {
FontMetrics metrics = style.getMetrics();
int shapeWidth=0;
int width = 0;
int top = tipY;
int bottom = tipY;
arcX = tipX;
arcY = tipY;
if (shape != null) {
Rectangle2D bounds = shape.getBounds2D();
shapeWidth = (int) bounds.getWidth();
int height = (int)(bounds.getHeight()/2);
arcX = tipX + shapeWidth;
top = tipY - height - style.getPadTop();
bottom = tipY + height + style.getPadBottom();
}
if (title != null) {
titleX = arcX + style.getPadLeft();
titleY = arcY - style.getPadBottom();
width = metrics.stringWidth(title);
top = Math.min(top, arcY - metrics.getMaxAscent() - style.getPadTop());
}
if (subtitle != null) {
subtitleX = arcX + style.getPadLeft();
subtitleY = arcY + style.getPadTop() + metrics.getMaxAscent();
width = Math.max(width, metrics.stringWidth(subtitle));
bottom = Math.max(bottom, subtitleY + metrics.getMaxDescent() + style.getPadBottom());
}
int height = bottom - top;
width += shapeWidth + style.getPadLeft() + style.getPadRight();
bounds.setTop(top);
bounds.setLeft(tipX);
bounds.setHeight(height);
bounds.setWidth(width);
}
public Edge getEdge() {
if (attachedWidget == null) {
throw new RuntimeException("ArcEnd is not attached to any widget");
}
if (edge == null) {
Rect bounds = attachedWidget.getBounds();
edge =
(tipX==0) ? Edge.LEFT :
(tipX==bounds.getWidth()) ? Edge.RIGHT :
(tipY==0) ? Edge.TOP :
Edge.BOTTOM;
}
return edge;
}
@Override
public void paint(Graphics2D g) {
if (title != null) {
g.setColor(style.getColor());
g.setFont(style.getFont());
g.drawString(title, titleX, titleY);
}
if (subtitle != null) {
g.setColor(style.getColor());
g.setFont(style.getFont());
g.drawString(subtitle, subtitleX, subtitleY);
}
if (shape != null) {
paintShape(g);
}
}
private void paintShape(Graphics2D g) {
g.setColor(style.getBorderColor());
AffineTransform tx = new AffineTransform(g.getTransform());
g.translate(tipX, tipY);
switch (edge) {
case BOTTOM :
g.rotate(Math.PI/2);
break;
case TOP :
g.rotate(-Math.PI/2);
break;
}
g.draw(shape);
if (filled) g.fill(shape);
g.setTransform(tx);
}
@Override
public Rect getBounds() {
return bounds;
}
@Override
public void layout() {
attachAt(tipX, tipY);
}
@Override
public void setPosition(int left, int top) {
throw new UnsupportedOperationException();
}
@Override
public Widget getParent() {
return attachedWidget;
}
@Override
public void setParent(Widget parent) {
attachedWidget = parent;
}
public String toString() {
return "ArcEnd(x=" + tipX + ", y=" + tipY + ")";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy