Vector // Serializable // Hiiiiilfe ;)

hey :smiley:

schreibe ein programm, was einfache formen zeichnen kann (ellipse,
rechteck, strich), diese formen aber als ganzes auch speichern und
laden können muss. soweit, so gut.
frage is nur, wie ich den Vector in der klasse flaeche Serializable
mache. hab versucht, eine eigene Serializable klasse myVector zu
schreiben die die Klasse Vector extendet. bekomm aber trotzdem noch
folgende exception:

java.io.NotSerializableException: java.util.Vector$1

quelltext folgt (sry wenns bissl viel is, weiss nich obs hier
erwünscht is, quelltexte auf ner nopaste-seite zu speichern):

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.io.*;

/**
* @author Freddy Seubert
* @date 7.12.06
* @version 1.0
*
*/

public class MouseTest extends JPanel{

/**
* default serialversionuid for saving and loading
*/
private static final long serialVersionUID = 1L;
MenuBar menubar = new MenuBar(this);

Flaeche fl;

/**
* main method
* @param args not used
*/

public static void main(String[] args) {
JFrame frame = new JFrame(„Maus-Test“);
MouseTest myMouseTest = new MouseTest();
frame.getContentPane().add(myMouseTest);

frame.setJMenuBar(myMouseTest.menubar);

frame.setSize(400, 300);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
} );
}

/**
* constructor of type MouseTest
*/

public MouseTest(){
setLayout(new BorderLayout());
fl = new Flaeche();
add(fl, BorderLayout.CENTER);
JPanel p = new JPanel();
JRadioButton oval = new JRadioButton(„Oval“, true);
JRadioButton rechteck = new JRadioButton(„Rechteck“);
JRadioButton linie = new JRadioButton(„Linie“);
ButtonGroup formen = new ButtonGroup();
formen.add(oval);
formen.add(rechteck);
formen.add(linie);
p.add(oval);
p.add(rechteck);
p.add(linie);
add(p, BorderLayout.SOUTH);
oval.addActionListener(fl);
rechteck.addActionListener(fl);
linie.addActionListener(fl);
}

/**
* opens a previously saved file for further drawing
*/

public void openFile(){
//System.out.println(„testestetstetsttstststst“); funktioniert
JFileChooser chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(false);
int option = chooser.showOpenDialog(null);
if(option == JFileChooser.APPROVE_OPTION){
File myFile = chooser.getSelectedFile();
try{
FileInputStream istream = new FileInputStream(myFile);
ObjectInputStream input = new ObjectInputStream
(istream);
System.out.println(„loaded“);
fl = (Flaeche) input.readObject();
this.repaint();
}catch(Exception e){
System.err.println(e.toString());
}
}
}

/**
* saves the drawings to a file for further working
*/

public void saveFile(){
JFileChooser chooser = new JFileChooser();

int option = chooser.showSaveDialog(null);
if(option == JFileChooser.APPROVE_OPTION){
File myFile = chooser.getSelectedFile();
try{
FileOutputStream ostream = new FileOutputStream
(myFile);
ObjectOutputStream output = new ObjectOutputStream
(ostream);
output.writeObject(fl);
System.out.println(„saved“);
}catch(Exception e){
System.err.println(e.toString());
}
}
}

/**
* clears the background on which you are painting
*/

public void clear(){
System.out.println(„clear“);
fl.clear();
this.repaint();
}
}

class MenuBar extends JMenuBar implements ActionListener{

/**
* default serialversionuid for saving and loading
*/
private static final long serialVersionUID = 1L;
MouseTest parent;

/**
* @param parent the „parent“ MouseTest from where the MenuBar is
called
*/

public MenuBar(MouseTest parent){
super();
this.parent = parent;
JMenu menu1 = new JMenu(„Datei“);
JMenuItem neu = new JMenuItem(„Neu“);
JMenuItem open = new JMenuItem(„Öffnen…“);
JMenuItem save = new JMenuItem(„Speichern…“);
JMenuItem close = new JMenuItem(„Beenden“);

neu.addActionListener(this);
open.addActionListener(this);
save.addActionListener(this);
close.addActionListener(this);

menu1.add(neu);
menu1.add(open);
menu1.add(save);
menu1.addSeparator();
menu1.add(close);

this.add(menu1);
}

public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if(cmd.equals(„Neu“)){
parent.clear();
}else if(cmd.equals(„Öffnen…“)){
parent.openFile();
}else if(cmd.equals(„Speichern…“)){
parent.saveFile();
}else if(cmd.equals(„Beenden“)){
System.exit(0);
}
}
}

class Flaeche extends JPanel implements ActionListener,
java.io.Serializable{
/**
* serialversionuid for saving and loading
*/

private static final long serialVersionUID = 1L;
private MyVector v;
private int formwahl;
private Form form;
Enumeration enumer;

/**
* constructor (Flaeche)
*/

public Flaeche() {
formwahl = 1;
v = new MyVector();
form = new Form(0, 0, 0, 0, 0);
setBackground(Color.white);
addMouseListener(new MausTasten());
addMouseMotionListener(new MausBewegungen());
}

/**
*
*/

public void clear(){
v = new MyVector();
form = new Form(0, 0, 0, 0, 0);
enumer = null;
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
Form f;

enumer = v.elements();
while (enumer.hasMoreElements()) {
f = (Form)enumer.nextElement();
if (f.kz == 1)
g.drawOval(f.x, f.y, f.width, f.height);
else if (f.kz == 2)
g.drawRect(f.x, f.y, f.width, f.height);
else if (f.kz == 3)
g.drawLine(f.x, f.y, (f.x + f.width), (f.y +
f.height));
}
if (form.width > 0 && form.height > 0)
if (form.kz == 1)
g.drawOval(form.x, form.y, form.width, form.height);
else if (form.kz == 2)
g.drawRect(form.x, form.y, form.width, form.height);
else if (form.kz == 3)
g.drawLine(form.x, form.y, (form.x + form.width),
(form.y + form.height));
}

public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.equals(„Oval“))
formwahl = 1;
else if (cmd.equals(„Rechteck“))
formwahl = 2;
else if (cmd.equals(„Linie“))
formwahl = 3;
}

class MausTasten extends MouseAdapter {
public void mousePressed(MouseEvent e) {
form = new Form(formwahl, e.getX(), e.getY(), 0, 0);
}

public void mouseReleased(MouseEvent e) {
if (form.width > 0 && form.height > 0)
v.addElement(form);
}
}

class MausBewegungen extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if (x > form.x && y > form.y) {
form.width = x - form.x;
form.height = y - form.y;
}
repaint();
}
}
}

class Form implements java.io.Serializable{
/**
* bla standard serialVersionUID for saving and loading
*/
private static final long serialVersionUID = 1L;

public int kz, x, y, width, height;

/**
* @param kz
* @param x
* @param y
* @param width
* @param height
*/

public Form(int kz, int x, int y, int width, int height){
this.kz = kz;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}

class MyVector extends Vector implements java.io.Serializable{

/**
* bla for saving and loading
*/

private static final long serialVersionUID = 1L;

MyVector(){
super();
}

}

Re: Vector // Serializable // Hiiiiilfe :wink:
Hallo.

bekomm aber trotzdem
noch folgende exception:

java.io.NotSerializableException: java.util.Vector$1

XP+SP2, JDK 1.4: Programm lässt sich fehlerlos kompilieren und ausführen. Friert beim Arbeiten aber ein… Die Fehlermeldung taucht auch nicht auf :frowning:
Vielleicht kann das hier dennoch nützlich sein: http://www.java-tips.org/java-se-tips/java.io/how-to…

Und Quellcode wird übrigens in pre-Tags angegeben :wink:

mfg M.L.

XP+SP2, JDK 1.4: Programm lässt sich fehlerlos kompilieren und
ausführen. Friert beim Arbeiten aber ein… Die Fehlermeldung
taucht auch nicht auf :frowning:

jop die exception taucht auch nich beim kompilieren auf, sondern dann
wenn du versuchst irgendwelche gemalten striche zu SPEICHERN.

liebe grüße, freddy

jop die exception taucht auch nich beim kompilieren auf,
sondern dann
wenn du versuchst irgendwelche gemalten striche zu SPEICHERN.

Ich glaube das Problem ist, dass du das ganze Panel apspeichern willst.
Darunter sind offenbar Teile, die eben nicht serialisierbar sind.
Mit folgenden Aenderungen klappt speichern und laden:

public class MouseTest extends JPanel {
...
 public void openFile() {
...
 System.out.println("loaded");
 Form form = (Form) input.readObject();
 fl.setForm(form);
...
 }

 public void saveFile() {
...
 output.writeObject(fl.getForm());
...
 }
...
}
...
class Flaeche extends JPanel 
 implements ActionListener, java.io.Serializable {
...
 public Form getForm() {
 return form;
 }

 public void setForm(Form form) {
 this.form = form;
 }
...
}

Ob dir das dann schon in letzter Konsequenz hilft, kann
ich nicht sagen.

Gruss
Patrick

Ich glaube das Problem ist, dass du das ganze Panel
apspeichern willst.
Darunter sind offenbar Teile, die eben nicht serialisierbar
sind.

jop deshalb ja die exception. problem is einfach dass ich ja nich nur
die letzt gemalte ->form abspeichern will, sondern den vector in dem
alle gespeichert sind. und der is nich serialisierbar, was ich nich
versteh, da darin ja nur form-elemente liegen, welche ja
serialisierbar sind (was man auch daran sieht, dass es mit deinen
änderungen (also NUR form speichern) funktioniert).

Ob dir das dann schon in letzter Konsequenz hilft, kann
ich nicht sagen.

eher nicht, da ich ne möglichkeit suche, diesen vector zu speichern.

ha!! alles klar. hab deine methoden dahingehend umgeschrieben, dass
sie nicht die form sondern den vector bearbeiten.

 public MyVector getVector() {
 return v;
 }

 public void setVector(MyVector v) {
 this.v = v;
 }

und das dementsprechend eben auch in der save und load methode
geändert und siehe da, es funktioniert :smile:)))

versteh aber trotzdem nicht, warum es auf diesem weg geht aber er das
Flaeche extends JPanel nicht als Objekt speichern kann oO is das
allgemein nich möglich? wär ja mal schwachsinn

aber soweit schonmal dickes dankeschön :smiley: !!!

grüße freddy

er das Flaeche extends JPanel nicht als Objekt speichern kann oO is
das allgemein nich möglich? wär ja mal schwachsinn

Ja, nee, JPanel implementiert Serializable. Das habe ich uebersehen.
Dann weiss ich auch nicht was da gehakt hat. Aber wenn es jetzt
funktioniert…

Gruss
Patrick

Serializable: Korrektur mit Erklärung :wink:
Hallo Freddy.

schreibe ein programm, was einfache formen zeichnen kann,
diese formen aber als ganzes auch speichern und laden können muss.

frage is nur, wie ich den Vector in der klasse flaeche
Serializable mache.

Gar nicht, denn die Vector-Klasse ist bereits serialisierbar,
deshalb ist Deine MyVector-Klasse schlichtweg überflüssig,
siehe unten …

java.io.NotSerializableException: java.util.Vector$1

Die Enumeration, die Du als extra Attribut in der Klasse Flaeche eingeführt hast, ist nicht serialisierbar gewesen, nicht der
Vector. Da diese Enumeration aber aus dem Vector abgeleitet
wird, ist sie als extra Attribut überflüssig.

Hier Dein korrigierter Quelltext (ich habe ihn möglichst
wenig verändert und nur die Bugfixes gemacht, obwohl ich
einiges daran anders machen würde … ):

import java.awt.\*;
import java.awt.event.\*;
import javax.swing.\*;
import java.util.\*;
import java.io.\*;

/\*\*
 \* @author Freddy Seubert: initial version
 \* @author Andreas Brand: bugfixes for GUI serialization and deserialization
 \* 
 \* @date 8.12.06
 \* @version 1.1
 \*/
public class MouseTest extends JPanel{
 private static final long serialVersionUID = 1L;
 MenuBar menubar = new MenuBar(this);

 Flaeche fl;

 /\*\*
 \* main method
 \* @param args not used
 \*/
 public static void main(String[] args) {
 JFrame frame = new JFrame("Maus-Test");
 MouseTest myMouseTest = new MouseTest();
 frame.getContentPane().add(myMouseTest);

 frame.setJMenuBar(myMouseTest.menubar);

 frame.setSize(400, 300);
 frame.setVisible(true);
 frame.addWindowListener(new WindowAdapter() {
 public void windowClosing(WindowEvent e) {
 System.exit(0);
 }
 } );
 }

 /\*\*
 \* constructor of type MouseTest
 \*/

 public MouseTest(){
 setLayout(new BorderLayout());
 fl = new Flaeche();
 add(fl, BorderLayout.CENTER);
 JPanel p = new JPanel();
 JRadioButton oval = new JRadioButton("Oval", true);
 JRadioButton rechteck = new JRadioButton("Rechteck");
 JRadioButton linie = new JRadioButton("Linie");
 ButtonGroup formen = new ButtonGroup();
 formen.add(oval);
 formen.add(rechteck);
 formen.add(linie);
 p.add(oval);
 p.add(rechteck);
 p.add(linie);
 add(p, BorderLayout.SOUTH);
 oval.addActionListener(fl);
 rechteck.addActionListener(fl);
 linie.addActionListener(fl);
 }

 /\*\*
 \* opens a previously saved file for further drawing
 \*/
 public void openFile(){
 JFileChooser chooser = new JFileChooser();
 chooser.setMultiSelectionEnabled(false);
 int option = chooser.showOpenDialog(null);
 if(option == JFileChooser.APPROVE\_OPTION){
 File myFile = chooser.getSelectedFile();
 try{
 FileInputStream istream = new FileInputStream(myFile);
 ObjectInputStream input = new ObjectInputStream(istream);

 System.out.println("loaded");

 ///////////////////////////////////////////
 // BUGFIX: das alte fl muss vorher aus
 // dem GUI entfernt werden, um dann 
 // das neu erstellte hinzufügen zu können.
 // Ansonsten arbeitet das GUI immer mit der
 // alten fl-Referenz weiter, wie das Debugging
 // ergibt.
 remove(fl);
 fl = (Flaeche)input.readObject();
 add(fl, BorderLayout.CENTER);
 //////////////////////////////////////////

 this.repaint();
 }catch(Exception e){
 System.err.println(e.toString());
 }
 }
 }

 /\*\*
 \* saves the drawings to a file for further working
 \*/

 public void saveFile(){
 JFileChooser chooser = new JFileChooser();

 int option = chooser.showSaveDialog(null);
 if(option == JFileChooser.APPROVE\_OPTION){
 File myFile = chooser.getSelectedFile();
 try{
 FileOutputStream ostream = new FileOutputStream
 (myFile);
 ObjectOutputStream output = new ObjectOutputStream
 (ostream);
 output.writeObject(fl);
 System.out.println("saved");
 }catch(Exception e){
 System.err.println(e.toString());
 }
 }
 }

 /\*\*
 \* clears the background on which you are painting
 \*/

 public void clear(){
 System.out.println("clear");
 fl.clear();
 this.repaint();
 }
}

class MenuBar extends JMenuBar implements ActionListener{
 private static final long serialVersionUID = 1L;
 MouseTest parent;

 /\*\*
 \* @param parent the "parent" MouseTest from where the MenuBar is
called
 \*/

 public MenuBar(MouseTest parent){
 super();
 this.parent = parent;
 JMenu menu1 = new JMenu("Datei");
 JMenuItem neu = new JMenuItem("Neu");
 JMenuItem open = new JMenuItem("Öffnen...");
 JMenuItem save = new JMenuItem("Speichern...");
 JMenuItem close = new JMenuItem("Beenden");

 neu.addActionListener(this);
 open.addActionListener(this);
 save.addActionListener(this);
 close.addActionListener(this);

 menu1.add(neu);
 menu1.add(open);
 menu1.add(save);
 menu1.addSeparator();
 menu1.add(close);

 this.add(menu1);
 }

 public void actionPerformed(ActionEvent e) {
 String cmd = e.getActionCommand();
 if(cmd.equals("Neu")){
 parent.clear();
 }else if(cmd.equals("Öffnen...")){
 parent.openFile();
 }else if(cmd.equals("Speichern...")){
 parent.saveFile();
 }else if(cmd.equals("Beenden")){
 System.exit(0);
 }
 }
}

class Flaeche extends JPanel implements ActionListener, java.io.Serializable{
 private static final long serialVersionUID = 1L;
 private Vector v;
 private int formwahl;
 private Form form;

 /\*\*
 \* constructor (Flaeche)
 \*/
 public Flaeche() {
 formwahl = 1;
 v = new Vector();
 form = new Form(0, 0, 0, 0, 0);
 setBackground(Color.white);
 addMouseListener(new MausTasten());
 addMouseMotionListener(new MausBewegungen());
 }

 /\*\*
 \*
 \*/

 public void clear(){
 v = new Vector();
 form = new Form(0, 0, 0, 0, 0);
 }

 public void paintComponent(Graphics g) {
 super.paintComponent(g);
 Form f;

 Enumeration enumer = v.elements();
 while (enumer.hasMoreElements()) {
 f = (Form)enumer.nextElement();
 if (f.kz == 1)
 g.drawOval(f.x, f.y, f.width, f.height);
 else if (f.kz == 2)
 g.drawRect(f.x, f.y, f.width, f.height);
 else if (f.kz == 3)
 g.drawLine(f.x, f.y, (f.x + f.width), (f.y +
 f.height));
 }
 if (form.width \> 0 && form.height \> 0)
 if (form.kz == 1)
 g.drawOval(form.x, form.y, form.width, form.height);
 else if (form.kz == 2)
 g.drawRect(form.x, form.y, form.width, form.height);
 else if (form.kz == 3)
 g.drawLine(form.x, form.y, (form.x + form.width),
 (form.y + form.height));
 }

 public void actionPerformed(ActionEvent e) {
 String cmd = e.getActionCommand();
 if (cmd.equals("Oval"))
 formwahl = 1;
 else if (cmd.equals("Rechteck"))
 formwahl = 2;
 else if (cmd.equals("Linie"))
 formwahl = 3;
 }

 class MausTasten extends MouseAdapter {
 public void mousePressed(MouseEvent e) {
 form = new Form(formwahl, e.getX(), e.getY(), 0, 0);
 }

 public void mouseReleased(MouseEvent e) {
 if (form.width \> 0 && form.height \> 0)
 v.addElement(form);
 }
 }

 class MausBewegungen extends MouseMotionAdapter {
 public void mouseDragged(MouseEvent e) {
 int x = e.getX();
 int y = e.getY();
 if (x \> form.x && y \> form.y) {
 form.width = x - form.x;
 form.height = y - form.y;
 }
 repaint();
 }
 }
}

class Form implements java.io.Serializable{
 /\*\*
 \* bla standard serialVersionUID for saving and loading
 \*/
 private static final long serialVersionUID = 1L;

 public int kz, x, y, width, height;

 /\*\*
 \* @param kz
 \* @param x
 \* @param y
 \* @param width
 \* @param height
 \*/

 public Form(int kz, int x, int y, int width, int height){
 this.kz = kz;
 this.x = x;
 this.y = y;
 this.width = width;
 this.height = height;
 }
}

Du hast also den Falschen verdächtigt (die Serialisierung
hatte funktioniert, der Wiedereinbau der deseralisierten Komponente
in das GUI war das Problem) und damit noch mehr Fehler
eingebaut (siehe MyVector und das extra Enumeration-Attribut).

Üble Geschichte, aber daraus lernt man ne Menge :wink:

Gruß,
-Andreas.

die Vector-Klasse ist bereits serialisierbar,
deshalb ist Deine MyVector-Klasse schlichtweg überflüssig,

so was in der art dachte ich mir schon :smiley:

Hier Dein korrigierter Quelltext (ich habe ihn möglichst
wenig verändert und nur die Bugfixes gemacht, obwohl ich
einiges daran anders machen würde … ):

suuperding :smile: vielein dank für deine mühe. werd das ein oder andere
natürlich übernehmen, wobei ich das programm ja inzwischen schon am
laufen hatte und in meinem fall eher egal ist, ob das nun
superschicker und möglichs kurzer quelltext is, da das programm für
die uni is, und einfach nur funktionieren muss :smiley: trotzdem super
sache von dir.

Üble Geschichte, aber daraus lernt man ne Menge :wink:

jop dazu programmier ich ja um was zu lernen :wink:

Gruß,
-Andreas.

gruß zurück