【问题标题】:I am not able to draw after clear my jpanel清除我的 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

标签: java swing jpanel drawing


【解决方案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新手,我从你的代码中学到了很多东西,一点点东西,使用你的代码我如何撤消最后一个矩形?
猜你喜欢
  • 1970-01-01
  • 2016-04-20
  • 2011-10-17
  • 2017-08-31
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
相关资源
最近更新 更多