我有 Java Paint 应用程序的代码。 我添加了一个从 1 更改为 20 的滑块,默认大小为 1。此滑块用于动态更改描边大小,因此我创建了一个变量描边大小值和滑块 + 侦听器,新的描边大小会更新并正常工作很好,但它会更新数组中添加的所有形状。即使对于已经绘制的形状也是如此。 我将各个笔画粗细与对象一起保存在多维数组中。 我如何更改它,以便它不会更新数组中的所有形状,并且仅对新创建的形状有效?
我猜这行造成了问题: graphSettings.setStroke(StrokeSizeCounter.next());
谢谢
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
import java.awt.*;
import java.awt.geom.*;
import java.text.DecimalFormat;
import java.util.*;
@SuppressWarnings("serial")
public class Lesson48 extends JFrame{
JButton brushBut, lineBut, ellipseBut, rectBut, strokeBut, fillBut;
JSlider transSlider;
JLabel transLabel;
DecimalFormat dec = new DecimalFormat("#.##");
JSlider strokeSizeSlider;
JLabel strokeSizeLabel;
Graphics2D graphSettings;
int strokeSize;
//graphSettings.setStroke(new BasicStroke(5f));
int currentAction = 1;
float transparentVal = 1.0f;
Color strokeColor = Color.BLACK, fillColor = Color.BLACK;
public static void main(String[] args) {
new Lesson48();
}
public Lesson48() {
this.setSize(1000, 600);
this.setTitle("Java Paint");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel buttonPanel = new JPanel();
Box theBox = Box.createHorizontalBox();
brushBut = makeMeButtons("./src/Brush.png", 1);
lineBut = makeMeButtons("./src/Line.png", 2);
ellipseBut = makeMeButtons("./src/Ellipse.png", 3);
rectBut = makeMeButtons("./src/Rectangle.png", 4);
strokeBut = makeMeColorButton("./src/Stroke.png", 5, true);
fillBut = makeMeColorButton("./src/Fill.png", 6, false);
theBox.add(brushBut);
theBox.add(lineBut);
theBox.add(ellipseBut);
theBox.add(rectBut);
theBox.add(strokeBut);
theBox.add(fillBut);
transLabel = new JLabel(" Transparent: 1");
transSlider = new JSlider(1, 99, 99);
ListenerForSlider lForSlider = new ListenerForSlider();
transSlider.addChangeListener(lForSlider);
theBox.add(transLabel);
theBox.add(transSlider);
// changing the strokeSize dynamically
strokeSizeLabel = new JLabel(" Stroke: 1");
strokeSizeSlider = new JSlider(1, 20, 1);
ListenerForSlider2 sForSlider = new ListenerForSlider2();
strokeSizeSlider.addChangeListener(sForSlider);
theBox.add(strokeSizeLabel);
theBox.add(strokeSizeSlider);
buttonPanel.add(theBox);
this.add(buttonPanel, BorderLayout.SOUTH);
this.add(new DrawingBoard(), BorderLayout.CENTER);
this.setVisible(true);
}
public JButton makeMeButtons(String iconFile, final int actionNum) {
JButton theBut = new JButton();
Icon butIcon = new ImageIcon(iconFile);
theBut.setIcon(butIcon);
theBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
currentAction = actionNum;
}
});
return theBut;
}
public JButton makeMeColorButton(String iconFile, final int actionNum, final boolean stroke) {
JButton theBut = new JButton();
Icon butIcon = new ImageIcon(iconFile);
theBut.setIcon(butIcon);
theBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(stroke) {
strokeColor = JColorChooser.showDialog(null, "Pick a Stroke", Color.BLACK);
} else {
fillColor = JColorChooser.showDialog(null, "Pick a Fill", Color.BLACK);
}
}
});
return theBut;
}
private class DrawingBoard extends JComponent{
ArrayList<Shape> shapes = new ArrayList<Shape>();
ArrayList<Color> shapeFill = new ArrayList<Color>();
ArrayList<Color> shapeStroke = new ArrayList<Color>();
ArrayList<Float> transPercent = new ArrayList<Float>();
ArrayList<Stroke> shapeStrokeSize = new ArrayList<Stroke>();
Point drawStart, drawEnd;
public DrawingBoard() {
this.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if(currentAction != 1) {
drawStart = new Point(e.getX(), e.getY());
drawEnd = drawStart;
repaint();
}
}
public void mouseReleased(MouseEvent e) {
if(currentAction != 1) {
Shape aShape = null;
if(currentAction == 2) {
aShape = drawLine(drawStart.x, drawStart.y, e.getX(), e.getY());
} else
if(currentAction == 3) {
aShape = drawEllipse(drawStart.x, drawStart.y, e.getX(), e.getY());
} else
if(currentAction == 4) {
aShape = drawRectangle(drawStart.x, drawStart.y, e.getX(), e.getY());
}
shapes.add(aShape);
shapeFill.add(fillColor);
shapeStroke.add(strokeColor);
transPercent.add(transparentVal);
//shapeStrokeSize.add(strokeSize);
drawStart = null;
drawEnd = null;
repaint();
}
}
});
this.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if(currentAction == 1) {
int x = e.getX();
int y = e.getY();
Shape aShape = null;
strokeColor = fillColor;
aShape = drawBrush(x, y, 2, 2);
shapes.add(aShape);
shapeFill.add(fillColor);
shapeStroke.add(strokeColor);
transPercent.add(transparentVal);
//shapeStrokeSize.add(strokeSize);
}
drawEnd = new Point(e.getX(), e.getY());
repaint();
}
});
}
public void paint(Graphics g) {
graphSettings = (Graphics2D)g;
graphSettings.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphSettings.setStroke(new BasicStroke(strokeSize));
Iterator<Color> strokeCounter = shapeStroke.iterator();
Iterator<Color> fillCounter = shapeFill.iterator();
Iterator<Float> transCounter = transPercent.iterator();
Iterator<Stroke> strokeSizeCounter = shapeStrokeSize.iterator();
for(Shape s : shapes) {
//graphSettings.setStroke(strokeSizeCounter.next());
//graphSettings.draw(s);
graphSettings.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, transCounter.next()));
graphSettings.setPaint(strokeCounter.next());
graphSettings.draw(s);
graphSettings.setPaint(fillCounter.next());
graphSettings.fill(s);
}
if(drawStart != null && drawEnd != null) {
graphSettings.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
graphSettings.setPaint(Color.LIGHT_GRAY);
Shape aShape = null;
if(currentAction == 2) {
aShape = drawLine(drawStart.x, drawStart.y, drawEnd.x, drawEnd.y);
} else
if(currentAction == 3) {
aShape = drawEllipse(drawStart.x, drawStart.y, drawEnd.x, drawEnd.y);
} else
if(currentAction == 4) {
aShape = drawRectangle(drawStart.x, drawStart.y, drawEnd.x, drawEnd.y);
}
graphSettings.draw(aShape);
}
}
private Rectangle2D.Float drawRectangle(int x1, int y1, int x2, int y2){
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int width = Math.abs(x1-x2);
int height = Math.abs(y1-y2);
return new Rectangle2D.Float(x, y, width, height);
}
private Ellipse2D.Float drawEllipse(int x1, int y1, int x2, int y2){
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int width = Math.abs(x1-x2);
int height = Math.abs(y1-y2);
return new Ellipse2D.Float(x, y, width, height);
}
private Line2D.Float drawLine(int x1, int y1, int x2, int y2){
return new Line2D.Float(x1, y1, x2, y2);
}
private Ellipse2D.Float drawBrush(int x1, int y1, int brushStrokeWidth, int brushStrokeHeight){
return new Ellipse2D.Float(x1, y1, brushStrokeWidth, brushStrokeHeight);
}
}
private class ListenerForSlider implements ChangeListener{
public void stateChanged(ChangeEvent e) {
if(e.getSource() == transSlider) {
transLabel.setText(" Transparent: " + dec.format(transSlider.getValue() * .01));
transparentVal = (float) (transSlider.getValue() * .01);
}
}
}
private class ListenerForSlider2 implements ChangeListener{
public void stateChanged(ChangeEvent e) {
if(e.getSource() == strokeSizeSlider) {
strokeSizeLabel.setText(" Stroke: " + strokeSizeSlider.getValue());
strokeSize = strokeSizeSlider.getValue();
}
}
}
}
如果这是我的项目,我会绘制到离屏缓冲区(BufferedImage),然后在我的绘画方法中显示该图像。这样,当前笔划宽度将仅用于最新的绘图。我也想:
例如:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class Lesson48b extends JPanel {
private static final int BI_WIDTH = 1000;
private static final int BI_HEIGHT = 600;
private BufferedImage buffer;
private JSlider strokeWidthSlider = new JSlider(0, 20, 1);
private JButton cleaButton = new JButton("Clear");
public Lesson48b() {
// give the drawing a white background
clearImage();
strokeWidthSlider.setMajorTickSpacing(5);
strokeWidthSlider.setMinorTickSpacing(1);
strokeWidthSlider.setPaintTicks(true);
strokeWidthSlider.setPaintLabels(true);
strokeWidthSlider.setOpaque(false);
add(strokeWidthSlider);
cleaButton.addActionListener(e -> clearImage());
add(cleaButton);
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
private void clearImage() {
buffer = new BufferedImage(BI_WIDTH, BI_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = buffer.createGraphics();
g2d.setBackground(Color.WHITE);
g2d.clearRect(0, 0, BI_WIDTH, BI_HEIGHT);
g2d.dispose();
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(BI_WIDTH, BI_HEIGHT);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (buffer != null) {
g.drawImage(buffer, 0, 0, this);
}
}
class MyMouse extends MouseAdapter {
private int x1, y1;
Graphics2D g2d;
public void mousePressed(MouseEvent e) {
// set my x1 and y1 points for drawing.
x1 = e.getX();
y1 = e.getY();
// create a graphics object to draw to
g2d = buffer.createGraphics();
// smooth the drawing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// use the current stroke width value from the slider
int strokeWidth = strokeWidthSlider.getValue();
g2d.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
// generate a random color
float hue = (float) Math.random();
float saturation = (float) (0.5 * Math.random() + 0.5);
float brightness = 1f;
Color randomColr = Color.getHSBColor(hue, saturation, brightness);
g2d.setColor(randomColr);
// draw a single point
g2d.drawLine(x1, y1, x1, y1);
repaint();
}
public void mouseDragged(MouseEvent e) {
if (g2d == null) {
return;
}
// get the next point
int x2 = e.getX();
int y2 = e.getY();
// draw a connecting line
g2d.drawLine(x1, y1, x2, y2);
// reset the points
x1 = x2;
y1 = y2;
repaint();
}
public void mouseReleased(MouseEvent e) {
if (g2d == null) {
return;
}
int x2 = e.getX();
int y2 = e.getY();
g2d.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
repaint();
// dispose of the Graphics object
g2d.dispose();
g2d = null;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Lesson48b mainPanel = new Lesson48b();
JFrame frame = new JFrame("Java Paint");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}