Vector // Serializable // Hiiiiilfe ;)

Von: , Frage gestellt am Do, 7. Dez 2006

hey :D

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();
}

}

7 Antworten zu dieser Frage

  1. Antwort von nach 3 Stunden 1 hilfreich
    Re: Vector // Serializable // Hiiiiilfe ;)

    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 :(
    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 ;-)

    mfg M.L.

    • Antwort von nach 9 Stunden 0 hilfreich
      Re^2: Vector // Serializable // Hiiiiilfe ;)

      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 :(
      jop die exception taucht auch nich beim kompilieren auf, sondern dann
      wenn du versuchst irgendwelche gemalten striche zu SPEICHERN.

      liebe grüße, freddy

      • Antwort von nach 10 Stunden 1 hilfreich
        Re^3: Vector // Serializable

        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

        • Antwort von nach 11 Stunden 0 hilfreich
          Re^4: Vector // Serializable

          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 :))))

          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 :D !!!

          grüße freddy

          • Antwort von nach 12 Stunden 0 hilfreich
            Re^5: Vector // Serializable

            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

  2. Antwort von nach einem Tag 0 hilfreich
    Serializable: Korrektur mit Erklärung ;)

    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 ;)

    Gruß,
    -Andreas.

    • Antwort von nach einem Tag 0 hilfreich
      Re: Serializable: Korrektur mit Erklärung ;)

      die Vector-Klasse ist bereits serialisierbar,
      deshalb ist Deine MyVector-Klasse schlichtweg überflüssig,
      so was in der art dachte ich mir schon :D 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 :) 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 :D trotzdem super
      sache von dir. Üble Geschichte, aber daraus lernt man ne Menge ;)
      jop dazu programmier ich ja um was zu lernen ;) Gruß,
      -Andreas.
      gruß zurück

Keine passende Antwort gefunden? Jetzt eigene Frage stellen!