You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java绘图应用:动态设置Graphics2D笔触宽度不影响已有图形

问题解决:Java绘图应用中笔触宽度仅对新图形生效

问题说明

开发Java绘图应用时,添加了取值范围1-20、默认值1的滑块动态修改笔触宽度,新宽度能正常更新,但会影响所有已绘制图形。已将每个图形的笔触权重存储在集合中,需要修改代码让新笔触宽度仅对新建图形生效。

修改步骤

  1. 存储新图形的笔触设置:创建新图形时,将当前strokeSize转换为BasicStroke对象,存入shapeStrokeSize集合(原代码中相关代码被注释,需启用并修正类型)。
  2. 绘制时应用对应图形的笔触:移除全局统一设置笔触的代码,在绘制每个图形前,从shapeStrokeSize中取出该图形对应的笔触设置。
  3. 修正画笔工具的尺寸:让画笔工具的绘制尺寸跟随当前滑块设置的笔触宽度,而非固定值。

关键代码修改点

1. 存储新图形的笔触

在mouseReleased和mouseDragged方法中,替换原注释代码:

// 存储当前笔触设置为BasicStroke对象
shapeStrokeSize.add(new BasicStroke(strokeSize));

2. 绘制时应用对应笔触

在paint方法中,移除全局笔触设置,并在循环内为每个图形设置对应笔触:

// 移除这行全局统一设置
// graphSettings.setStroke(new BasicStroke(strokeSize));

// 循环内添加该行,为每个图形应用专属笔触
for(Shape s : shapes) {
    graphSettings.setStroke(strokeSizeCounter.next());
    // ...其余绘制代码
}

3. 修正画笔工具的尺寸

在mouseDragged的画笔逻辑中,将固定尺寸改为当前strokeSize:

aShape = drawBrush(x, y, strokeSize, strokeSize);

修改后的完整代码

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;
    
    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(new BasicStroke(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, strokeSize, strokeSize);
                        
                        shapes.add(aShape);
                        shapeFill.add(fillColor);
                        shapeStroke.add(strokeColor);
                        
                        transPercent.add(transparentVal);
                        
                        // 存储当前笔触设置
                        shapeStrokeSize.add(new BasicStroke(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.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);
                
                // 预览时使用当前设置的笔触
                graphSettings.setStroke(new BasicStroke(strokeSize));
                
                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();
            }
            
        }
        
    }
    
}

内容的提问来源于stack exchange,提问作者Petarnan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 10:37:32