我基本上想在Java中序列化一个ArrayList,这显然是需要更改的代码。 (编辑:粘贴整个类)
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import javax.swing.*;
public class GraphEditSerial extends JFrame{
//stores all dots on the MainPanel
private ArrayList<Circle> circles = new ArrayList<Circle>();
class Circle implements Serializable{
private static final long serialVersionUID = -8364830119753788192L;
private int x, y;
public String toString(){
return "("+x+", "+y+")";
}
public Circle(int x, int y) {
this.x = x;
this.y = y;
}
}
//variables for current workmode
private boolean canInsert = false;
private boolean canDelete = false;
private boolean canMove = false;
private boolean wasMoved = false;
//defines a JPanel and adds a MouseListener
class MainPanel extends JPanel implements MouseListener{
//constructor
public MainPanel(){
setBackground(Color.white);
addMouseListener(this);
}
//paints a blue spot on specified location
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.blue);
for (Circle k: circles) {
g.fillOval(k.x - 5, k.y - 5, 10, 10);
}
}
public void mouseClicked(MouseEvent e) {
//user wants to add a circle
if(canInsert){
//adds new circle to ArrayList and displays all circles
circles.add(new Circle(e.getX(), e.getY()));
repaint();
}
//user wants to delete a circle
else if(canDelete){
//checking if clicked position is within 4px of existing circles
for (int k=0; k<circles.size();k++){
Circle c = circles.get(k);
if(c.x-e.getX()<=4
&&c.x-e.getX()>=-4
&&c.y-e.getY()<=4
&&c.y-e.getY()>=-4){
//removes circle that is within 4 px of clicked position
circles.remove(k);
}
}
repaint();
}
}
//used to move existing circles, but only if current workmode = move
public void mousePressed(MouseEvent e) {
//current workmode has to be "move"
if(canMove==true){
//checking if clicked position is within 4px of existing circles
for (int k=0; k<circles.size();k++){
Circle c = circles.get(k);
if(c.x-e.getX()<=4
&&c.x-e.getX()>=-4
&&c.y-e.getY()<=4
&&c.y-e.getY()>=-4){
//removes circle that is within 4 px of clicked position
circles.remove(k);
wasMoved=true;
}
}
}
}
//displays moved circle at current position of mouse
public void mouseReleased(MouseEvent e) {
//current workmode has to be "move"
if(canMove==true){
//checking if user clicked on an existing circle before
if(wasMoved==true){
circles.add(new Circle(e.getX(), e.getY()));
repaint();
wasMoved=false;
}
}
}
//not assigned
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
//Menu
JMenuBar mb = new JMenuBar();
JMenu graph = new JMenu("Graph");
JMenu vertex = new JMenu("Vertex");
JMenuItem open = new JMenuItem("open");
JMenuItem mnew = new JMenuItem("new");
JMenuItem save = new JMenuItem("save");
JMenuItem insert = new JMenuItem("insert");
JMenuItem move = new JMenuItem("move");
JMenuItem delete = new JMenuItem("delete");
JMenuItem none = new JMenuItem("none");
//FileChooser
JFileChooser fc;
//main panel
MainPanel main = new MainPanel();
//bottom row
JPanel bottomrow = new JPanel(new GridLayout(1,2));
JLabel l1 = new JLabel("Selected Action: ", SwingConstants.RIGHT);
JTextField l2 = new JTextField("none", SwingConstants.LEFT);
//setting up a Menu with MenuItems, Dimensions, ActionListeners, etc...
public GraphEditSerial(String s){
super(s);
//adding menu items to menus
graph.add(open);
graph.add(mnew);
graph.add(save);
vertex.add(insert);
vertex.add(move);
vertex.add(delete);
vertex.add(none);
fc = new JFileChooser();
//Label l2 changes accordingly to selected MenuItem
open.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Graph: open");
canInsert=false; canDelete=false; canMove=false;
repaint();
int returnVal = fc.showOpenDialog(GraphEditSerial.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File f = fc.getSelectedFile();
try{
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<Circle> a = (ArrayList<Circle>)ois.readObject();
circles = a;
repaint();
}
catch (ClassNotFoundException e) {}
catch (IOException e){}
}
}
});
mnew.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Graph: new");
canInsert=false; canDelete=false; canMove=false;
//clears all vertexes
circles.clear();
repaint();
}
});
save.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Graph: save");
canInsert=false; canDelete=false; canMove=false;
repaint();
int returnVal = fc.showSaveDialog(GraphEditSerial.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String datname = fc.getSelectedFile().getAbsolutePath().toString();
try{
FileOutputStream fos = new FileOutputStream(datname);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject((ArrayList<Circle>) circles);
oos.close();
}
catch (IOException e){
l2.setText(e.toString());
e.printStackTrace();
}
}
}
});
insert.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Vertex: insert");
canInsert=true; canDelete=false; canMove=false;
repaint();
}
});
move.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Vertex: move");
canInsert=false; canDelete=false; canMove=true;
repaint();
}
});
delete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("Vertex: delete");
canInsert=false; canDelete=true; canMove=false;
repaint();
}
});
none.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
l2.setText("none");
canInsert=false; canDelete=false; canMove=false;
repaint();
}
});
bottomrow.add(l1);
bottomrow.add(l2);
main.setPreferredSize(new Dimension(500,300));
main.setOpaque(true);
main.setBackground(Color.WHITE);
mb.setPreferredSize(new Dimension(500, 20));
mb.add(graph);
mb.add(vertex);
setJMenuBar(mb);
add(main, BorderLayout.CENTER);
add(bottomrow, BorderLayout.PAGE_END);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
pack();
setVisible(true);
setLocationRelativeTo(null);
}
public static void main(String[] arg){
//new GraphEditor("MyGraphEditor");
new GraphEditSerial("MyGraphEditor");
}
}
我在没有JFileChooser的情况下做到了这一点,只是指定了一个文件名,所以它就像一个魅力。我也可以反序列化而不会出现问题。但是,一旦我使用JFileChooser,我就会得到“ java.io.NotSerializableException:javax.swing.plaf.metal.MetalFileChooserUI”
有人知道吗?
编辑:这是e.printStackTrace()打印的内容
java.io.NotSerializableException: javax.swing.plaf.metal.MetalFileChooserUI
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at javax.swing.event.EventListenerList.writeObject(Unknown Source)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source)
at javax.swing.JComponent.writeObject(Unknown Source)
at sun.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source)
at java.awt.Window.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.awt.Window.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.util.ArrayList.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at GraphEditSerial$3.actionPerformed(GraphEditSerial.java:202)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
最佳答案
Circle
是UI类本身的内部类吗?如果它是内部类,而fc是外部类的字段,则writeObject
元素上的Circle
不仅会尝试序列化其字段,而且还将尝试序列化其外部类的字段。而且,如果fc是外部类的一个字段,并且是MetalFileChooserUI,则显然它将失败序列化。
这是我可以从您的代码段中得出的最佳猜测。如果不能解决您的问题,如vanza所说,我们将需要有关Circle
内容的更多信息