如何使用对象序列化从文件加载线数组对象 java
How to load line array objects from a file using object serialization java
该程序旨在使用户能够用线绘制一些东西并将其保存到一个文件中,然后可以加载该文件,使用 ObjectOutput writeObject 方法保存可以正常工作,但它正在加载不起作用的文件,如果你保存文件你可以画一条额外的线来使显示与保存的不同,但是在使用 ObjectInputStream readObject 方法加载它时,它不会在面板上显示保存的绘图。
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import java.io.*;
public class DrawLine extends JPanel
{
private LineClass lines[];
private String fileName;
private int lineCount;
private LineClass currentLine;
public JLabel statusLabel;
private int currShapeX1,currShapeY1;
private static JButton saveButton, loadButton;
private ObjectOutputStream output;
private ObjectInputStream input;
private JFileChooser fileChooser;
public DrawLine()
{
statusLabel = new JLabel("(0,0)");
saveButton = new JButton("Save");
loadButton = new JButton("Load");
lines = new LineClass[100];
lineCount = 0;
currentLine = null;
MouseHandler handler = new MouseHandler();
addMouseListener(handler);
addMouseMotionListener(handler);
saveButton.addActionListener(handler);
loadButton.addActionListener(handler);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(int count = 0; count < lineCount; ++count)
{
lines[count].draw(g);
}
if( currentLine != null ) {
currentLine.draw(g);
}
}
public static void main(String args[])
{
JFrame frame = new JFrame();
DrawLine panel = new DrawLine();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(saveButton,BorderLayout.NORTH);
frame.add(loadButton,BorderLayout.SOUTH);
frame.add(panel,BorderLayout.CENTER);
frame.setSize(400,400);
frame.setVisible(true);
}
private class MouseHandler extends MouseAdapter implements MouseMotionListener, ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == loadButton)
{
fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int result = fileChooser.showOpenDialog(DrawLine.this);
if (result == JFileChooser.CANCEL_OPTION)
System.err.println("No file selected.");
else
{
File file = fileChooser.getSelectedFile();
if ((file != null) && !(file.getName().equals("")))
{
fileName = file.getName();
try
{
input = new ObjectInputStream(new FileInputStream(fileName));
lines = ((LineClass[])input.readObject());
lineCount = 0;
for(int j = 0; j < 100; ++j)
{
if (lines[j] == null)
break;
else
lineCount++;
}
repaint();
}
catch(EOFException ex)
{
System.out.println("Finished loading file");
}
catch(IOException ex)
{
JOptionPane.showMessageDialog(DrawLine.this, "Error loading \""+fileName+"\"", "Error Message", JOptionPane.ERROR_MESSAGE);
}
catch(ClassNotFoundException ex)
{
JOptionPane.showMessageDialog(DrawLine.this, "Unable to create object", "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
}
}
if (event.getSource() == saveButton)
{
fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int result = fileChooser.showSaveDialog(DrawLine.this);
if (result == JFileChooser.CANCEL_OPTION)
System.err.println("File was not saved");
else if (result == JFileChooser.APPROVE_OPTION)
{
File file = fileChooser.getSelectedFile();
if ((file != null)&&!(file.getName().equals("")))
{
fileName = file.getName()+".drw";
try
{
output = new ObjectOutputStream(new FileOutputStream(fileName));
output.writeObject(lines);
output.close();
System.out.println(fileName+" saved");
}
catch(IOException ex)
{
JOptionPane.showMessageDialog(DrawLine.this, "Error saving \""+fileName+"\"", "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
}
}
}
public void mousePressed(MouseEvent event)
{
//it assigns currentShape a new shape and initializes both points to the mouse position.
currShapeX1 = event.getX();
currShapeY1 = event.getY();
}
public void mouseReleased(MouseEvent event)
{
//finish drawing the current shape and place it in the array
//Set the second point of currentShape to the current mouse position
currentLine = new LineClass(currShapeX1,currShapeY1,event.getX(),event.getY());
// and add currentShape to the array.
//Instance variable shapeCount determines the insertion index. Set currentShape to null and call method repaint to update the drawing with the new shape.
lines[lineCount] = currentLine;
lineCount++;
currentLine = null;
repaint();
}
public void mouseDragged(MouseEvent event)
{
//it sets the second point of the currentShape to the current mouse position and calls method repaint
//finish drawing the current shape and place it in the array
//Set the second point of currentShape to the current mouse position
currentLine = new LineClass(currShapeX1,currShapeY1,event.getX(),event.getY());
// and add currentShape to the array.
//Instance variable shapeCount determines the insertion index. Set currentShape to null and call method repaint to update the drawing with the new shape.
//lines[lineCount] = currentLine;
//currentLine = null;
repaint();
statusLabel.setText(String.format("(%d,%d)",event.getX(),event.getY()));
}
public void mouseMoved(MouseEvent event)
{
//to set the text of the statusLabel so that it displays the mouse coordinates—this will update the label with the coordinates every time the user moves
//(but does not drag) the mouse within the DrawPanel
statusLabel.setText(String.format("(%d,%d)",event.getX(),event.getY()));
}
}
}
//LineClass
class LineClass implements Serializable
{
private int x1;
private int y1;
private int x2;
private int y2;
public LineClass(int x1, int y1, int x2, int y2)
{
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public void draw(Graphics g)
{
g.drawLine(x1,y1,x2,y2);
}
}
当您读回文件时,lineCount 似乎设置为 100,因为这是您保存的数组的大小。
如果你只画了 3 条线,lineCount 是 100 而不是 3。
这意味着当您进行重绘时,它会尝试绘制空对象。
你需要做的是当你加载文件时找到行数组中的第一个空值并根据它设置你的 lineCount,而不是数组的长度。
一个简单的方法是
for (int loop = 0; loop < lines.length; loop++)
{
if (lines[loop] == null)
{
lineCount = loop;
break;
}
}
而不是
lineCount = lines.length;
该程序旨在使用户能够用线绘制一些东西并将其保存到一个文件中,然后可以加载该文件,使用 ObjectOutput writeObject 方法保存可以正常工作,但它正在加载不起作用的文件,如果你保存文件你可以画一条额外的线来使显示与保存的不同,但是在使用 ObjectInputStream readObject 方法加载它时,它不会在面板上显示保存的绘图。
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import java.io.*;
public class DrawLine extends JPanel
{
private LineClass lines[];
private String fileName;
private int lineCount;
private LineClass currentLine;
public JLabel statusLabel;
private int currShapeX1,currShapeY1;
private static JButton saveButton, loadButton;
private ObjectOutputStream output;
private ObjectInputStream input;
private JFileChooser fileChooser;
public DrawLine()
{
statusLabel = new JLabel("(0,0)");
saveButton = new JButton("Save");
loadButton = new JButton("Load");
lines = new LineClass[100];
lineCount = 0;
currentLine = null;
MouseHandler handler = new MouseHandler();
addMouseListener(handler);
addMouseMotionListener(handler);
saveButton.addActionListener(handler);
loadButton.addActionListener(handler);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(int count = 0; count < lineCount; ++count)
{
lines[count].draw(g);
}
if( currentLine != null ) {
currentLine.draw(g);
}
}
public static void main(String args[])
{
JFrame frame = new JFrame();
DrawLine panel = new DrawLine();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(saveButton,BorderLayout.NORTH);
frame.add(loadButton,BorderLayout.SOUTH);
frame.add(panel,BorderLayout.CENTER);
frame.setSize(400,400);
frame.setVisible(true);
}
private class MouseHandler extends MouseAdapter implements MouseMotionListener, ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == loadButton)
{
fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int result = fileChooser.showOpenDialog(DrawLine.this);
if (result == JFileChooser.CANCEL_OPTION)
System.err.println("No file selected.");
else
{
File file = fileChooser.getSelectedFile();
if ((file != null) && !(file.getName().equals("")))
{
fileName = file.getName();
try
{
input = new ObjectInputStream(new FileInputStream(fileName));
lines = ((LineClass[])input.readObject());
lineCount = 0;
for(int j = 0; j < 100; ++j)
{
if (lines[j] == null)
break;
else
lineCount++;
}
repaint();
}
catch(EOFException ex)
{
System.out.println("Finished loading file");
}
catch(IOException ex)
{
JOptionPane.showMessageDialog(DrawLine.this, "Error loading \""+fileName+"\"", "Error Message", JOptionPane.ERROR_MESSAGE);
}
catch(ClassNotFoundException ex)
{
JOptionPane.showMessageDialog(DrawLine.this, "Unable to create object", "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
}
}
if (event.getSource() == saveButton)
{
fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int result = fileChooser.showSaveDialog(DrawLine.this);
if (result == JFileChooser.CANCEL_OPTION)
System.err.println("File was not saved");
else if (result == JFileChooser.APPROVE_OPTION)
{
File file = fileChooser.getSelectedFile();
if ((file != null)&&!(file.getName().equals("")))
{
fileName = file.getName()+".drw";
try
{
output = new ObjectOutputStream(new FileOutputStream(fileName));
output.writeObject(lines);
output.close();
System.out.println(fileName+" saved");
}
catch(IOException ex)
{
JOptionPane.showMessageDialog(DrawLine.this, "Error saving \""+fileName+"\"", "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
}
}
}
public void mousePressed(MouseEvent event)
{
//it assigns currentShape a new shape and initializes both points to the mouse position.
currShapeX1 = event.getX();
currShapeY1 = event.getY();
}
public void mouseReleased(MouseEvent event)
{
//finish drawing the current shape and place it in the array
//Set the second point of currentShape to the current mouse position
currentLine = new LineClass(currShapeX1,currShapeY1,event.getX(),event.getY());
// and add currentShape to the array.
//Instance variable shapeCount determines the insertion index. Set currentShape to null and call method repaint to update the drawing with the new shape.
lines[lineCount] = currentLine;
lineCount++;
currentLine = null;
repaint();
}
public void mouseDragged(MouseEvent event)
{
//it sets the second point of the currentShape to the current mouse position and calls method repaint
//finish drawing the current shape and place it in the array
//Set the second point of currentShape to the current mouse position
currentLine = new LineClass(currShapeX1,currShapeY1,event.getX(),event.getY());
// and add currentShape to the array.
//Instance variable shapeCount determines the insertion index. Set currentShape to null and call method repaint to update the drawing with the new shape.
//lines[lineCount] = currentLine;
//currentLine = null;
repaint();
statusLabel.setText(String.format("(%d,%d)",event.getX(),event.getY()));
}
public void mouseMoved(MouseEvent event)
{
//to set the text of the statusLabel so that it displays the mouse coordinates—this will update the label with the coordinates every time the user moves
//(but does not drag) the mouse within the DrawPanel
statusLabel.setText(String.format("(%d,%d)",event.getX(),event.getY()));
}
}
}
//LineClass
class LineClass implements Serializable
{
private int x1;
private int y1;
private int x2;
private int y2;
public LineClass(int x1, int y1, int x2, int y2)
{
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public void draw(Graphics g)
{
g.drawLine(x1,y1,x2,y2);
}
}
当您读回文件时,lineCount 似乎设置为 100,因为这是您保存的数组的大小。
如果你只画了 3 条线,lineCount 是 100 而不是 3。
这意味着当您进行重绘时,它会尝试绘制空对象。
你需要做的是当你加载文件时找到行数组中的第一个空值并根据它设置你的 lineCount,而不是数组的长度。
一个简单的方法是
for (int loop = 0; loop < lines.length; loop++)
{
if (lines[loop] == null)
{
lineCount = loop;
break;
}
}
而不是
lineCount = lines.length;