我有一个组合框,我可以选择绘制矩形,圆形或手绘.
如果我选择绘制一个圆圈,它会完美地绘制它.如果我然后切换到绘制一个矩形,它会在矩形内部绘制一个圆圈.如果我首先选择绘制矩形然后再绘制圆圈,也会发生同样的情况. (见下图)
我的问题是:
>如何在没有圆形出现在矩形内部的情况下切换圆形和矩形之间切换?
>当我拖动鼠标时,如何显示矩形/圆圈.我的意思是,在我发布鼠标点击之前,线条是如何显示的?
>为什么不用空手画?
这是我的测试类:
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 shapeList = new ArrayList();
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;
}
}
解决方法:
有很多事情正在发生……
>覆盖JFrame的绘制
>在执行自定义绘画之前不调用super.paint.
>每次更改形状时添加新的MosueListener
相反,创建一个自定义组件,从JPanel扩展并覆盖它的paintComponent方法.使用此组件具有基本绘图表面(您的控件应包含在另一个组件中).
确保在执行任何自定义绘制之前调用super.paintComponent,这样就不会破坏绘制链
创建一个SINGLE 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属性…
标签:java,swing
来源: https://codeday.me/bug/20190929/1833254.html