Ok mon problème est simple: je fais l'application de la peinture, et je voudrais offrir une sorte de fonctionnalité « défaire ». J'ai lu sur les gestionnaires d'annulation et ainsi de suite, mais cette approche semble être difficile à comprendre pour moi alors j'ai décidé de concevoir le mien. Mon idée est simple: puisque je dessine sur JPanel je vais juste sauvegarder son contenu actuel juste avant que toute opération de dessin soit faite. Et le bouton Annuler va juste restaurer le précédent.Saving JPanel comme l'image (non sous forme de fichier, mais comme une variable)
Le problème est: Je suis incapable de « restaurer » l'image enregistrée et placez-le sur le JPanel. Je suis tamponné depuis que j'ai déjà mis en place "sauvegarder" l'image actuelle sur disque dur et aussi "ouvrir" l'image arbitraire du disque dur. Les deux fonctionnent parfaitement bien.
Malheureusement essayant exactement de la même approche pour mon système « défaire » ne fonctionne pas.
Regardez le code: (pour simplifier, i manuellement "Enregistrer l'image actuelle -> à des fins de test)
public class PictureEdit { //class for saving the current JPanel drawing for undo
public BufferedImage saveBI;
public Graphics2D saveG2D;
}
public void actionPerformed(ActionEvent e) { //action for "UNDO" button, not working
//drawingField - instance of JPanel
//pe - instance of PictureEdit class
drawingField.setBufferedImg(drawingField.pe.saveBI);
drawingField.updateArea(drawingField.getBufferedImg());
}
public void actionPerformed(ActionEvent e) { //action for manual "save" (for undo)
drawingField.pe.saveBI=drawingField.getBufferedImg();
drawingField.pe.saveG2D=(Graphics2D)drawingField.getBufferedImg().getGraphics();
}
maintenant l'exemple de ma solution de travail, mais en rapport avec les fichiers de Woking sur le disque dur:
public void actionPerformed(ActionEvent e){ //Opening file from harddrive - works fine
JFileChooser jfc = new JFileChooser();
int selection = jfc.showOpenDialog(PaintUndo.this);
if (selection == JFileChooser.APPROVE_OPTION){
try {
drawingField.setBufferedImg(ImageIO.read(jfc.getSelectedFile()));
drawingField.updateArea(drawingField.getBufferedImg());
} catch (IOException ex) {
Logger.getLogger(PaintUndo.class.getName()).log(Level.SEVERE, null, ex);
JOptionPane.showMessageDialog(PaintUndo.this, "Could not open file");
}
}
}
public void actionPerformed(ActionEvent e) { //Saving to harddrive - works fine
int n = JOptionPane.showConfirmDialog(PaintUndo.this, "Are you sure you want to save?", "Saving image...", JOptionPane.OK_CANCEL_OPTION);
if (n == JOptionPane.YES_OPTION){
JFileChooser jfc = new JFileChooser();
int nn = jfc.showSaveDialog(PaintUndo.this);
if (nn == JFileChooser.APPROVE_OPTION){
File saveFile = new File(jfc.getSelectedFile()+".bmp");
try {
ImageIO.write(drawingField.getBufferedImg(), "bmp", saveFile);
} catch (IOException ex) {
Logger.getLogger(PaintUndo.class.getName()).log(Level.SEVERE, null, ex);
JOptionPane.showMessageDialog(PaintUndo.this, "Error while saving file");
}
}
}
}
Juste au cas où quelqu'un est curieux: updateArea
fonction (membre de la classe JPanel étendue qui représente mentionné drawingField
):
public void updateArea(BufferedImage img){ //it is just resizing the current picture (if necessary) and then assigns the new Graphics.
area.height=img.getHeight();
area.width=img.getWidth();
this.setPreferredSize(area);
g2d = (Graphics2D)this.getGraphics();
}
Fondamentalement, la procédure est exactement la même, et travailler avec des fichiers est ok alors je ne peux pas sauvegarder et de restaurer l'image quand je suis sur les variables d'exploitation ... Qu'est-ce qui pourrait être mal? des idées? Quand j'utilise Undo/boutons UndoSave, absolument rien ne change dans mes JPanel (drawingField
)
Toute aide appréciée
fonctionnalité Annuler dépend de la façon dont vous dessinez. Dessinez-vous des formes simples? Ou dessiner des pixels arbitraires? – Mohayemin
1) Publier une [SSCCE] (http://sscce.org) au lieu de l'affichage des morceaux sur lesquels nous devons faire des suppositions sauvages 2) Alors que votre approche est originale, il sera tout à fait mémoire coûteuse et sur chaque action , vous devrez repeindre un nouveau BufferedImage qui n'est pas si bon marché. –
Eh bien oui, je dessine des formes simples comme point, ligne, rectangle, ovale. En dehors de cela, je suis en train de tourner/retourner l'image. Concernant SSCCE: http://pastebin.com/0QY4uwHG (j'ai minimisé le code au strict minimum pour le rendre exécutable -> dessin exclu des ovales/rectangles et retournement/rotation). En ce qui concerne mon approche, eh bien, je ne pense pas que «UndoManager» est «moins cher» en termes de mémoire - mais je me trompe peut-être ici. Néanmoins, essayer de comprendre le non-gou- verneur me semble un peu douloureux, alors j'ai décidé d'y aller seul. UndoManager est-il si bon et optimisé pour qu'il soit plus rapide que la mienne? –