2

This is a general software design question. My program is written in Java, but I suppose my question applies to any object-oriented programming language. The best way for me to explain my situation is with an example.

In applications like LibreOffice and MS Office, the user chooses a program option when launching the software. For example, in LibreOffice, you have to choose Writer, Calc, Draw, Impress, etc. before you can start using the program. In MS Office, it's Word, Excel, PowerPoint, etc.

My program is sort of like that. It has a main JFrame class that sets an overridden JPanel as its content pane when the program launches. So far, there are three choices of JPanel, and the program chooses between them with a simple conditional statement:

public MyJFrame(String editorType, int numPages) { ... if (editorType.equals("order-editor")) setContentPane(new OrderEditor(this)); else if (editorType.equals("order-finder")) setContentPane(new OrderFinder(this)); else if (editorType.equals("article-writer")) setContentPane(new ArticleWriter(this, numPages)); ... } 

So everything is hard-coded into the JFrame class. When I override another JPanel, I have to go back to the JFrame class to add another else if clause to the constructor. Is there a better way to do this? The only way I can imagine doing it programmatically would be compiling code at runtime, and that seems like the wrong way to go.

The editorType string is a command-line argument to the main function. I could pass a JPanel object to the constructor instead, but I would still have to check the arguments to main before choosing the appropriate class. I'm beginning to think there's no other way to do this, but I'll leave this question up just in case.

Here's an example of my main function:

public static void main(String[] args) { // calls private static String getEditorType(String[] args) // to parse the program input String editorType = getEditorType(args); if (editorType == null) { System.out.println("Invalid editor type."); System.exit(1); } int[] numPages = {-1}; if (editorType.equals("article-writer")) // calls a similar static function to parse input numPages[0] = getNumPages(args); EventQueue.invokeLater(new Runnable() { public void run() { try { JFrame frame = new MyJFrame(editorType, numPages[0]); frame.pack(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } 
3
  • And just where are you getting that editor type string from? Any good reason it couldn't be passing us a new OrderEditor() or a new OrderEditorBuilder()? Commented Aug 20, 2016 at 14:57
  • Sorry, I forgot to add that. I will edit my question. Thank you. Commented Aug 20, 2016 at 15:03
  • @chris Look at Class.forName() to lookup classes by name. Commented Aug 21, 2016 at 13:06

1 Answer 1

0

First, get rid of that numPages. The OrderEditor, OrderFinder and ArticleWriter should implement common interface, that allows them to parse their own arguments. This is so that if arguments of any of those change, you don't have to change the whole initialization logic.

Second thing to do is to create dictionary where key is the editorType and value is either function that creates the instance or interface that allows creation of the instance.

I would actually opt in for the interface, because then argument parsing can be moved into it.

1
  • Okay, thank you. I thought about creating something like HashMap<String, MyPanelBuilder> where MyPanelBuilder would be an interface that calls the appropriate JPanel constructor. I'll set it up this way. Commented Aug 20, 2016 at 16:52

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.