3

When dedicating a class to a particular Swing component, is it better to extend that particular component, or construct it internally and provide a reference?

public class Foo extends JComponent{

}

OR

public class Foo{
    public JComponent getComponent(){
    }
}

EDIT

This is what I mean by dedicating

public class Foo{
    private static Foo INSTANCE;

    public static Foo getInstance(){
        if(INSTANCE == null){
            INSTANCE = new Foo();
        }
    }

    public void createAndShowComponent(){
        //do stuff
    }
}

Inside createAndShowComponent(), I create a JComponent with all its components and their respective listeners without exposing the internals of the component I just created.

mre
  • 43,520
  • 33
  • 120
  • 170
  • 1
    Seeing some answers which I wouldn't entirely agree with I must ask you this what do you exactly mean by `dedicating`? .... a class to a particular Swing component. – Boro May 27 '11 at 17:48

6 Answers6

7

+1 for Composition over extension. It makes the API much cleaner since you only expose what methods are important for your new component

meverett
  • 921
  • 5
  • 6
  • +1, the exposure extending a Swing component results in is exactly why I asked this question. – mre May 27 '11 at 17:39
  • 4
    I don't think this is a harden fast rule. If you are making a generic component to be used many places, sure extend whatever JComponent, but if its a stand alone class for a single application, which I argue most are, than it greatly decouples a piece of your application to use composition and creates a clean API – meverett May 27 '11 at 17:51
  • +1. Use Composition when you need composition (most of the time). Use extension when you are implementing a new Component (say, a paginated JTable). The exception here would be extending JApplet (because we need too). – Anthony Accioly May 27 '11 at 17:53
  • 1
    Sorry guys but I do not understand why second option would be the way to go ever. It is like mixing controller Foo with view the returned JComponent. It feels bad for me. If you return the component you still can do whatever you want to with it anyway. I fail to see what it gives you but I see what burden it puts on you. (+/-0) – Boro May 27 '11 at 17:57
  • Boro, you're never going to be able to prevent someone from doing what they're not supposed to. Using composition like this just makes it more difficult. By returning a JComponent they're going to have to cast it to some other Component to perform most of the operations on it. You're just introducing steps to make someone think twice before they do what something they shouldn't. You're also forcing yourself to design/think about what the api for some component really should be instead of exposing how its actually implemented along with the 500+ function calls on swing components. – meverett May 27 '11 at 18:04
  • @meverett thanks for you input. Maybe I have never been in such a situation to observe the benefits. I still see it as more limitation that any help. At least in my experience I often find myself reusing components often when developing an application thus the 2nd option doesn't speak to me. :) – Boro May 27 '11 at 18:08
  • @meverett, could you check out my edit and let me know if this is still the way to go? – mre May 27 '11 at 18:28
  • @mre, its going to partly depend on what you're doing but generally yes that is the approach. Then you would have respective, public methods for whatever callers of this class need exposed. Any listeners, internal components, properties for the given component can all be hidden – meverett May 27 '11 at 18:54
3

I agree with jzd it all depends.

Technically speaking, if you are dealing with GUI in my opinion it is best to build components when you need them, by extending for example JComponent. This way you can simply reuse them.

Personally I would never use the 2nd option in my class. I would only have a class return another component only if there is a very good reason for doing so, e.g. to enable user to modify a button look in your complex calendar component.

For a very simple reason each component class should know what it has this component for, and it should control the view accordingly to what is happening. Thus you would have appropriate methods.

Boro
  • 7,913
  • 4
  • 43
  • 85
2

I would say extending it would be better. Being able to use all its properties and using it like it is that object makes it a lot simpler to use. Just my personal Opinion. Both ways are good.

If you are dedicating the entire class to it. Might as well make it that by inheritence.

RMT
  • 7,040
  • 4
  • 25
  • 37
2

If your object IS a component, than extend it. If not, then use composition.

Trasplazio Garzuglio
  • 3,535
  • 2
  • 25
  • 25
1

It really depends on what you are doing. If you want to include your new class on a JPanel for example, you will need to extend the component. If your code can add the component to the correct place on the GUI, then you don't have to extend it.

jzd
  • 23,473
  • 9
  • 54
  • 76
  • if I wanted to include the component of the class on a `JPanel`, couldn't I just provide an accessor to that component within the class? – mre May 27 '11 at 17:35
  • @mre, you absolutely could like your second example does. But then you will possibly have some extra coupling between your new class and the class that needs the JComponent. There are times where it can greatly simplify your code to extend the component. – jzd May 27 '11 at 17:38
1

I would say none of them. Swing components are very (very) rich and can be customized for visualisation (L&F) and behaviour (events) in any manner. Another point is to create a group of different components and lay them out in a JPanel.

PeterMmm
  • 24,152
  • 13
  • 73
  • 111
  • neither approach? then how do you go about creating Swing components? – mre May 27 '11 at 17:37
  • I won't, i will "configure" them. IMHO Swing programming does'nt mean "extend me", it means "use and configure me". Depends on your use case, but be warned to start to extend Swing beyond trivial things ... – PeterMmm May 27 '11 at 17:48
  • @mre so `dedicating` a class means `creating` a new component? – Boro May 27 '11 at 17:49
  • Do you mean "dedicating" as "data binding" ? I do not understand "dedicating" in this context. – PeterMmm May 27 '11 at 17:53