222 lines
6.2 KiB
Java
222 lines
6.2 KiB
Java
package stroke;
|
|
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import java.awt.geom.*;
|
|
import javax.swing.*;
|
|
|
|
/**
|
|
* This program demonstrates different stroke types.
|
|
* @version 1.04 2016-05-10
|
|
* @author Cay Horstmann
|
|
*/
|
|
public class StrokeTest
|
|
{
|
|
public static void main(String[] args)
|
|
{
|
|
EventQueue.invokeLater(() ->
|
|
{
|
|
JFrame frame = new StrokeTestFrame();
|
|
frame.setTitle("StrokeTest");
|
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
frame.setVisible(true);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This frame lets the user choose the cap, join, and line style, and shows the resulting stroke.
|
|
*/
|
|
class StrokeTestFrame extends JFrame
|
|
{
|
|
private StrokeComponent canvas;
|
|
private JPanel buttonPanel;
|
|
|
|
public StrokeTestFrame()
|
|
{
|
|
canvas = new StrokeComponent();
|
|
add(canvas, BorderLayout.CENTER);
|
|
|
|
buttonPanel = new JPanel();
|
|
buttonPanel.setLayout(new GridLayout(3, 3));
|
|
add(buttonPanel, BorderLayout.NORTH);
|
|
|
|
ButtonGroup group1 = new ButtonGroup();
|
|
makeCapButton("Butt Cap", BasicStroke.CAP_BUTT, group1);
|
|
makeCapButton("Round Cap", BasicStroke.CAP_ROUND, group1);
|
|
makeCapButton("Square Cap", BasicStroke.CAP_SQUARE, group1);
|
|
|
|
ButtonGroup group2 = new ButtonGroup();
|
|
makeJoinButton("Miter Join", BasicStroke.JOIN_MITER, group2);
|
|
makeJoinButton("Bevel Join", BasicStroke.JOIN_BEVEL, group2);
|
|
makeJoinButton("Round Join", BasicStroke.JOIN_ROUND, group2);
|
|
|
|
ButtonGroup group3 = new ButtonGroup();
|
|
makeDashButton("Solid Line", false, group3);
|
|
makeDashButton("Dashed Line", true, group3);
|
|
}
|
|
|
|
/**
|
|
* Makes a radio button to change the cap style.
|
|
* @param label the button label
|
|
* @param style the cap style
|
|
* @param group the radio button group
|
|
*/
|
|
private void makeCapButton(String label, final int style, ButtonGroup group)
|
|
{
|
|
// select first button in group
|
|
boolean selected = group.getButtonCount() == 0;
|
|
JRadioButton button = new JRadioButton(label, selected);
|
|
buttonPanel.add(button);
|
|
group.add(button);
|
|
button.addActionListener(event -> canvas.setCap(style));
|
|
pack();
|
|
}
|
|
|
|
/**
|
|
* Makes a radio button to change the join style.
|
|
* @param label the button label
|
|
* @param style the join style
|
|
* @param group the radio button group
|
|
*/
|
|
private void makeJoinButton(String label, final int style, ButtonGroup group)
|
|
{
|
|
// select first button in group
|
|
boolean selected = group.getButtonCount() == 0;
|
|
JRadioButton button = new JRadioButton(label, selected);
|
|
buttonPanel.add(button);
|
|
group.add(button);
|
|
button.addActionListener(event -> canvas.setJoin(style));
|
|
}
|
|
|
|
/**
|
|
* Makes a radio button to set solid or dashed lines
|
|
* @param label the button label
|
|
* @param style false for solid, true for dashed lines
|
|
* @param group the radio button group
|
|
*/
|
|
private void makeDashButton(String label, final boolean style, ButtonGroup group)
|
|
{
|
|
// select first button in group
|
|
boolean selected = group.getButtonCount() == 0;
|
|
JRadioButton button = new JRadioButton(label, selected);
|
|
buttonPanel.add(button);
|
|
group.add(button);
|
|
button.addActionListener(event -> canvas.setDash(style));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This component draws two joined lines, using different stroke objects, and allows the user to
|
|
* drag the three points defining the lines.
|
|
*/
|
|
class StrokeComponent extends JComponent
|
|
{
|
|
private static final Dimension PREFERRED_SIZE = new Dimension(400, 400);
|
|
private static int SIZE = 10;
|
|
|
|
private Point2D[] points;
|
|
private int current;
|
|
private float width;
|
|
private int cap;
|
|
private int join;
|
|
private boolean dash;
|
|
|
|
public StrokeComponent()
|
|
{
|
|
addMouseListener(new MouseAdapter()
|
|
{
|
|
public void mousePressed(MouseEvent event)
|
|
{
|
|
Point p = event.getPoint();
|
|
for (int i = 0; i < points.length; i++)
|
|
{
|
|
double x = points[i].getX() - SIZE / 2;
|
|
double y = points[i].getY() - SIZE / 2;
|
|
Rectangle2D r = new Rectangle2D.Double(x, y, SIZE, SIZE);
|
|
if (r.contains(p))
|
|
{
|
|
current = i;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void mouseReleased(MouseEvent event)
|
|
{
|
|
current = -1;
|
|
}
|
|
});
|
|
|
|
addMouseMotionListener(new MouseMotionAdapter()
|
|
{
|
|
public void mouseDragged(MouseEvent event)
|
|
{
|
|
if (current == -1) return;
|
|
points[current] = event.getPoint();
|
|
repaint();
|
|
}
|
|
});
|
|
|
|
points = new Point2D[3];
|
|
points[0] = new Point2D.Double(200, 100);
|
|
points[1] = new Point2D.Double(100, 200);
|
|
points[2] = new Point2D.Double(200, 200);
|
|
current = -1;
|
|
width = 8.0F;
|
|
}
|
|
|
|
public void paintComponent(Graphics g)
|
|
{
|
|
Graphics2D g2 = (Graphics2D) g;
|
|
GeneralPath path = new GeneralPath();
|
|
path.moveTo((float) points[0].getX(), (float) points[0].getY());
|
|
for (int i = 1; i < points.length; i++)
|
|
path.lineTo((float) points[i].getX(), (float) points[i].getY());
|
|
BasicStroke stroke;
|
|
if (dash)
|
|
{
|
|
float miterLimit = 10.0F;
|
|
float[] dashPattern = { 10F, 10F, 10F, 10F, 10F, 10F, 30F, 10F, 30F, 10F, 30F, 10F, 10F,
|
|
10F, 10F, 10F, 10F, 30F };
|
|
float dashPhase = 0;
|
|
stroke = new BasicStroke(width, cap, join, miterLimit, dashPattern, dashPhase);
|
|
}
|
|
else stroke = new BasicStroke(width, cap, join);
|
|
g2.setStroke(stroke);
|
|
g2.draw(path);
|
|
}
|
|
|
|
/**
|
|
* Sets the join style.
|
|
* @param j the join style
|
|
*/
|
|
public void setJoin(int j)
|
|
{
|
|
join = j;
|
|
repaint();
|
|
}
|
|
|
|
/**
|
|
* Sets the cap style.
|
|
* @param c the cap style
|
|
*/
|
|
public void setCap(int c)
|
|
{
|
|
cap = c;
|
|
repaint();
|
|
}
|
|
|
|
/**
|
|
* Sets solid or dashed lines.
|
|
* @param d false for solid, true for dashed lines
|
|
*/
|
|
public void setDash(boolean d)
|
|
{
|
|
dash = d;
|
|
repaint();
|
|
}
|
|
|
|
public Dimension getPreferredSize() { return PREFERRED_SIZE; }
|
|
}
|