Własny kształt: Arrow – strzałka
Klasy
Klasa Arrow
package arrow; import java.awt.*; import java.awt.geom.*; /** * Klasa umożliwiająca tworzenie obiektów typu Arrow (strzałka). Obiekt tej * klasy może być rysowany podobnie jak inne kształty Javy, a więc tylko kontur, * tylko wypełnienie albo kontur z wypełnieniem. Strzałka może mieć dowolny * kolor. Kontur może mieć dowolny kolor i być dowolnego typu. */ class Arrow implements Shape { private final GeneralPath path; /** * Tworzy obiekt typu Arrow * * @param endX float - współrzędna x tylnego końca strzałki * @param endY float - współrzędna y tylnego końca strzałki * @param arrowWidth float - długość strzałki * @param arrowHeight float - grubość strzałki * @param arrowAngle float - kat pod ktorym jest skierowana strzalka * katy podawane sa w stopniach, kat zerowy to polozenie godziny 3.00, * katy wzrastaja w kierunku przeciwnym do wskazowek zegara * @param brudWidth float - długość grota mierzona wzdłuż osi strzałki * @param brudAngle float - kąt między osią strzałki a brzegiem grota * @param close boolean - * <ul> * <li>true - grot bez wcięcia * * <li>false - grot z wcięciem * </ul> */ public Arrow(float endX, float endY, float arrowWidth, float arrowHeight, float arrowAngle, float brudWidth, float brudAngle, boolean close) { float cosa = (float) Math.cos(Math.toRadians(arrowAngle)); float sina = (float) Math.sin(Math.toRadians(arrowAngle)); float half = arrowHeight / 2f; float cosah = cosa * half; float sinah = sina * half; float startX = endX + arrowWidth * (float) Math.cos(Math.toRadians(-arrowAngle)); float startY = endY + arrowWidth * (float) Math.sin(Math.toRadians(-arrowAngle)); float middleX = endX + (arrowWidth - brudWidth) * (float) Math.cos(Math.toRadians(-arrowAngle));//x7 float middleY = endY + (arrowWidth - brudWidth) * (float) Math.sin(Math.toRadians(-arrowAngle));//y7 float cosb = (float) Math.cos(Math.toRadians(brudAngle)); float sinb = (float) Math.sin(Math.toRadians(brudAngle)); float w2 = half * cosb / sinb; float mmiddleX = endX + (arrowWidth - w2) * (float) Math.cos(Math.toRadians(-arrowAngle));// float mmiddleY = endY + (arrowWidth - w2) * (float) Math.sin(Math.toRadians(-arrowAngle));// float w3 = brudWidth - w2; float w4 = w3 * sinb / cosb; float w5 = w4 + half; //- float x1 = endX - sinah; float y1 = endY - cosah; float x2 = endX + sinah; float y2 = endY + cosah; float x5 = middleX + sinah; float y5 = middleY + cosah; float x6 = middleX - sinah; float y6 = middleY - cosah; float x8 = mmiddleX + sinah; float y8 = mmiddleY + cosah; float x9 = mmiddleX - sinah; float y9 = mmiddleY - cosah; float x10 = middleX + sina * w5; float y10 = middleY + cosa * w5; float x11 = middleX - sina * w5; float y11 = middleY - cosa * w5; //- path = new GeneralPath(); if (close) { path.moveTo(x1, y1); path.lineTo(x2, y2); path.lineTo(x5, y5); path.lineTo(x10, y10); path.lineTo(x8, y8); path.lineTo(startX, startY); path.lineTo(x9, y9); path.lineTo(x11, y11); path.lineTo(x6, y6); path.closePath(); } else { path.moveTo(x1, y1); path.lineTo(x2, y2); path.lineTo(x8, y8); path.lineTo(startX, startY); path.lineTo(x9, y9); path.lineTo(x1, y1); path.moveTo(x11, y11); path.lineTo(x9, y9); path.moveTo(x10, y10); path.lineTo(x8, y8); } } @Override public boolean contains(Point2D p) { return path.contains(p); } @Override public boolean contains(Rectangle2D r) { return path.contains(r); } @Override public boolean contains(double x, double y) { return path.contains(x, y); } @Override public boolean contains(double x, double y, double w, double h) { return path.contains(x, y, w, h); } @Override public Rectangle getBounds() { return path.getBounds(); } @Override public Rectangle2D getBounds2D() { return path.getBounds2D(); } @Override public PathIterator getPathIterator(AffineTransform at) { return path.getPathIterator(at); } @Override public PathIterator getPathIterator(AffineTransform at, double flatness) { return path.getPathIterator(at, flatness); } @Override public boolean intersects(Rectangle2D r) { return path.intersects(r); } @Override public boolean intersects(double x, double y, double w, double h) { return path.intersects(x, y, w, h); } }
Klasa ArrowPanel
package arrow; import java.awt.*; import javax.swing.*; class ArrowPanel extends JPanel { private static final long serialVersionUID = 8983225865613648722L; public ArrowPanel() { setPreferredSize(new Dimension(500, 300)); setBounds(0, 0, 500, 300); //setBackground(Color.BLUE); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Arrow ar = new Arrow(100f, 100f, 200f, 30f, 25f, 75f, 25f, false); g2.setColor(Color.RED); BasicStroke stroke = new BasicStroke(5); g2.setStroke(stroke); g2.fill(ar); g2.setColor(Color.BLACK); g2.draw(ar); Arrow ar1 = new Arrow(300f, 100f, 200f, 30f, 25f, 75f, 25f, true); g2.setColor(Color.MAGENTA); BasicStroke stroke1 = new BasicStroke(5); g2.setStroke(stroke1); g2.draw(ar1); g2.fill(ar1); Arrow ar2 = new Arrow(100f, 200f, 100f, 2f, 35f, 15f, 15f, true); g2.setColor(Color.BLUE); g2.fill(ar2); Arrow ar3 = new Arrow(250f, 150f, 100f, 2f, 235f, 50f, 5f, true); g2.setColor(Color.ORANGE); g2.fill(ar3); Arrow ar4 = new Arrow(450f, 150f, 200f, 10f, 190f, 45f, 15f, false); g2.setColor(Color.CYAN); BasicStroke stroke2 = new BasicStroke(5, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND); g2.setStroke(stroke2); g2.draw(ar4); g2.fill(ar4); } }
Klasa Main
package arrow; import java.awt.*; import javax.swing.*; class Main extends JFrame { private static final long serialVersionUID = 1L; public static void main(String[] args) { SwingUtilities.invokeLater(() -> new Main(new ArrowPanel())); } private Main(JComponent comp) { JPanel panel = (JPanel) comp; panel.setLayout(null); int frameWidth = 530; int frameHeight = 300; panel.setBounds(0, 0, frameWidth, frameHeight); //panel.setBounds(0, 0, 256, 256); setLayout(null); setPreferredSize(new Dimension(500, 300)); setBounds((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - (frameWidth / 2), (Toolkit.getDefaultToolkit() .getScreenSize().height / 2) - (frameHeight / 2), frameWidth, frameHeight); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Ramka Graficzna"); // setResizable(false); add(panel); setVisible(true); } }
Wynik