package com.horstmann.violet.framework; import com.horstmann.violet.ArrowHead; import com.horstmann.violet.BentStyle; import com.horstmann.violet.LineStyle; public class EditorFrame { EditorFrame(Class appClass) { /*fileMenu.add(factory.createMenuItem( "file.save_as", this, "saveAs"));*/ fileMenu.add(factory.createMenuItem( "file.save_as", new ActionListener() { public void actionPerformed(ActionEvent event) { saveAs(); } })); } /** Saves the current graph as a new file. */ public void saveAs() { GraphFrame frame = (GraphFrame)desktop.getSelectedFrame(); if (frame == null) return; Graph graph = frame.getGraph(); try { Save save = fileService.save(null, frame.getFileName(), violetFilter, null, defaultExtension); OutputStream out = save.getOutputStream(); if (out != null) { try { saveFile(graph, out); } catch (Exception e) { e.printStackTrace(); } out.close(); frame.setFileName(save.getName()); setTitle(); frame.getGraphPanel().setModified(false); } } catch (IOException exception) { JOptionPane.showInternalMessageDialog(desktop, exception); } } /** Saves the current graph in a file. We use long-term bean persistence to save the program data. See http://java.sun.com/products/jfc/tsc/articles/persistence4/index.html for an overview. @param out the stream for saving */ protected static void saveFile(Graph graph, OutputStream out) { XMLEncoder encoder = new XMLEncoder(out); encoder.setExceptionListener(new ExceptionListener() { public void exceptionThrown(Exception ex) { ex.printStackTrace(); } }); /* The following does not work due to bug #4741757 encoder.setPersistenceDelegate( Point2D.Double.class, new DefaultPersistenceDelegate( new String[]{ "x", "y" }) ); */ encoder.setPersistenceDelegate(Point2D.Double.class, new DefaultPersistenceDelegate() { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); Point2D p = (Point2D)oldInstance; out.writeStatement( new Statement(oldInstance, "setLocation", new Object[]{ new Double(p.getX()), new Double(p.getY()) }) ); } }); encoder.setPersistenceDelegate(BentStyle.class, staticFieldDelegate); encoder.setPersistenceDelegate(LineStyle.class, staticFieldDelegate); encoder.setPersistenceDelegate(ArrowHead.class, staticFieldDelegate); Graph.setPersistenceDelegate(encoder); AbstractNode.setPersistenceDelegate(encoder); encoder.writeObject(graph); encoder.close(); } private static PersistenceDelegate staticFieldDelegate = new DefaultPersistenceDelegate() { protected Expression instantiate(Object oldInstance, Encoder out) { try { Class cl = oldInstance.getClass(); Field[] fields = cl.getFields(); for (int i = 0; i < fields.length; i++) { if (Modifier.isStatic( fields[i].getModifiers()) && fields[i].get(null) == oldInstance) { return new Expression(fields[i], "get", new Object[] { null }); } } } catch (IllegalAccessException ex) { ex.printStackTrace(); } return null; } protected boolean mutatesTo( Object oldInstance, Object newInstance) { return oldInstance == newInstance; } }; // workaround for bug #4646747 in J2SE SDK 1.4.0 private static java.util.HashMap beanInfos; static { beanInfos = new java.util.HashMap(); Class[] cls = new Class[] { Point2D.Double.class, BentStyle.class, ArrowHead.class, LineStyle.class, Graph.class, AbstractNode.class, }; for (int i = 0; i < cls.length; i++) { try { beanInfos.put(cls[i], java.beans.Introspector.getBeanInfo(cls[i])); } catch (java.beans.IntrospectionException ex) { } } } }