清除我的 jpanel 后我无法绘图
Posted
技术标签:
【中文标题】清除我的 jpanel 后我无法绘图【英文标题】:I am not able to draw after clear my jpanel 【发布时间】:2022-01-20 01:13:49 【问题描述】:import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.border.BevelBorder;
public class Cliente extends JPanel
private JButton adelanteButton;
private JButton undoButton;
private JPanel panel1;
private JPanel panelDibujo;
private Rectangulo rectangulo = new Rectangulo();
Originator originator;
Caretaker caretaker;
public static void main(String[] args)
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Patron Memento");
Cliente cliente = new Cliente();
frame.setContentPane(cliente.panel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
@Override
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Memento m : caretaker.history)
System.out.println("forcitooooooo");
dibujar(m.getState(), Color.GREEN);
public Cliente()
caretaker = new Caretaker();
originator = new Originator();
createUIComponents();
undoButton.addActionListener(e ->
caretaker.anterior();
panelDibujo.repaint();
);
panelDibujo.setBackground(Color.WHITE);
panelDibujo.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
panelDibujo.addMouseListener(new MouseAdapter()
@Override
public void mousePressed(MouseEvent e)
MousePressedEvent(e);
@Override
public void mouseReleased(MouseEvent e)
MouseReleasedEvent(e);
);
private void createUIComponents()
private void MousePressedEvent(MouseEvent e)
rectangulo.setX1(e.getX());
rectangulo.setY1(e.getY());
private void MouseReleasedEvent(MouseEvent e)
rectangulo.setX2(e.getX());
rectangulo.setY2(e.getY());
originator.setState(rectangulo);
dibujar(rectangulo, Color.orange);
caretaker.addMemento(originator.CreateMemento());
rectangulo = new Rectangulo();
public void dibujar(Rectangulo r, Color c)
Graphics g = panelDibujo.getGraphics();
g.setColor(c);
g.drawRect(r.getX1(), r.getY1(), r.getX2() - r.getX1(), r.getY2() - r.getY1());
g.dispose();
您好,我正在通过使用 jpanel 并在内部绘制一些矩形来应用 memento 模式,现在我的代码在使用鼠标事件进行绘图方面工作正常,但问题是当我尝试撤消时。到目前为止,我的逻辑是清除 jpanel 并重做所有矩形减去最后一个。 但是在清除我的 jpanel 后不再绘制 :( 有人可以帮我修复它吗?谢谢
看守者.java
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Stack;
public class Caretaker
LinkedList<Memento> history;
int indice;
public Caretaker()
history = new LinkedList<>();
indice = 0;
void addMemento(Memento m)
if (history.size() == indice || history.isEmpty())
indice++;
history.add(m);
else
indice = history.size()-1;
history.subList(indice +1, history.size()).clear();
Memento anterior()
if (history.size() > 0)
indice--;
return history.removeLast();
JOptionPane.showMessageDialog(null, "No hay mas wey!");
return null;
Memento siguiente()
if (indice < history.size()+1)
indice++;
return history.get(indice+1);
JOptionPane.showMessageDialog(null, "No hay mas wey!");
return null;
public void redibujar(JPanel f)
Graphics g = f.getGraphics();
for (Memento m: history)
g.drawRect(m.getState().getX1(), m.getState().getY1(), m.getState().getX2() - m.getState().getX1(), m.getState().getY2() - m.getState().getY1());
g.dispose();
public void clear()
history.clear();
indice = 0;
Memento.java
public class Memento
Rectangulo state;
/*
Constructor, unica manera de mandar/crear/guardar los datos
*/
public Memento(Rectangulo state)
this.state = state;
public Memento()
state = new Rectangulo();
Rectangulo getState()
return state;
Originator.java
public class Originator
Rectangulo state;
public void setState(Rectangulo rectangulo)
this.state = rectangulo;
public Memento CreateMemento()
return new Memento(state);
public void setMemento(Memento m)
setState(m.getState());
Rectangulo.java
import java.awt.*;
public class Rectangulo
private int x1;
private int x2;
private int y1;
private int y2;
Rectangulo()
public Rectangulo(int x1, int x2, int y1, int y2)
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
public int getX1()
return x1;
public void setX1(int x1)
this.x1 = x1;
public int getX2()
return x2;
public void setX2(int x2)
this.x2 = x2;
public int getY1()
return y1;
public void setY1(int y1)
this.y1 = y1;
public int getY2()
return y2;
public void setY2(int y2)
this.y2 = y2;
public void draw(Graphics g)
g.setColor(Color.orange);
g.drawRect(this.getX1(), this.getY1(), this.getX2() - this.getX1(), this.getY2() - this.getY1());
【问题讨论】:
一个问题是这不是您在 Swing 中使用图形的方式。您不应该在组件上调用.getGraphics()
并使用该 Graphics 对象。而是使用传递给您的 paintComponent 方法的那个。
您想引出什么确切行为?
请注意,鉴于您当前的代码,我们都无法重现您的程序的不当行为,因为我们无法编译或运行它。考虑将其压缩为重现您的问题的最小可运行代码,minimal reproducible example。
我添加了运行它所需的所有代码。感谢您的时间和帮助。
不。由于 GUI 中未初始化的对象(例如 undoButton 等),您的代码会引发 NullPointerException
【参考方案1】:
再一次,您的绘图不正确。您正在尝试使用从未添加到 GUI 中的 JPanel、客户端进行渲染,并且您正在尝试使用从该未渲染组件中提取的 Graphics 对象,从而使由此获得的 Graphics 对象短暂且不稳定。
相反,在paintComponent 方法中进行所有绘制。如果需要,您可以使用 BufferedImage 并在paintComponent 中绘制它,特别是如果您想要具有显示不同颜色的对象的图像,或者您可以使用您的List(这里是LinkedList,但ArrayList 可以)并在paintComponent 中绘制。例如,一些简单的事情:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class Cliente2 extends JPanel
private static final int BI_WIDTH = 800;
private static final int BI_HEIGHT = 650;
private Rectangle drawingRect = null;
// private java.util.List<Rectangulo> rectangulos = new ArrayList<>();
List<Rectangulo2> rectangulos = new ArrayList<>();
private JButton clearBtn = new JButton("Clear");
public Cliente2()
setBackground(Color.WHITE);
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
clearBtn.addActionListener(e -> clear());
add(clearBtn);
private void clear()
rectangulos.clear();
repaint();
@Override
public Dimension getPreferredSize()
return new Dimension(BI_WIDTH, BI_HEIGHT);
@Override
protected void paintComponent(Graphics g)
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (drawingRect != null)
g2.setColor(Color.LIGHT_GRAY);
g2.draw(drawingRect);
for (Rectangulo2 rectangulo : rectangulos)
rectangulo.draw(g2);
private class MyMouse extends MouseAdapter
private Point p0;
@Override
public void mousePressed(MouseEvent e)
p0 = e.getPoint();
@Override
public void mouseDragged(MouseEvent e)
drawingRect = createDrawingRect(e);
repaint();
private Rectangle createDrawingRect(MouseEvent e)
Point p1 = e.getPoint();
int x = Math.min(p0.x, p1.x);
int y = Math.min(p0.y, p1.y);
int width = Math.abs(p0.x - p1.x);
int height = Math.abs(p0.y - p1.y);
return new Rectangle(x, y, width, height);
@Override
public void mouseReleased(MouseEvent e)
// lets create some random colors:
float hue = (float) Math.random();
float brightness = (float) Math.random();
Color color = Color.getHSBColor(hue, 1f, brightness);
Rectangulo2 rectangulo = new Rectangulo2(color, p0, e.getPoint());
rectangulos.add(rectangulo);
drawingRect = null;
repaint();
public static void main(String[] args)
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Patron Memento");
// Cliente cliente = new Cliente();
// frame.setContentPane(cliente.panel1);
frame.add(new Cliente2());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
class Rectangulo2
private static final Stroke STROKE = new BasicStroke(3f);
private Color color;
private Point p0, p1;
public Rectangulo2()
public Rectangulo2(Color color, Point p0, Point p1)
super();
this.color = color;
this.p0 = p0;
this.p1 = p1;
public Color getColor()
return color;
public Point getP0()
return p0;
public Point getP1()
return p1;
public void draw(Graphics g)
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(color);
int x = Math.min(p0.x, p1.x);
int y = Math.min(p0.y, p1.y);
int width = Math.abs(p0.x - p1.x);
int height = Math.abs(p0.y - p1.y);
g2.fillRect(x, y, width, height);
g2.setStroke(STROKE);
g2.setColor(Color.BLACK);
g2.drawRect(x, y, width, height);
g2.dispose();
【讨论】:
非常感谢,我是java新手,我从你的代码中学到了很多东西,一点点东西,使用你的代码我如何撤消最后一个矩形?以上是关于清除我的 jpanel 后我无法绘图的主要内容,如果未能解决你的问题,请参考以下文章