有时我们在遇到要对复杂对象的状态进行保存时,常常难以处理对象的状态。比如如图所示遇到的情况:
我们要在点击OK按钮时要保存该界面的状态,而在点击Cancel按钮时要取消该次界面的操作,回到之前界面的状态。如果在点击Cancel状态时,该界面的数据状态和初始化一致,则下次我们弹出该对话框时,直接重新初始化该对话框就对了。可是如果之前我们已经对该界面进行了操作。要在点击Cancel后,再次显示该对话框时能回到上次的状态,就比较麻烦了。我们可以对该界面的各个组件的状态进行记录保存,在初始化完该对话框后,根据保存的状态再来填充界面的状态,这能达到我们的要求。可是如果该界面的数据结构比较复杂,这样做就比较麻烦了。下面我们采用java对象序列化对象来实现复杂数据结构状态的保存。
示例
复杂对象代码:
package com.michael.test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
/**
*@author mengke
*@email wqjsir@foxmail.com
*@version 1.0
*@date 2011-11-5 下午06:41:39
*/
public class ComplexObject extends JDialog implements Serializable{
private static final long serialVersionUID = 1L;
private JButton btnOk;
private JButton btnCancel;
private JComboBox comBox;
private JRadioButton radioBtn;
private JRadioButton radioBtn2;
private JCheckBox checkBox;
private JCheckBox checkBox2;
private boolean isBtnOkAction;
public ComplexObject(){
putcompents();
setSize(new Dimension(200,300));
setModal(true);
}
private void putcompents() {
comBox = new JComboBox();
comBox.addItem("item1");
comBox.addItem("item2");
radioBtn = new JRadioButton("radio button1");
radioBtn2 = new JRadioButton("radio button2");
checkBox = new JCheckBox("check box 1");
checkBox2 = new JCheckBox("check box 2");
JPanel _plBody = new JPanel();
_plBody.setLayout(new GridLayout(5, 1));
_plBody.add(comBox);
_plBody.add(radioBtn);
_plBody.add(radioBtn2);
_plBody.add(checkBox);
_plBody.add(checkBox2);
btnOk = new JButton("OK");
btnCancel = new JButton("Cancel");
ButtonActionListener _actionListener = new ButtonActionListener();
btnOk.addActionListener(_actionListener);
btnCancel.addActionListener(_actionListener);
JPanel _plButton = new JPanel();
_plButton.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5));
_plButton.add(btnOk);
_plButton.add(btnCancel);
setLayout(new BorderLayout());
add(_plBody,BorderLayout.CENTER);
add(_plButton,BorderLayout.SOUTH);
}
public boolean isBtnOkAction(){
return isBtnOkAction;
}
/**该类必须实现Serializable接口,不然监听类不会被序列化*/
class ButtonActionListener implements ActionListener,Serializable{
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnOk){
isBtnOkAction = true;
setVisible(false);
}else if(e.getSource() == btnCancel){
isBtnOkAction = false;
setVisible(false);
}
}
}
}
拥有该复杂对象的类:
package com.michael.test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 复杂对象状态的保持
*
* @author mengke
*@email wqjsir@foxmail.com
*@version 1.0
*@date 2011-11-5 下午06:39:12
*/
public class ComplexStatusSave {
private ComplexObject currentComplexObj;
private ComplexObject oldComplexObj;
private boolean isPreSaveOkStatus;
public void showUI() {
final JFrame _frame = new JFrame();
_frame.setLayout(new BorderLayout());
JButton _btnAction = new JButton("button");
_btnAction.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (currentComplexObj == null ||oldComplexObj == null|| !isPreSaveOkStatus) {
currentComplexObj = new ComplexObject( );
currentComplexObj.setLocationRelativeTo(_frame);
}
currentComplexObj.setVisible(true);
//操作前没有保存OK状态,则重新获取是否需要保存OK状态
if (!isPreSaveOkStatus) {
//如果点击了OK按钮则保存OK状态
if(currentComplexObj.isBtnOkAction()){
oldComplexObj = copyObject(currentComplexObj);
isPreSaveOkStatus = true;
}
}else if(!currentComplexObj.isBtnOkAction()){
currentComplexObj = oldComplexObj;
oldComplexObj = copyObject(currentComplexObj);
} else if (currentComplexObj.isBtnOkAction()) {
oldComplexObj = copyObject(currentComplexObj);
}
}
});
JPanel _plButton = new JPanel();
_plButton.setLayout(new FlowLayout());
_plButton.add(_btnAction);
_frame.add(_plButton, BorderLayout.SOUTH);
_frame.setSize(new Dimension(300, 200));
_frame.setLocation(300, 200);
_frame.setVisible(true);
}
/**
* 对对象进行复制
* @param obj
* @return
*/
private ComplexObject copyObject(Object obj) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oops = new ObjectOutputStream(baos);
oops.writeObject(obj);
oops.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
try {
ObjectInputStream ois = new ObjectInputStream(bais);
return (ComplexObject) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
new ComplexStatusSave().showUI();
}
}
对于复杂对象数据状态的保存,这里难就难再有两个按钮,不同的按钮的操作要求有不同的结果。我们这里只是通过java对象序列化来实现对复杂UI对象进行一份拷贝,保存一份历史状态的备份。