Hello
Here is how to persist (save/restore) the users settings (ordering of columns, visbility etc) of JXTables in a view using the Swing Application Framework (JSR-296 -- https://appframework.dev.java.net/). You will need to download the jar for the App. framework to get the stuff below working.
I guess the whole view can be persisted by the App. framework but that will have to be later.
Code:<!-- Storage location for JXTable user settings --> <bean id="moduleApplicationContext" class="ModuleApplicationContext"> <constructor-arg value="${user.home}/.myAppHome/" /> </bean>
Code:/** * Nicked from * http://puces-blog.blogspot.com/2009/04/netbeans-platform-meets-swing.html */ public class ModuleApplicationContext extends ApplicationContext { private String storageDirectoryPath = ""; static { // download from https://jdnc-incubator.dev.java.net/source/browse/jdnc-incubator/src/kleopatra/java/org/jdesktop/appframework/swingx/XProperties.java?rev=1.3&view=markup new XProperties().registerPersistenceDelegates(); } public ModuleApplicationContext(String path) { // Needed due to issue // https://appframework.dev.java.net/issues/show_bug.cgi?id=112 setLocalStorage(new ModuleLocalStorage(this)); // getLocalStorage().setDirectory(getModuleSessionStorageDir(moduleInfo)); storageDirectoryPath = path; getLocalStorage().setDirectory(new File(storageDirectoryPath)); getSessionStorage().putProperty(JXTable.class, new XProperties.XTableProperty()); } }Code:/** * A LocalStorage for modules. It respects the direcory property in JNLP mode. <BR/> * <BR/> * Needed due to issue <A * HREF="https://appframework.dev.java.net/issues/show_bug.cgi?id=112"> * https://appframework.dev.java.net/issues/show_bug.cgi?id=112</A> * * @author puce */ public class ModuleLocalStorage extends LocalStorage { public ModuleLocalStorage(ApplicationContext context) { super(context); } @Override public boolean deleteFile(String fileName) throws IOException { File path = new File(getDirectory(), fileName); return path.delete(); } @Override public InputStream openInputFile(String fileName) throws IOException { File path = new File(getDirectory(), fileName); return new BufferedInputStream(new FileInputStream(path)); } @Override public OutputStream openOutputFile(String fileName) throws IOException { File path = new File(getDirectory(), fileName); return new BufferedOutputStream(new FileOutputStream(path)); } }Now we need a table factory that creates JXTablesCode:<bean id="tableFactory" class="DefaultTableFactory" /> <bean id="componentFactory" class="org.springframework.richclient.factory.DefaultComponentFactory"> <!-- property name="iconSource"> <ref bean="iconSource" /> </property --> <property name="messageSource"> <ref bean="messageSource" /> </property> <property name="tableFactory"> <ref bean="tableFactory" /> </property> </bean>
And then in your view(s):Code:public class DefaultTableFactory implements TableFactory { public JTable createTable() { JXTable result = new JXTable(); return configureTable(result); } public JTable createTable(TableModel model) { JXTable result = new JXTable(model); return configureTable(result); } private JXTable configureTable(JXTable result) { result.getSelectionMapper().setEnabled(false); result.setColumnControlVisible(true); result.setHighlighters(createHighlighter(result), new ColorHighlighter( HighlightPredicate.ROLLOVER_ROW, null, Color.BLUE)); result.setRolloverEnabled(true); result.setHorizontalScrollEnabled(true); return result; } private CompoundHighlighter createHighlighter(JXTable t) { ColorHighlighter first = new SubstanceHighLighter( HighlightPredicate.EVEN, t); ColorHighlighter hl = new SubstanceHighLighter(HighlightPredicate.ODD, t); return new CompoundHighlighter(first, hl); } // get striping on jxtable to work with substance static private class SubstanceHighLighter extends ColorHighlighter { private JXTable comp; SubstanceHighLighter(HighlightPredicate pred, JXTable t) { setHighlightPredicate(pred); comp = t; } @Override public Color getBackground() { return SubstanceColorUtilities.getStripedBackground(comp, getHighlightPredicate() == HighlightPredicate.EVEN ? 1 : 0); } } }
Notice that the JXTables need to have a name for all of this to work, e.g.:Code:public abstract class MyView extends AbstractView { private ModuleApplicationContext mac = (ModuleApplicationContext) Application .instance().getApplicationContext().getBean( "moduleApplicationContext"); ... @Override public void dispose() { saveJXTableSetup(getControl()); } private void saveJXTableSetup(Container comp) { Component[] components = comp.getComponents(); for (Component com : components) { if (com instanceof JXTable) { Container parent = com.getParent(); JXTable t = (JXTable) com; parent.remove(com); try { log.debug("Saving table state in " + t.getName() + ".xml"); mac.getSessionStorage().save(com, t.getName() + ".xml"); parent.add(com); } catch (IOException e) { log.error("", e); } } else if (com instanceof Container) { saveJXTableSetup((Container) com); } } }
More info (but cluttered with netbeans stuff) can be found here http://puces-blog.blogspot.com/2009/...ets-swing.htmlCode:public abstract class MyTable extends AbstractObjectTable { private ModuleApplicationContext mac = (ModuleApplicationContext) Application .instance().getApplicationContext().getBean( "moduleApplicationContext"); ... @Override protected JComponent createControl() { JXTable t = (JXTable) super.createControl(); // name table and restore its state t.setName(getModelId()); try { mac.getSessionStorage().restore(t, getModelId() + ".xml"); } catch (IOException e) { log.error("", e); } return t; }
BR
Carsten


Reply With Quote