gpt4 book ai didi

java - 多次调用paintComponent()

转载 作者:行者123 更新时间:2023-12-01 06:54:31 27 4
gpt4 key购买 nike

我有这两个类(class):

public class Pencil extends JComponent implements MouseListener, MouseMotionListener{
Plansa plansa;
Graphics g;
public Pencil(Plansa newCanvas){
this.plansa = newCanvas;
this.plansa.setFlagShape(false);
}
@Override
public void mouseDragged(MouseEvent arg0) {
plansa.setMouseDragged(arg0);
this.plansa.setFlagShape(false);
plansa.paintComponent(plansa.getGraphics());
}

@Override
public void mouseClicked(MouseEvent e) {
}

@Override
public void mousePressed(MouseEvent arg0) {
plansa.setMousePressed(arg0);
}

@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
plansa.setMouseReleased(arg0);
this.plansa.setFlagShape(true);
plansa.paintComponent(plansa.getGraphics());

}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}

@Override
public void mouseMoved(MouseEvent e) {
}

}

还有这个:

public class Plansa extends JPanel{
Image image;
Pencil pencil;
//...
void init(){
this.setShape("freeLine");
this.setColor(Color.BLACK);
this.size=1;
this.type="round";
this.fill=false;
this.setBackground(Color.WHITE);
pencil = new Pencil(this);
addMouseListener(pencil);
addMouseMotionListener(pencil);
flagPaint = true;
flagShape = false;
}
public Plansa(){
this.setSize(800, 600);
init();
}

//...

@Override
public void paintComponent(Graphics g) {
g.setColor(currentColor);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(setBrush(size,type));
super.paintComponent(g);
switch(shape){
default: break;
case "freeLine":{
g.drawLine(xDragged, yDragged, xCurrent, yCurrent);
break;
}
case "rectangle":{
if(flagShape == true){
g.drawRect(xPressed, yPressed, Math.max(xCurrent-xPressed,xPressed-xCurrent), Math.max(yCurrent-yPressed,yPressed-yCurrent));
if(fill == true) g.fillRect(xPressed, yPressed, Math.max(xCurrent-xPressed,xPressed-xCurrent), Math.max(yCurrent-yPressed,yPressed-yCurrent));
}
break;
}
case "circle":{
if(flagShape == true){
int radius = (int)Math.sqrt(Math.max(xCurrent-xPressed,xPressed-xCurrent)*Math.max(xCurrent-xPressed,xPressed-xCurrent)+Math.max(yCurrent-yPressed,yPressed-yCurrent)*Math.max(yCurrent-yPressed,yPressed-yCurrent));
g.drawOval(xPressed, yPressed, radius, radius);
if(fill == true) g.fillOval(xPressed, yPressed, radius, radius);
}
break;
}
case "oval":{
if(flagShape == true){
g.drawOval(xPressed, yPressed, Math.max(xCurrent-xPressed,xPressed-xCurrent), Math.max(yCurrent-yPressed,yPressed-yCurrent));
if(fill == true) g.fillOval(xPressed, yPressed, Math.max(xCurrent-xPressed,xPressed-xCurrent), Math.max(yCurrent-yPressed,yPressed-yCurrent));
}
break;
}
case "line":{
if(flagShape == true){
g.drawLine(xPressed, yPressed, xCurrent, yCurrent);
}
break;
}
}

}

//...
}

我的问题是,每次我调用paintComponent()方法时,JPanel都会被清除,唯一剩下的项目就是我刚刚绘制的项目。有什么办法可以避免这种情况吗?

最佳答案

仔细检查代码后,看来您正在尝试使用 Component 作为“画家”,这有点像使用跑车作为卡丁车,很多额外的收获很少。

相反,您应该为自己定义一个接口(interface),提供您想要绘制/绘制的内容的基本要求,然后定义实现该功能的具体类实现。

然后,您将维护一个包含某种可绘制的所有绘图的列表

虽然很简单,但下面的示例提供了一个可以增强的起点,允许选择绘图、重新排序和删除(如果您需要的话)。

这本质上与 Doorknob (+1) 提出的概念相同

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestDraw {

public static void main(String[] args) {
new TestDraw();
}

public TestDraw() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new Pencil());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class Pencil extends JPanel implements MouseListener, MouseMotionListener {

private List<Drawable> drawables;
private Drawable activeDrawable;

private Point clickPoint;

public Pencil() {
drawables = new ArrayList<>(5);
addMouseListener(this);
addMouseMotionListener(this);
}

@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Drawable drawable : drawables) {
drawable.paint(g2d);
}
g2d.dispose();
}

@Override
public void mouseDragged(MouseEvent e) {
if (activeDrawable != null) {
Point p = e.getPoint();
Rectangle bounds = activeDrawable.getBounds();

int x = bounds.x;
int y = bounds.y;
int width = p.x - clickPoint.x;
int height = p.y - clickPoint.y;
if (width < 0) {
width *= -1;
x = p.x;
}
if (height < 0) {
height *= -1;
y = p.y;
}
bounds = new Rectangle(x, y, width, height);
System.out.println(bounds);
activeDrawable.setBounds(bounds);
repaint();
}
}

@Override
public void mouseClicked(MouseEvent e) {
}

protected Drawable createActiveShape(MouseEvent e) {

System.out.println("Anchor = " + e.getPoint());
Drawable drawable = new FreeLine(e.getPoint());
drawable.setLocation(e.getPoint());
return drawable;

}

@Override
public void mousePressed(MouseEvent e) {
// You could also check to see if the clicked on a drawable...
clickPoint = e.getPoint();
activeDrawable = createActiveShape(e);
drawables.add(activeDrawable);
repaint();
}

@Override
public void mouseReleased(MouseEvent e) {
if (activeDrawable != null) {
Rectangle bounds = activeDrawable.getBounds();
if (bounds.width == 0 || bounds.height == 0) {
drawables.remove(activeDrawable);
}
}
clickPoint = null;
activeDrawable = null;
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}

@Override
public void mouseMoved(MouseEvent e) {
}
}

public interface Drawable {

public void setLocation(Point p);

public void setSize(Dimension dim);

public void setBounds(Rectangle bounds);

public Rectangle getBounds();

public void paint(Graphics2D g2d);
}

public abstract class AbstractDrawable implements Drawable {

private Rectangle bounds;

public AbstractDrawable() {
bounds = new Rectangle();
}

@Override
public void setLocation(Point p) {
bounds.setLocation(p);
}

@Override
public void setBounds(Rectangle bounds) {
this.bounds = bounds;
}

@Override
public void setSize(Dimension dim) {
bounds.setSize(dim);
}

@Override
public Rectangle getBounds() {
return bounds;
}
}

public class FreeLine extends AbstractDrawable {

private Point anchor;

public FreeLine(Point anchor) {
this.anchor = anchor;
}

@Override
public void paint(Graphics2D g2d) {
Rectangle bounds = getBounds();
Point p1 = new Point(anchor);
Point p2 = new Point(bounds.getLocation());
if (p1.x > p2.x) {
p2.x = p1.x - bounds.width;
} else {
p2.x = p1.x + bounds.width;
}
if (p1.y > p2.y) {
p2.y = p1.y - bounds.height;
} else {
p2.y = p1.y + bounds.height;
}
g2d.draw(new Line2D.Float(p1, p2));
}
}

关于java - 多次调用paintComponent(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15890704/

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