我有一个组合框,我可以选择绘制矩形,圆形或手绘。 如果我选择绘制一个圆圈,它会完美地绘制它。如果我然后切换到绘制一个矩形,它会在矩形内部绘制一个圆圈。如果我首先选择绘制矩形然后再绘制圆圈,也会发生同样的情况。 (见下图)
我的问题是:
如何在没有圆形出现在矩形内部的情况下,在绘制圆形和矩形之间切换?
如何在拖动鼠标时显示矩形/圆圈。我的意思是在我释放鼠标之前线条如何显示?
为什么不用空手画?
这是我的测试类:
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;
}
}
答案 0 :(得分:3)
有很多事情正在发生......
paint
JFrame
super.paint
。MosueListener
相反,创建一个自定义组件,从JPanel
扩展并覆盖它的paintComponent
方法。使用此组件具有基本绘图表面(您的控件应包含在另一个组件中)。
确保在执行任何自定义绘画之前致电super.paintComponent
,这样您就不会打破油漆链
有关详细信息,请参阅Performing Custom Painting和Painting in AWT and Swing
创建一个单MouseListener
并将其注册到面板。当用户选择不同的形状时,更改面板中的状态变量(通过设置器),告诉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...
}
}
向自定义类添加SINGLE 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
属性...