Question

I would like to ask you about one technical aspect of creating GUI in Swing. Let's assume I have a JFrame or JDialog (never mind) with content organized in many JPanels (settings, actions, displaying data, charts etc...) - all in one Frame.

For example: here

What I'm doing now is to definie all components in one file (let name it MainPanel.java) and organizing them in JPanels. A have a separate methods for organizing each panel

private void organizePanels() {
  pnlSettings = createPnlSettings();
  pnlActions = createPnlActions();
  pnlChart = createPnlChart();
  // ...
}

Each method is responsible for setting JPanel's layout, organizing components inside it etc. When I have 3-4 not complicated panels it makes sense (I mean is quite readable). But if I create a more complicated structure it starts to be a small maintaining nightmare (or a good starting point for being such).

That's why I want to use such approach: - For each JPanel create a separate class - Each class should have a accessors to their inner components (clicking a JButton in JPanel A should effect in refreshing a JCombo in other JPanel). -Comunication between Panels should be provided somehow by MainPanel.

So, in mainPanel I will have only references to JPanels and not to components inside them. Accessing particular data will be a little bit longer (pnlActions.getSaveButton.setEnabled(true) instead of btnSave.setEnabled(true) but it's probably a natural consequnce. I can make also all components in JPanels public.

Do you find this approach correct? Do you think that I should use the second approach all the time or maybe my first approach is suitable for not very complicated structures?

What experience do you have?

Was it helpful?

Solution

Like so many things in GUI application design, which way is best is a matter of tradeoffs that eventually depend on the application itself. There is no right answer that applies across many applications.

Your way will work and can be best in some situations. It does, however, spread the knowledge of the organization of your GUI panels across multiple classes, and that could make maintenance more difficult than it needs to be. If you later want to move some buttons or groups of buttons to another panel for whatever reason, then the access of the data changes, and that means you have to change code in whatever places access the data as well as where the buttons are.

You could, also, design a class that holds just the data for the panel, ensuring that there are NO UI dependencies anywhere in it. Neither Swing nor any other UI package should appear anywhere in the list of imports, and if you wanted to use this class in, say, an SWT or Spring MVC or Windows application, it should be able to work there unchanged. Then provide a reference to a singleton instance of this class to each of your panels, and let them get and set values as they need to. This allows you to change the UI in whatever fashion you like without changing how the data is accessed.

This method supposes that this "data model" for the given frame/dialog is not so complicated that a class to handle it is unduly complex itself. For such a complex frame, you might consider an overall model that was divided into sections, given that different portions of the model only need accessing from certain parts of the UI, and dividing up access among those sections.

OTHER TIPS

I think, you are on the right way. I would even go further by introducing a panel-handler class (static or not). This way you are clearly seperating the GUI-components (including the JFrame itself) from its internal management. Register your panels via a public method in you panel-handler in some way. If a something is happening in one panel whicha ffects other, you let the panel contact the handler as you already planned it. All panels have their respective interface which determines how the handler can manipulate them. This conceptual design is quite feasable for bigger applications because the handler sums up all possible interactions which could be triggered instead of "hiding" away the functionalities somewhere in a pile of panel-classes.

You could even improve this conceptual design by letting all panels inerhit methods or variables which they share. This reduces time and effort for some changes in code. If you want to use more concurrent programming, a handler-class allows you to create a query for everything which needs to be done. You simply let the panels add jobs to the query and the handler does the jobs and remove them from the query afterwards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top