java窗体线条切换消失_java – 在对象之间切换时如何摆脱矩形内的圆

我有一个组合框,我可以选择绘制矩形,圆形或手绘.

如果我选择绘制一个圆圈,它会完美地绘制它.如果我然后切换到绘制一个矩形,它会在矩形内部绘制一个圆圈.如果我首先选择绘制矩形然后再绘制圆圈,也会发生同样的情况. (见下图)

我的问题是:

>如何在没有圆形出现在矩形内部的情况下切换圆形和矩形之间切换?

>当我拖动鼠标时,如何显示矩形/圆圈.我的意思是,在我发布鼠标点击之前,线条是如何显示的?

>为什么不用空手画?

这是我的测试类:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值