gpt4 book ai didi

java - 在对象之间切换时如何摆脱矩形内的圆圈

转载 作者:行者123 更新时间:2023-12-01 22:37:39 24 4
gpt4 key购买 nike

我有一个组合框,我可以在其中选择绘制矩形、圆形或徒手绘制。如果我选择画一个圆圈,它就会完美地画出来。如果我然后切换到绘制一个矩形,它会在矩形内绘制一个圆。如果我首先选择绘制一个矩形然后绘制一个圆形,也会发生同样的情况。 (见下图)

我的问题是:

  1. 如何在绘制圆形和矩形之间切换而不让圆形出现在矩形内?

  2. 如何在拖动鼠标时显示矩形/圆形。我的意思是,在我释放鼠标单击之前,线条如何显示?

  3. 为什么不能徒手绘图?

enter image description here

这是我的测试类:

import java.awt.*; 
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class Lab6 extends JFrame implements ActionListener {
int startX, startY, endX, endY, w, h;
ArrayList<Shape> shapeList = new ArrayList<Shape>();
Container cp = getContentPane();

private JPanel topPanel;
private JComboBox comboBox;
private final String[] boxOptions = new String[] {"Rektangel", "Cirkel", "Frihand"};


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


private void initComponents() {
topPanel = new JPanel(new GridLayout(1,2));
topPanel.setPreferredSize(new Dimension(0,40));

comboBox = new JComboBox(boxOptions);
comboBox.setSelectedIndex(0);
comboBox.addActionListener(this);

topPanel.add(comboBox);
this.add(topPanel, BorderLayout.PAGE_START);
}

@Override
public void paint(Graphics g) {
for (Shape s : shapeList) {
s.draw(g);
}
}

@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(comboBox)) {
JComboBox cb = (JComboBox)e.getSource();
if (cb.getSelectedItem().equals("Rektangel")) {
cp.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
startX = e.getX();
startY = e.getY();
}
@Override
public void mouseReleased(MouseEvent e) {
endX = e.getX();
endY = e.getY();

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

Rectangle r = new Rectangle(startX, startY, w, h);

shapeList.add(r);
repaint();
}
});
}
else if (cb.getSelectedItem().equals("Cirkel")) {

cp.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
startX = e.getX();
startY = e.getY();
}
@Override
public void mouseReleased(MouseEvent e) {
endX = e.getX();
endY = e.getY();

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

Circle c = new Circle(startX, startY, w, h);

shapeList.add(c);
repaint();
}
});
}
else if (cb.getSelectedItem().equals("Frihand")) { //I need help with this part

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

FreeHand fh = new FreeHand(startX, startY, e.getX(), e.getY());

shapeList.add(fh);
repaint();
}
});

}
}
}

public static void main(String args[]) {
new Lab6("Drawing Program");
}
}

在 Rectangle 类中(Circle 类看起来相同):

import java.awt.*;

public class Rectangle extends Shape {

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

public Rectangle() {
super();
}

@Override
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(4));
g.drawRect(getX(), getY(), getWidth(), getHeight());
}
}

在 FreeHand 类中(我需要这部分的帮助):

import java.awt.*;

public class FreeHand extends Shape {

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

public FreeHand() {
super();
}

@Override
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLUE);
g2.setStroke(new BasicStroke(4));
g2.drawLine(getX(), getY(), getWidth(), getHeight());
}
}

类形状:

import java.awt.Graphics;
import javax.swing.JPanel;

public abstract class Shape extends JPanel {

private int startX, startY, width, height;

public Shape() {
this(0, 0, 1, 1);
}

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

public abstract void draw(Graphics g);

@Override
public int getX() {
return startX;
}

@Override
public int getY() {
return startY;
}

@Override
public int getWidth() {
return width;
}

@Override
public int getHeight() {
return height;
}
}

最佳答案

发生了很多事情......

  1. 重写JFramepaint
  2. 在执行自定义绘制之前不调用 super.paint
  3. 每次更改形状时添加新的 MosueListener

相反,创建一个自定义组件,从JPanel之类的东西扩展,并覆盖它的paintComponent方法。使用此组件具有您的基本绘图表面(您的控件应包含在另一个组件中)。

确保在执行任何自定义绘制之前调用 super.paintComponent,这样就不会破坏绘制链

参见Performing Custom PaintingPainting in AWT and Swing了解更多详情

创建一个MouseListener并将其注册到面板。当用户选择不同的形状时,更改面板内的状态变量(通过 setter ),该变量告诉 MouseListener 当用户开始绘图时它应该做什么。

已更新...

创建一个从 JPanel 扩展的自定义类...

public static class ShapePane extends JPanel {

}

重写类paintComponent方法...

public static class ShapePane extends JPanel {

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Custom Painting here...
}

}

为布局管理器提供一些大小调整提示...

public static class ShapePane extends JPanel {

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Custom Painting here...
}

public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

}

提供一种可以更改形状类型的方法...以便您知道要绘制什么...

public static class ShapePane extends JPanel {

public enum ShapeType {

CIRCLE,
RECTANGLE
}

private ShapeType currentShapeType;

public void setCurrentShapeType(ShapeType currentShapeType) {
this.currentShapeType = currentShapeType;
}

public ShapeType getCurrentShapeType() {
return currentShapeType;
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Custom Painting here...
}

}

向自定义类添加一个 MouseListener 以创建所需的形状类型...

public static class ShapePane extends JPanel {

public enum ShapeType {

CIRCLE,
RECTANGLE
}

private ShapeType currentShapeType;

public ShapePane() {
addMouseListener(new MouseAdapter() {

private Point clickPoint;

@Override
public void mousePressed(MouseEvent e) {
clickPoint = e.getPoint();
}

@Override
public void mouseReleased(MouseEvent e) {
Point releasePoint = e.getPoint();
int x = Math.min(releasePoint.x, clickPoint.x);
int y = Math.min(releasePoint.y, clickPoint.y);
int width = Math.abs(clickPoint.x - releasePoint.x);
int height = Math.abs(clickPoint.y - releasePoint.y);
switch (getCurrentShapeType()) {
case CIRCLE:
// Make a circle
break;
case RECTANGLE:
// Make a rectangle...
break;
}
repaint();
}

});
}

public void setCurrentShapeType(ShapeType currentShapeType) {
this.currentShapeType = currentShapeType;
}

public ShapeType getCurrentShapeType() {
return currentShapeType;
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Custom Painting here...
}

}

填空...

创建另一个JPanel(这次您可以简单地创建一个实例),向其中添加您的控件

创建 JFrame 的实例,向其添加自定义类和控制面板(确保它们布局正确,这样它们就不会相互覆盖 - 有关更多信息,请参阅 Laying Out Components Within a Container详情)

使用适当的控件监听器来确定用户想要绘制的形状类型,并相应地设置 currentShapeType 属性...

关于java - 在对象之间切换时如何摆脱矩形内的圆圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26662768/

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