tags:

views:

77

answers:

4

I'm trying to "future-proof" an application that I'm writing by splitting out those elements that are likely to change over time. In my application I need to be able to adapt to changes in the output format (e.g. today I output to a CSV file, in the future I may need to output directly to a SQL Server database, or to a web service, etc.).

I'm handling this by defining an abstract class ("OutputProvider") that I will subclass for each individual case. The one aspect of this that has me stumped is how to provide a configuration GUI that is specific to each concrete class. I have a settings dialog with a tab for output configuration. On that tab I intend to provide a drop-down to select the provider and a JPanel beneath it to hold the contents of the provider-specific GUI. How do I get the right GUI in that panel at runtime and have it behave correctly with respect to events?

Also, a bonus would be if there was a way to do this such that in order to add support for new providers I could simply provide a new jar or class file to be dropped in a specific folder and the application could pick that up at startup.

I'm using NetBeans and Swing.

+1  A: 

Perhaps you could having an abstract method on your OutputProvider class that returns a JPanel containing the configuration options for that provider. If you want to separate more then instead of returning a JPanel the method could return a Class/class name. An instance could then be created at runtime.

This question might answer the second part of your question.

Adrian
+1  A: 

Seems to me a perfect Factory Design Pattern Candidate e.g. you seem to want to call something like this ( in pseudocode: ´)

//get the writer responsible for storing to any media ... 
Writer objWriter = new Writer ( configForCsvOrDb ) ; 
//perform the actual write according to the type of storage
objWriter.Write(objToWrite ) ; 
YordanGeorgiev
+1  A: 

Adrian's solution is good. Just extend your OutputProvider to mandate the following two methods:

/**
 * returns a JPanel that shows configuration options for this outputprovider,
 * after initializing the JPanel with current output options
 */
public JPanel getConfigurationPanel();
/**
 * configures output options using values in configPanel, previously 
 * requested through getConfigurationPanel
 */
public void configureFromPanel(JPanel configPanel) throws BadConfigException;

and include the returned JPanel in the corresponding field of the output configuration dialog. When the user presses the "accept" button, configureFromPanel() gets called.

tucuxi
+1  A: 

This looks like a good case for the strategy pattern. You could define a OutputProviderStrategy with methods like getOutputPanel().

Catalina Island