Zielony Smok - logo witryny

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

Rys. 148. Różne strzałki