Should I subclass JFrame / JPanel or not?

I was used to subclass window classes in a different programming environment, but in Java tutorials I usually see something like

JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS)); p.add(aComponent); p.add(anotherComponent); 

So what are the conventions in Java regarding subclassing the classes of the top container?

+6
source share
5 answers

Use the same principle as for all java classes. If you change or extend behavior or functionality, then by all means extend JPanel or JFrame . The trick is to think carefully and decide if you are really adding something. In most cases, when I see people extending the JFrame , this is neither necessary nor wrong;

 public class MyFrame extends JFrame { public static void main(String[] args) { new MyFrame().setVisible(true); } } 

Why worry about a JFrame extension? You have not added anything! Composition is a much better option.

The JPanel extension is a little different. JPanel is a pretty abstract idea, its just a general container for other components. IMHO for a subclass of JPanel permissible to create a more specific panel and then use it in your application. It promotes OOP and encapsulation.

For example, let's say your graphical interface had two main display areas; one with some buttons / controls / inputs, and the other with displaying the output (for example, in the text area). For a subclass of JPanel it is perfectly acceptable to create a ControlPanel that contains buttons / controls / inputs. This translates all the code into a nice neat module, clearing out its class that contains and processes the main JFrame .

+6
source

There is no rule for this, it depends on how you think about your object. You can have a JPanel that has a specific layout and bahavior, so its, for example, VideoViewerPanel. But even this VideoViewerPanel may contain a JPanel, which is designed only to arrange some buttons so that you don’t just name it and just use it as a JPanel.

+3
source

I think that this is due to the principle of the replacement of Liskov, you should study it.

Liskov substitution principle

Liskov Substitution Principle: An Applied Example

+2
source

A well-known and good practice is to avoid subclassing top-level containers ( JFrame , JDialog , JInternalFrame ).

Regarding JPanel , several methods are used:

  • subclass for each view (then add all components inside the constructor subclass)
  • create a ViewBuilder (for each view type) that dynamically adds components to the "standard" JPanel

Usually I use the first option, which seems more logical to me, but I also sometimes use the second method with some level of adaptation: my view designer actually creates and saves (as fields) all the components, but adds them to the existing panel (passed as an argument).

For example, I use this to reuse sets of components: for example. I have an AddressView class that works this way and I add it twice to ContactView that subclasses JPanel , once for the home address, once for the business address.

You could say that I could also subclass JPanel for AddressView , and then add 2 instances to my ContactView panel. The reason why I do not do this is because Swing LayoutManager does not support alignment of components on different panels, so the resulting ContactView panel does not look visually pleasing in this case.

+1
source

My general rule: Before using inheritance, consider whether composition makes sense.

Cause. Subclasses usually mean greater complexity and connectivity, i.e. harder to change, maintain, and scale without making mistakes.

A more complete and specific answer from Tim Boudreau from Sun:

Common problems using inheritance, as I see it, are:

  • Innocent actions can have unexpected results. A classic example of this is the call to overridden methods from the superclass constructor before the fields of instances of subclasses have been initialized. In an ideal world, no one will ever do this. This is not an ideal world.
  • He suggests perverse temptations for subclasses to make assumptions about the order of method calls, etc. - such assumptions tend not to be stable if the superclass can evolve over time. See also my toaster and coffee machine counterpart .
  • Classes get heavier - you don't always know what your superclass does in its constructor, or how much memory it is going to use. So building an innocent potential light object can be a lot more expensive than you think, and it can change over time if the superclass evolves
  • He encourages the explosion of subclasses. Classloading costs time; more classes cost memory. This may not be a problem as long as you are not dealing with a NetBeans-wide application, but there we had real problems with, for example, slow menus, because the first display from the menu starts mass loading of classes. We fixed this by moving on to more declarative syntax and other methods, but it takes time to fix as well.
  • This makes it difficult to change things later — if you made the class public, replacing the superclass will subclass it — it's a choice that, after you make the code public, you are married to. Therefore, if you do not change the actual functionality of the superclass, you will get much more freedom to change things later, if you do not expand what you need. Take, for example, subclassing JPanel - this is usually wrong; and if the subclass is somewhere public, you will never get a chance to return to this decision. If it is available as JComponent getThePanel (), you can still do it (hint: expose models for components inside your API).
  • Hierarchies of objects do not scale (or their scaling is much more complicated than planning ahead) - this is the classic "too many layers" problem. I will talk about this below, and how the AskTheOracle template can (although it can offend OOP purists).

...

My lesson what to do if you allow inheritance that you can take with salt:

  • Do not show fields except constants
  • Methods must be abstract or final.
  • Calling no methods from the superclass constructor

...

all this applies less to small projects than large ones, and less for private classes than for public

+1
source

Source: https://habr.com/ru/post/887351/


All Articles