gpt4 book ai didi

java - 在绘制矩形和徒手绘制之间切换

转载 作者:行者123 更新时间:2023-11-29 03:15:47 26 4
gpt4 key购买 nike

我的 Java 绘画程序有一些问题。

我有一个 JComboBox,我可以在其中选择绘制矩形或徒手绘制。对象被添加到 ArrayList。我希望能够在绘制矩形和徒手绘制之间切换,然后返回绘制矩形,然后再徒手绘制……等等。

如果我按照现在的代码那样做,它首先会很好地绘制矩形,然后当我切换到自由手时它会很好地绘制线条,但是当我切换回矩形时它仍然会绘制线条(或者有时线条与看起来很奇怪的矩形)。我切换得越多,它就越奇怪。

谁能看出代码有什么问题,因为我看不到?

public abstract class Draw  {
public int startX, startY, endX, endY, width, height, w, h;
public String color = "Black";


public Draw(int startX, int startY, int width, int height) {
this.startX = startX;
this.startY = startY;
this.width = width;
this.height = height;
}

public abstract void draw(Graphics2D g);

public int getX() {
return startX;
}

public void setX(int startX) {
this.startX = startX;
}

public int getY() {
return startY;
}

public void setY(int startY) {
this.startY = startY;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}

public void setColor(String color) {
this.color = color;
}
}



public class Rectangle extends Draw {

public Rectangle(int x, int y, int width, int height) {
super(x, y, width, height);
}

@Override
public void draw(Graphics2D g2) {
g2.drawRect(getX(), getY(), getWidth(), getHeight());
}
}

public class FreeHand extends Draw {

public FreeHand(int x, int y, int width, int height) {
super(x, y, width, height);
}

@Override
public void draw(Graphics2D g2) {
g2.drawLine(getX(), getY(), getWidth(), getHeight());
}
}

public class PaintProgram extends JFrame implements ActionListener {

public ArrayList<Draw> shapeList = new ArrayList<>();
int startX, startY, endX, endY, w, h;
private JPanel topPanel;
private JPanel bottomPanel;
private JPanel leftPanel;
private JPanel rightPanel;
private JComboBox comboBox;
private final String[] boxOptions = new String[] {"Rectangle", "Freehand"};
Container cp = getContentPane();
private int count = 0;


public JavaApplication30(String title) {
super(title);
this.setLayout(new BorderLayout());
this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setSize(840, 500);
this.initComponents();
this.setVisible(true);
}


private void initComponents() {

cp.setBackground(Color.WHITE);

comboBox = new JComboBox(boxOptions);
topPanel = new JPanel();
bottomPanel = new JPanel(new GridLayout(1,2));
rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

comboBox.setSelectedIndex(0);
comboBox.addActionListener(this);

topPanel.setPreferredSize(new Dimension(0,40));
bottomPanel.setPreferredSize(new Dimension(0,30));
bottomPanel.setBackground(Color.LIGHT_GRAY);

topPanel.add(comboBox);
bottomPanel.add(leftPanel);
bottomPanel.add(rightPanel);

this.add(topPanel, BorderLayout.PAGE_START);
this.add(bottomPanel, BorderLayout.PAGE_END);
}


@Override
public void paint(Graphics g) {
if(count == 0) {
cp.repaint();
}
Graphics2D g2 = (Graphics2D) g;

for (Draw d : shapeList) {
d.draw(g2);
}

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

g2.setStroke(new BasicStroke(1));

if (startX != 0 && startY != 0 && endX != 0 && endY != 0) {

int width = Math.abs(startX - endX);
int height = Math.abs(startY - endY);

int minX = Math.min(startX, endX);
int minY = Math.min(startY, endY);

Rectangle r = new Rectangle(minX, minY, width, height);

g2.setPaint(Color.WHITE);
g2.fillRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
r.setColor(pickedColor);

r.draw(g2);
}
}


@Override
public void actionPerformed(ActionEvent e) {

count++;

if (e.getSource().equals(comboBox)) {

JComboBox cb = (JComboBox)e.getSource();

if (cb.getSelectedItem().equals("Rectangle")) {

this.addMouseListener(new MouseAdapter() {

@Override
public void mousePressed(MouseEvent e) {
startX = e.getX();
startY = e.getY();

endX = startX;
endY = startY;
repaint();
}

@Override
public void mouseReleased(MouseEvent e) {
endX = e.getX();
endY = e.getY();

int width = Math.abs(startX - endX);
int height = Math.abs(startY - endY);

int minX = Math.min(startX, endX);
int minY = Math.min(startY, endY);

Rectangle r = new Rectangle(minX, minY, width, height);
shapeList.add(r);
r.setColor(pickedColor);

startX = 0;
startY = 0;
endX = 0;
endY = 0;
repaint();
}
});

this.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
endX = e.getX();
endY = e.getY();
repaint();
}
});
}


else if (cb.getSelectedItem().equals("Freehand")) {

this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
startX = e.getX();
startY = e.getY();
addCoordinate(startX, startY);
}
});

this.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
Graphics g = getGraphics();
Graphics2D g2 = (Graphics2D) g;

FreeHand fh = new FreeHand(startX, startY, e.getX(), e.getY());
shapeList.add(fh);
fh.setColor(pickedColor);
fh.draw(g2);
startX = e.getX();
startY = e.getY();
}
});
}
}
}

public static void main(String args[]) {
new PaintProgram("Paint");
}
}

最佳答案

您添加了 MouseListener 但没有删除它们。每次您在组合框中选择某些内容时,都会添加一个新的监听器。因此,当您绘制某些内容时,每个监听器都会被应用,并且会发生奇怪的事情。

您应该在添加新的 MouseListener 之前删除之前的 MouseListener。您可能需要在实例变量中记住它。

或者,您可以在开始时添加所有监听器,但检查监听器中组合框的值。如果该值不对应于监听器的用途,则它不应该执行任何操作。

编辑:以下是删除所有听众的方法

    for (MouseListener listener : this.getMouseListeners()) {
this.removeMouseListener(listener);
}
for (MouseMotionListener listener : this.getMouseMotionListeners()) {
this.removeMouseMotionListener(listener);
}

在 actionPerformed() 方法中添加新的监听器之前放入此代码

关于java - 在绘制矩形和徒手绘制之间切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26731091/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com