
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