Every time I think I am really making progress in understanding object oriented programming, I run into something that makes me have to go back and start all over again... This time its "subclassing".

I believe that I understand the basics inheritance and overriding, but when I start to develop a "structure" for an application, I get lost. If I want to created a window on the screen, I would use Main method, to allow this code to be runnable. I would also use a constructor to initialize my application. Then I would use a JFrame, JPanel and paintComponent to do the actual work of building and displaying my application. But the question always seems to be, "What is the best approach?" OR "Which approach is the best with respect to Object Oriented Programming?"

So, I could put almost everything inside the main() method, but that is obviously not very OOP. I could have the main() method call the constructor and then put the define the JFrame and JPanel objects in that method. I could extend the whole class with "extends JFrame" or perhaps better "extends JPanel" but its not intuitively obvious how that helps me or makes the application "more OOP".

So I have all these "tinkertoy" parts and I know how one connects to the other, but I just don't seem to get the "why" part, or how to know what approach to take.

I have read lots of tutorials, but its just not sinking in.


At an overview level, the object-oriented solution is the one that divides the problem into its natural components. Typically you'll have a natural division between getting the work done and talking to the customer. In the real world, we don't let the customer call the developer directly, we have the customer call tech support and tech support gets their problem solved. The GUI is tech support: it puts up the interface for the customer, and (from the customer's point of view) it solves the problem. Now, in the real world, we usually don't let tech support bug the developers, either. There's usually some interface (a knowledge base) and a management layer that they'd have to go through if they want to talk directly. The analogy begins to break down here, but it gets us this far:

Customer talks to tech support = user manipulates GUI
tech support -> passes the problem on to a solver = GUI calls some method
tech support <- gets a response = method return
tech support delivers solution = GUI displays return

So the GUI's job is to provide an interface, and to pass the data to the classes that do the actual work. The structure would be

       /    \
 worker <-> GUI
 driver        \
    |           stuff the worker
(stuff the      classes don't know about
GUI doesn't 
know about)

There are a few ways to do this. Often I'll have the GUI extend JFrame or JPanel, if there's just one window that I'm dealing with. If I'm spawning multiple windows, I keep the separate as a sub-driver class, coordinating traffic among the windows and passing messages up to the driver.
The main thing that the GUI should do is to be the only place anything else in the program goes for io issues. If someone wants to display something, they call a method in GUI, they never call lower in that hierarchy. That's what makes this an OO solution: from the rest of the program's viewpoint, all they see is a GUI object with methods that they can call, they know nothing and care less about what's below that. Practical advantage: this means that if you change something in the GUI, you don't have to change anything on the left side of the tree, you only have to modify the access methods in GUI.