有时我们在遇到要对复杂对象的状态进行保存时,常常难以处理对象的状态。比如如图所示遇到的情况:
我们要在点击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对象进行一份拷贝,保存一份历史状态的备份。