📄 graphicstoolkit.java
字号:
package toocom.ocgl;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.lang.*;
/**
* This class provides graphical methods to paint conceptual primitives hierarchies, graphs
* and axioms.
*
* @author Fr閐閞ic F黵st
*/
public class GraphicsToolkit{
/** Returns the point where the string needs to be drawn to fit in the rectangular bound with the
* specified center, according to the font size of the Graphics object. */
public static Point getTextPosition(Graphics g, String s, Point center){
Rectangle2D r;
if(s != null) r = g.getFont().getStringBounds(s,new FontRenderContext(null,true,true));
else r = new Rectangle(CGConstants.CONCEPTUAL_BOX_MIN_WIDTH,CGConstants.CONCEPTUAL_BOX_MIN_HEIGHT);
return new Point(center.x-(int) (r.getWidth()/2),center.y+(int) (r.getHeight()/2) - 3);
}
/** Returns the wide rectangular bounds of the string with the specified center,
* according to the font size of the Graphics object. The rectangle is wider than the strictly
* bounding area, in order to give a nice image. */
public static Rectangle getRectangularBounds(Graphics g, String s, Point Center){
Rectangle2D r;
if(s != null) r = g.getFont().getStringBounds(s,new FontRenderContext(null,true,true));
else r = new Rectangle(CGConstants.CONCEPTUAL_BOX_MIN_WIDTH,CGConstants.CONCEPTUAL_BOX_MIN_HEIGHT);
return new Rectangle( Center.x-6-(int)(r.getWidth()/2),
Center.y-3-(int)(r.getHeight()/2),
(int) (r.getWidth() + 12),
(int) (r.getHeight() + 6));
}
/** Returns the wide elliptical bounds of the string with the specified center for
* the rectangular bounds of the string, according to the font size of the Graphics object.
* The rectangle is wider than the strictly bounding area, in order to give a nice image.
*/
public static Ellipse2D getEllipticalBounds(Graphics g, String s, Point center){
Rectangle r;
if(s != null) r = GraphicsToolkit.getRectangularBounds(g,s,center);
else r = new Rectangle(CGConstants.CONCEPTUAL_BOX_MIN_WIDTH,CGConstants.CONCEPTUAL_BOX_MIN_HEIGHT);
return new Ellipse2D.Double( center.x - (r.getWidth()*0.75),
center.y - (r.getHeight()*0.625),
1.5*r.getWidth(),
1.25*r.getHeight());
}
/** Paint on the Graphics object a line between the two points with an arrow in the middle
* of the line, oriented from p1 to p2.
*/
public static void paintArrowLine(Graphics g, Point p1, Point p2){
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(CGConstants.LINK_STROKE_WIDTH));
g2d.setColor(CGConstants.GENERAL_LINK_COLOR);
g2d.drawLine(p1.x,p1.y,p2.x,p2.y);
double dist = Math.sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
double alpha = Math.PI/4.0;
double l = 10.0;
double dx = p1.x - p2.x;
double dy = p1.y - p2.y;
double rapport = l/dist;
int x = (int) ((dx*Math.cos(alpha) + dy*Math.sin(alpha))*rapport + (p1.x + p2.x)/2);
int y = (int) ((dy*Math.cos(alpha) - dx*Math.sin(alpha))*rapport + (p1.y + p2.y)/2);
g2d.drawLine(x,y,(p1.x + p2.x)/2,(p1.y + p2.y)/2);
x = (int) ((dx*Math.cos(alpha) - dy*Math.sin(alpha))*rapport + (p1.x + p2.x)/2);
y = (int) ((dy*Math.cos(alpha) + dx*Math.sin(alpha))*rapport + (p1.y + p2.y)/2);
g2d.drawLine(x,y,(p1.x + p2.x)/2,(p1.y + p2.y)/2);
g2d.setStroke(new BasicStroke(1));
}
/** Paint on the Graphics object a line between the two points. */
public static void paintLine(Graphics g, Point p1, Point p2){
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(CGConstants.LINK_STROKE_WIDTH));
g2d.setColor(CGConstants.GENERAL_LINK_COLOR);
g2d.drawLine(p1.x,p1.y,p2.x,p2.y);
g2d.setStroke(new BasicStroke(1));
}
/** Paint on the Graphics object a line between the two points with the given label centered. */
public static void paintLabelledLine(Graphics g, Point p1, Point p2, String label){
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(CGConstants.LINK_STROKE_WIDTH));
g2d.setColor(CGConstants.GENERAL_LINK_COLOR);
System.out.println("paint "+label);
g2d.drawLine(p1.x,p1.y,p2.x,p2.y);
g2d.setStroke(new BasicStroke(1));
g2d.drawString(label,(p1.x + p2.x)/2,(p1.y + p2.y)/2);
}
/** Returns true if the arrow line between p1 and p2 contains p (including the case of p in
* a branch of the arrow), returns false otherwise. */
public static boolean arrowLineContainsPoint(Graphics g, Point p1, Point p2, Point p){
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(CGConstants.LINK_STROKE_WIDTH));
boolean result = g2d.getStroke().createStrokedShape(new Line2D.Double(p1.x,p1.y,p2.x,p2.y)).contains(p.x,p.y);
double dist = Math.sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
double alpha = Math.PI/4.0;
double l = 10.0;
double dx = p1.x - p2.x;
double dy = p1.y - p2.y;
double rapport = l/dist;
int x = (int) ((dx*Math.cos(alpha) + dy*Math.sin(alpha))*rapport + (p1.x + p2.x)/2);
int y = (int) ((dy*Math.cos(alpha) - dx*Math.sin(alpha))*rapport + (p1.y + p2.y)/2);
result = result || g2d.getStroke().createStrokedShape(new Line2D.Double(x,y,(p1.x + p2.x)/2,(p1.y + p2.y)/2)).contains(p.x,p.y);
x = (int) ((dx*Math.cos(alpha) - dy*Math.sin(alpha))*rapport + (p1.x + p2.x)/2);
y = (int) ((dy*Math.cos(alpha) + dx*Math.sin(alpha))*rapport + (p1.y + p2.y)/2);
result = result || g2d.getStroke().createStrokedShape(new Line2D.Double(x,y,(p1.x + p2.x)/2,(p1.y + p2.y)/2)).contains(p.x,p.y);
g2d.setStroke(new BasicStroke(1));
return result;
}
/** Returns true if the line between p1 and p2 contains p, returns false otherwise. */
public static boolean lineContainsPoint(Graphics g, Point p1, Point p2, Point p){
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke((int) (CGConstants.LINK_STROKE_MODIFIER*CGConstants.LINK_STROKE_WIDTH)));
boolean result = g2d.getStroke().createStrokedShape(new Line2D.Double(p1.x,p1.y,p2.x,p2.y)).contains(p.x,p.y);
g2d.setStroke(new BasicStroke(1));
return result;
}
/** Draws on g a circle in the center of the segment [(x1,y1),(x2,y2)] and with a cross in the circle.
* Also draws liknks between the circle and the extremities of th segment. */
public static void drawLinkedCrossCircle(Graphics g,int x1, int y1, int x2, int y2,Color c){
int a = (x1 + x2)/2;
int b = (y1 + y2)/2;
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(CGConstants.CROSS_CIRCLE_STROKE_WIDTH));
g2d.setColor(c);
g2d.drawLine(x1,y1,x2,y2);
//g2d.fillOval(a - CGConstants.CROSS_CIRCLE_RADIUS,b - CGConstants.CROSS_CIRCLE_RADIUS,2*CGConstants.CROSS_CIRCLE_RADIUS,2*CGConstants.CROSS_CIRCLE_RADIUS);
g2d.drawOval(a - CGConstants.CROSS_CIRCLE_RADIUS,b - CGConstants.CROSS_CIRCLE_RADIUS,2*CGConstants.CROSS_CIRCLE_RADIUS,2*CGConstants.CROSS_CIRCLE_RADIUS);
double temp = Math.sqrt(CGConstants.CROSS_CIRCLE_RADIUS*CGConstants.CROSS_CIRCLE_RADIUS/2);
g2d.drawLine((int) (a - temp),(int) (b - temp),(int) (a + temp), (int) (b + temp));
g2d.drawLine((int) (a - temp),(int) (b + temp),(int) (a + temp), (int) (b - temp));
g2d.setStroke(new BasicStroke(1));
}
/** Draws on g a circle in the center of the segment [(x1,y1),(x2,y2)] and with a cross in the circle.
* Also draws liknks between the circle and the extremities of th segment. Draw only both out of the
* given bounds. */
public static void drawLinkedCrossCircle(Graphics g,int x1, int y1, int x2, int y2,Color c,RectangularShape r1,RectangularShape r2){
double x;
double y;
double h;
double w;
if(y2 <= (((x2 - r1.getX())*r1.getHeight()/r1.getWidth()) + r1.getY())){
// Nord East
if(y2 <= (((x2 - r1.getX())*(-1)*r1.getHeight()/r1.getWidth()) + (r1.getY() + r1.getHeight()))){
// Nord
x = Math.min(r1.getX(),r2.getX());
y = r2.getY() + r2.getHeight();
w = Math.max(r2.getX() + r2.getWidth(),r1.getX() + r1.getWidth()) - x;
h = r1.getY() - y;
}
else{
// East
x = r1.getX() + r1.getWidth();
y = Math.min(r2.getY(),r1.getY());
w = r2.getX() - x;
h = Math.max(r2.getY() + r2.getHeight(),r1.getY() + r1.getHeight()) - y;
}
}
else{
// South West
if(y2 <= (((x2 - r1.getX())*(-1)*r1.getHeight()/r1.getWidth()) + (r1.getY() + r1.getHeight()))){
// West
x = r2.getX() + r2.getWidth();
y = Math.min(r2.getY(),r1.getY());
w = r1.getX() - x;
h = Math.max(r2.getY() + r2.getHeight(),r1.getY() + r1.getHeight()) - y;
}
else{
// South
x = Math.min(r1.getX(),r2.getX());
y = r1.getY() + r1.getHeight();
w = Math.max(r2.getX() + r2.getWidth(),r1.getX() + r1.getWidth()) - x;
h = r2.getY() - y;
}
}
g.clipRect((int) x,(int) y,(int) w,(int) h);
GraphicsToolkit.drawLinkedCrossCircle(g,x1,y1,x2,y2,c);
g.setClip(null);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -