gpt4 book ai didi

java - 无法使 swing 撤消/重做系统适用于简单的绘画程序。

转载 作者:行者123 更新时间:2023-11-30 03:58:55 25 4
gpt4 key购买 nike

我遵循了许多文章中的步骤,但撤消系统的行为不符合预期。首先,撤消按钮会正确返回到第一次编辑,但不能超出第一次编辑。另外,当我单击撤消然后重新编辑时,它会返回到上次编辑。如果您执行代码并查看自己,那就更好了。

另一个问题,当我试图找出解决方案时,我读到将图像保存在数组中是内存密集型的,即使对于这个简单的绘画类也是如此,还有什么替代方案吗?保存图像的图形?

import java.awt.*;import java.awt.image.BufferedImage;import java.awt.event.*;import java.util.ArrayList;import javax.swing.*;import javax.swing.event.*;import javax.swing.undo.*;
public class Painter extends JFrame{
//attributes//
Painter.Canvas canvas;
JPanel controlPanel;
JButton undoButton;
JButton redoButton;
PainterHandler handler;
Container container;
//undo system elements//
UndoManager undoManager; // history list
UndoableEditSupport undoSupport; // event support

//constructor//
public Painter()
{
super("Painter-test");
controlPanel = new JPanel();
undoButton = new JButton("undo");
redoButton = new JButton("redo");
handler = new Painter.PainterHandler();
container = getContentPane();
canvas = new Painter.Canvas();

this.organizer();
}// end constructor

public void organizer()
{
controlPanel.setLayout(null);
controlPanel.setPreferredSize(new Dimension(120,350));
controlPanel.setBackground(null);

//add undo listeners to undo/redo buttons.
undoButton.addActionListener( new AbstractAction()
{
public void actionPerformed( ActionEvent evt )
{ undoManager.undo(); refreshCanvas(); refreshUndoRedo();}
});
redoButton.addActionListener(new AbstractAction()
{
public void actionPerformed(ActionEvent evt )
{ undoManager.redo(); refreshCanvas(); refreshUndoRedo(); }
});

// initilize the undo/redo system.
undoManager= new UndoManager();//history list
// event support, instance.
undoSupport = new UndoableEditSupport();
//add undoable edit listener to the support instance.
undoSupport.addUndoableEditListener(new UndoableEditListener()
{
public void undoableEditHappened (UndoableEditEvent event)
{
UndoableEdit edit = event.getEdit();
undoManager.addEdit( edit );
refreshUndoRedo();
}
});
refreshUndoRedo();

canvas.setPreferredSize(new Dimension(600,400));
//place buttons on panel.
undoButton.setBounds(10, 160, 80, 20);
redoButton.setBounds(10, 181, 80, 20);

//add components to panel.
controlPanel.add(undoButton);
controlPanel.add(redoButton);

//add panels to window.
container.add(canvas,BorderLayout.WEST);
container.add(controlPanel, BorderLayout.EAST);
}//end organizerTab3()

public void refreshCanvas() { canvas.repaint(); }

//refresh undo, redo buttons.
public void refreshUndoRedo()
{
// refresh undo
undoButton.setEnabled( undoManager.canUndo() );
// refresh redo
redoButton.setEnabled( undoManager.canRedo() );
}


//INNER CLASSES
ArrayList<BufferedImage> imagesArray = new ArrayList<BufferedImage>();
BufferedImage imageCopy;
Graphics graphics;
BufferedImage image;
int index;
private class Canvas extends JPanel
{
public Canvas()
{
//Panel properties
setSize(600,400);
setBackground(new Color(84,84,118));

image = new BufferedImage(getWidth(), getHeight(),BufferedImage.TYPE_INT_ARGB);
//add Listeners.
addMouseMotionListener(handler);
addMouseListener(handler);
}//end constructor

@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
}//end inner class PaintPanel


private class PainterHandler extends MouseAdapter
{
@Override
public void mouseDragged(MouseEvent event)
{
if(event.getComponent().equals(canvas))
{
if (image != null)
{
// Paint into the image
graphics = image.getGraphics();
graphics.setColor(new Color(249,30,138));
graphics.fillOval(event.getX(), event.getY(), 20, 20);
imageCopy = new BufferedImage(canvas.getWidth(),canvas.getHeight(),BufferedImage.TYPE_INT_ARGB);
imageCopy.getGraphics().drawImage(image, 0, 0, null);
canvas.repaint();
}
}
}//end mouseDragged(MouseEvent event)

@Override
public void mouseReleased(MouseEvent event)
{
if(event.getComponent().equals(canvas))
{
//UNDO SYSTEM START//
//add image to the array.
imagesArray.add(imageCopy);
// get image's index.
index = imagesArray.indexOf(imageCopy);
//create AddEdit instance of type UndoableEdit.
UndoableEdit edit = new Painter.AddEdit(imagesArray, imageCopy,index);
// notify the listeners
undoSupport.postEdit( edit );
//UNDO SYSTEM END//
}
}
}//end MouseHandler class

private class AddEdit extends AbstractUndoableEdit
{
private ArrayList<BufferedImage> undoableImagesArray;
private BufferedImage undoableImage;
int undoableIndex;
public AddEdit(ArrayList<BufferedImage> v, BufferedImage img, int i)
{
undoableImagesArray = v;
undoableImage = img;
undoableIndex = i;
}
public void undo() throws CannotUndoException
{
undoableImagesArray.remove(undoableImage);
if(!undoableImagesArray.isEmpty())
image = (BufferedImage)undoableImagesArray.get(undoableImagesArray.size()-1);
canvas.repaint();
}

public void redo() throws CannotRedoException
{
undoableImagesArray.add(undoableImage);
image = (BufferedImage)undoableImagesArray.get(undoableImagesArray.size()-1);
canvas.repaint();
}

public boolean canUndo() { return true; }
public boolean canRedo() { return true; }
}//end class AddEdit

public static void main(String[] s)
{
Painter p = new Painter();
p.setSize(800, 500);
p.setVisible(true);
p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}//END CLASS Painter

最佳答案

您不使用 undoableIndex。事实上,您不应该从数组中删除图像,而应该移动指针。

如果列表不为空且指针 >0,canUndo() 应该返回 true

如果指针!=列表的size(),则canRedo()应该返回true

关于java - 无法使 swing 撤消/重做系统适用于简单的绘画程序。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22402552/

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