Skip to main content

Partitioning components into sub-packages

13 replies [Last post]
Anonymous

I would like to discuss the issue of moving larger components from the
swing package to the sub-packages with the larger community. We
discussed this internally back in March (attached) and it was generally
agreed that it should be done. However, when I re-introduced this idea
today we had some disagreement. I would be interested to hear the
opinions of the development community on this issue.

In a nutshell, I want to move a component like say JXTable from

org.jdesktop.swing.JXTable to org.jdesktop.swing.table.JXTable.

Advantages:
-----------
-- Reduces package interdependency
-- Makes it easier reduce the size of the deployment bundle based on usage
-- Developers using a non-trivial component can look at the package (and
package doc) to get the whole story about using that component.
-- Encourages greater use of package private classes.

Disadvantages
-------------
-- This is not how Swing currently does it.
-- Not scalable in the medium term. Small components placed in swing.*
today may need to be placed in swing.foo.* tomorrow.

I've filed this as Issue 43:

https://jdnc.dev.java.net/issues/show_bug.cgi?id=43

I'm looking forward to hearing your thoughts on this matter.

Thanks,

--Mark
[email.eml]
[email.eml]
---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Mark Davidson

On 08/05/2004 06:06 AM, Joshua Marinacci wrote:
> I'll drop in my two cents.
>
> 1) I think that most of the support classes for a complex swing
> component should be in a separate package. I really like having
> javax.swing.tree.

This is the status quo so no action here.

> 2) I think that the most commonly used part of the component (usually
> the component itself) should be in a common package. JTable's various
> support classes are in javax.swing.tree, but JTable itself is in
> javax.swing. For the most common use cases you just need to import
> javaax.swing.* and never worry about the rest of it. I think this is a
> nice balance.

I disagree with the whole "import javax.swing.*" on principle. This
leads to class conflicts (java.util.List vs. java.awt.List). Also, it
makes it difficult to maintain a class since one does not know where the
classes come from.

On the other hand, having all classes in say javax.swing.* doesn't allow
for the separation of components. For example, if a developer only wants
the editor component then they wouldn't need to download the all of
swingx.jar. If we have separate components within sub-packages then sort
of partitioning is possible. Whether people feel that it would be
valuable to partition the components is a separate discussion.

> 3) I think there should be no private methods or member variables, only
> protected. Most of the time someone uses a component without messing
> with the internals, or only uses the approved methods of changing
> behavior (models, renderers, etc).

Uh, isn't OOD about encapsualtion? The interface is public but the
implementation can change.

I don't like protected fields. They are only have a single purpose which
convenient for sub-classes to access the field if the super-class
doesn't have a getter. I think a class is better served with a protected
getter method. That way the implementaion of the field could change -
say that the field is a result of a calculation or from a database or
web service. Perhaps the field could be retrieved from a delegate.

> But sometimes you really really want
> to change something deep down inside the component and you don't want to
> be stymied by a private variable. I've had this happen with the
> HTMLEditorKit several times. (That's actually what made me build my own
> xhtml renderer here on java.net). Messing with internals is dangerous,
> sure, but it shouldn't be impossible. Most people would never use them,
> but it's nice to know they are there. After all, no one overrides a
> protected method accidentally. If someone really wants to hack around
> and completely change the component they should be able to.

I sympathize with your HTMLEditorKit experiences. I've ratholed on
trying to extend it for a day or so. There is *way* too much private
implementation (within basic even!). I believe that HTMLEditorKit is an
extreme example that doesn't allow for extensibility.

> The only disadvantage I see to this is that your JavaDocs become
> polluted with protected items which are only of interest to hardcore
> developers. But perhaps this is an opportunity to write a system that
> produces two sets of JavaDocs, one for the casual users and one for
> hackers. (Could the 1.5 metadata stuff be useful here?)

There have been many requests for this.

Thanks for your input.

--Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

Patrick Wright

>> +1 on smaller packages (fewer public classes)
>
> Careful here. I'm all for separating things into packages carefully
> and using packages to organize things but please be aware that while
> public or protected methods and variables mean backward compatibility
> constraints they also enable flexibility and extensibility.

I am glad to drop the idea of protected access to fields. My main concern
is actually about class and interface organization. javax.swing is
absolutely enormous and it seems that no matter how often I use it, my
poor addled brain keeps forgetting which classes are where, and the list
is so darn long to scroll through.

I realize that package partitioning is largely a matter of taste, and to
some degree of managing interdependencies, but in any case I vote for
relatively smaller package contents than what Swing has currently.

Patrick

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

Mark Davidson

Thanks for your comments.

On 08/05/2004 03:21 AM, Adrian Sutton wrote:
>
> On 05/08/2004, at 7:13 PM, Patrick Wright wrote:
>
>> +1 on smaller packages (fewer public classes)
>
> Careful here. I'm all for separating things into packages carefully and
> using packages to organize things but please be aware that while public
> or protected methods and variables mean backward compatibility
> constraints they also enable flexibility and extensibility.

Agreed.

> Making things package private can make life extremely difficult for
> anyone who wants to extend the capabilities of the components.

One lesson learned from working on J2SE for the past 5 years is that you
can always make a (package) private class/method public. However, once a
method is public then it can never go away. For those keeping score, how
many deprecated methods has Sun removed from Java since 1.0? Answer: 0.

I still think that for the principle of encapsulation, methods should be
as private as possible. They should only become public when a genuine
use case is presented. Speculative generalization is not a good reason.

For JDNC, making methods/classes more visible will not be a heavyweight
process.

> If the
> only reason to make things package private were to make the API simpler
> for people to learn I'd suggest writing better documentation, tutorials
> and highlighting the most important methods in the class javadoc (see
> Apple's API reference documentation for an excellent example of this).

Part of the genesis of this project was to create an easier to use rich
client api. Part of the difficulties that novices have when approaching
Swing it the sheer number of classes and public/protected methods. There
is a large set of the public api in Swing which are implementation
details which allows the component and the ui implementation to
interoperate. These methods are not meant for developer usage.

The idea of moving complex components into subclasses is so that
classes/methods which are only public for the sake of implementation can
remain private. I believe that this will simplify the api when a
developer first approaches JDNC.

Writing better documentation and tutorials would be a great thing to
have. However, I'm doubtfull that it will happen automatically within an
open source project. Filtering/highlighting the javadoc is a great
option and there have been proposals within Sun about solving this problem.

> It is definitely important to make the simple things simple but it's
> also important to make difficult things possible.

You can always "drop down to Swing" to make the difficult things possible.

Simple things = JDNC
Difficult things = Swing.

Thanks,

--Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

Adrian Sutton

> One lesson learned from working on J2SE for the past 5 years is that
> you can always make a (package) private class/method public. However,
> once a method is public then it can never go away. For those keeping
> score, how many deprecated methods has Sun removed from Java since
> 1.0? Answer: 0.

One lesson I've learned from working with J2SE for the past 5 years is
that too many Sun Java engineers think like that. :) It is incredibly
annoying to be give a superb library like Swing only to find that you
can't add in the one little bit of extra functionality you need because
everything's package private, so you either use reflection to get
access to stuff you're not meant to access, rewrite everything yourself
or submit an enhancement request and delay the product by up to 18
months when a new version is available that may or may not actually
make those things protected.

Having said that, I agree that you should encapsulate as much as
possible - but you have to be aware of the fact that people will want
to build on top of the library as well as just using it in their
application.

> For JDNC, making methods/classes more visible will not be a
> heavyweight process.

This is the saving grace. As long as it's possible to just fork JDNC
and change things around to suit a particular project's needs then it
should be okay. I would still suggest planning for people that will
want to extend JDNC's abilities and that shouldn't generally require
excessive amounts of public API.

> The idea of moving complex components into subclasses is so that
> classes/methods which are only public for the sake of implementation
> can remain private. I believe that this will simplify the api when a
> developer first approaches JDNC.
>
> Writing better documentation and tutorials would be a great thing to
> have. However, I'm doubtfull that it will happen automatically within
> an open source project. Filtering/highlighting the javadoc is a great
> option and there have been proposals within Sun about solving this
> problem.

Restricting the abilities of JDNC doesn't seem like a good way to
simplify things. Filtering the javadoc seems to be the most obvious
solution and it's pretty trivial to do, simply include only public
methods in the "simple javadoc" and also include protected methods in
the "advanced javadoc". Splitting things into separate packages would
still be required but methods that are required to build upon the
library to be protected instead of package private and things that are
internal to the class should be private.

>> It is definitely important to make the simple things simple but it's
>> also important to make difficult things possible.
>
> You can always "drop down to Swing" to make the difficult things
> possible.
>
> Simple things = JDNC
> Difficult things = Swing.

The down side to this is that you then throw out all the advantages of
JDNC as soon as you want to do something more complex. I'm lazy so I
like to leverage existing code when I can.

> Thanks,
>
> --Mark

Regards,

Adrian Sutton.

----------------------------------------------
Intencha "tomorrow's technology today"
Ph: 38478913 0422236329
Suite 8/29 Oatland Crescent
Holland Park West 4121
Australia QLD
www.intencha.com
[PGP.sig]

rbair
Offline
Joined: 2003-07-08
Points: 0

> > One lesson learned from working on J2SE for the
> past 5 years is that
> > you can always make a (package) private
> class/method public. However,
> > once a method is public then it can never go away.
> For those keeping
> > score, how many deprecated methods has Sun removed
> from Java since
> > 1.0? Answer: 0.
>
> One lesson I've learned from working with J2SE for
> the past 5 years is
> that too many Sun Java engineers think like that. :)
> It is incredibly
> annoying to be give a superb library like Swing only
> to find that you
> can't add in the one little bit of extra
> functionality you need because
> everything's package private, so you either use
> reflection to get
> access to stuff you're not meant to access, rewrite
> everything yourself
> or submit an enhancement request and delay the
> product by up to 18
> months when a new version is available that may or
> may not actually
> make those things protected.
>
[snip]
> > For JDNC, making methods/classes more visible will
> not be a
> > heavyweight process.
>
> This is the saving grace. As long as it's possible
> to just fork JDNC
> and change things around to suit a particular
> project's needs then it
> should be okay. I would still suggest planning for
> people that will
> want to extend JDNC's abilities and that shouldn't
> generally require
> excessive amounts of public API.

Absolutely agreed! With both points! Yes, making a field/method protected or public later is easier than making it private (as in, that's impossible). In the case of JNDI, I think its a non-issue since its OSS and you can fork.

The package structure of a project is really an interesting question, and one that I've never heard anybody with any authority lay down. I haven't even heard much in the way of religious wars on the subject. It seems like package structure science is still pretty medieval. Hasn't any large corporation (US dept. of defense, IBM, Microsoft, SUN, etc) done studies on this kind of thing before? What is the standard OSS/Apache approach to package partitioning?

Is partitioning a GUI platform any different in theory or practice than an XML parser or an HTTP client kit?

tetsuo

It's not exactly the discussion here, but one thing I think we should do is to
keep component and test files in separate folder trees, say

/swingx
/src
/java
/org/jdesktop/swing
JTreeTable.java
JImagePanel.java
...
/test
/org/jdesktop/swing
JTreeTableTest.java
JImagePanelTest.java
...

so that it is easier to build the release package without the test classes, and
easier to understand the codebase. I believe it already was in the plans for the
future, but I think it should be done as soon as possible.

Tetsuo

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

tetsuo

Ooops, sorry, I haven't updated the code from the CVS recently, the tests are
already there :)

tetsuo wrote:

> It's not exactly the discussion here, but one thing I think we should do
> is to keep component and test files in separate folder trees, say
>
> /swingx
> /src
> /java
> /org/jdesktop/swing
> JTreeTable.java
> JImagePanel.java
> ...
> /test
> /org/jdesktop/swing
> JTreeTableTest.java
> JImagePanelTest.java
> ...
>
> so that it is easier to build the release package without the test
> classes, and easier to understand the codebase. I believe it already was
> in the plans for the future, but I think it should be done as soon as
> possible.
>
> Tetsuo
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
> For additional commands, e-mail: jdnc-help@jdnc.dev.java.net
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

Patrick Wright

+1 on smaller packages (fewer public classes)

Some of the current Swing packages are enormous and for that reason,
confusing and hard to learn. The javax.swing package has almost everything
you need, but then I never remember which special-purpose interfaces or
abstract or default classes are actually packaged in .tree, .table,
wherever...

IMO, the package structure should be cohesive and predictable, and smaller
packaging leads to this. And, as a rule, if one finds that one is always
going to the JavaDocs to remember what is in which package, there is a
problem. Obviously javax.swing can't be changed, but would be nice not to
make it any worse.

Regards
Patrick

> I would like to discuss the issue of moving larger components from the
> swing package to the sub-packages with the larger community. We
> discussed this internally back in March (attached) and it was generally
> agreed that it should be done. However, when I re-introduced this idea
> today we had some disagreement. I would be interested to hear the
> opinions of the development community on this issue.
>
> In a nutshell, I want to move a component like say JXTable from
>
> org.jdesktop.swing.JXTable to org.jdesktop.swing.table.JXTable.
>
> Advantages:
> -----------
> -- Reduces package interdependency
> -- Makes it easier reduce the size of the deployment bundle based on usage
> -- Developers using a non-trivial component can look at the package (and
> package doc) to get the whole story about using that component.
> -- Encourages greater use of package private classes.
>
> Disadvantages
> -------------
> -- This is not how Swing currently does it.
> -- Not scalable in the medium term. Small components placed in swing.*
> today may need to be placed in swing.foo.* tomorrow.
>
> I've filed this as Issue 43:
>
> https://jdnc.dev.java.net/issues/show_bug.cgi?id=43
>
> I'm looking forward to hearing your thoughts on this matter.
>
> Thanks,
>
> --Mark
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
> For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

Adrian Sutton

On 05/08/2004, at 7:13 PM, Patrick Wright wrote:

> +1 on smaller packages (fewer public classes)

Careful here. I'm all for separating things into packages carefully
and using packages to organize things but please be aware that while
public or protected methods and variables mean backward compatibility
constraints they also enable flexibility and extensibility.

Making things package private can make life extremely difficult for
anyone who wants to extend the capabilities of the components. If the
only reason to make things package private were to make the API simpler
for people to learn I'd suggest writing better documentation, tutorials
and highlighting the most important methods in the class javadoc (see
Apple's API reference documentation for an excellent example of this).
It is definitely important to make the simple things simple but it's
also important to make difficult things possible.

Regards,

Adrian Sutton.
----------------------------------------------
Intencha "tomorrow's technology today"
Ph: 38478913 0422236329
Suite 8/29 Oatland Crescent
Holland Park West 4121
Australia QLD
www.intencha.com
[PGP.sig]

Ronald Tetsuo Miura

I'd agree with partitioning the API in subpackages, but only for complex components or sets of related components. Something like swing, that has javax.swing.table and javax.swing.tree packages. The difference would be that in swing, the concrete component (JTree, JTable) is in the main package (javax.swing), only the extension interfaces and default implementations are separated in the subpackage. But I think that tight-related components should remain in the same package. If JXTable has its own subcomponents, tight-related components, extension interfaces, and default implementations, it should be moved to a separated package, IMHO (sorry, I haven't played much with it, I don't know :)).

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

Joshua Marinacci

I'll drop in my two cents.

1) I think that most of the support classes for a complex swing
component should be in a separate package. I really like having
javax.swing.tree.

2) I think that the most commonly used part of the component (usually
the component itself) should be in a common package. JTable's various
support classes are in javax.swing.tree, but JTable itself is in
javax.swing. For the most common use cases you just need to import
javaax.swing.* and never worry about the rest of it. I think this is a
nice balance.

3) I think there should be no private methods or member variables, only
protected. Most of the time someone uses a component without messing
with the internals, or only uses the approved methods of changing
behavior (models, renderers, etc). But sometimes you really really want
to change something deep down inside the component and you don't want to
be stymied by a private variable. I've had this happen with the
HTMLEditorKit several times. (That's actually what made me build my own
xhtml renderer here on java.net). Messing with internals is dangerous,
sure, but it shouldn't be impossible. Most people would never use them,
but it's nice to know they are there. After all, no one overrides a
protected method accidentally. If someone really wants to hack around
and completely change the component they should be able to.

The only disadvantage I see to this is that your JavaDocs become
polluted with protected items which are only of interest to hardcore
developers. But perhaps this is an opportunity to write a system that
produces two sets of JavaDocs, one for the casual users and one for
hackers. (Could the 1.5 metadata stuff be useful here?)

Okay. off the soap box now.

- Joshua

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

Ronald Tetsuo Miura

>1) I think that most of the support classes for a complex swing
>component should be in a separate package. I really like having
>javax.swing.tree.

+1

>2) I think that the most commonly used part of the component (usually
>the component itself) should be in a common package. JTable's various
>support classes are in javax.swing.tree, but JTable itself is in
>javax.swing. For the most common use cases you just need to import
>javaax.swing.* and never worry about the rest of it. I think this is a
>nice balance.

+0.5

Modern IDEs (should) add imports automatically. I never worry about imports either, I just press ctrl+space :)

>3) I think there should be no private methods or member variables, only
>protected. Most of the time someone uses a component without messing
>with the internals, or only uses the approved methods of changing
>behavior (models, renderers, etc). But sometimes you really really want
>to change something deep down inside the component and you don't want to
>be stymied by a private variable. I've had this happen with the
>HTMLEditorKit several times. (That's actually what made me build my own
>xhtml renderer here on java.net). Messing with internals is dangerous,
>sure, but it shouldn't be impossible. Most people would never use them,
>but it's nice to know they are there. After all, no one overrides a
>protected method accidentally. If someone really wants to hack around
>and completely change the component they should be able to.

NO private members is a little too much :)
I think that a component should be designed to have a coesive public interface, and protected members to predicted extension points. If you put utility methods as protected, they will only pollute the interface and unnecessarily expose its internals.

>The only disadvantage I see to this is that your JavaDocs become
>polluted with protected items which are only of interest to hardcore
>developers. But perhaps this is an opportunity to write a system that
>produces two sets of JavaDocs, one for the casual users and one for
>hackers. (Could the 1.5 metadata stuff be useful here?)

It would be nice if it were just here, for the development team that need to know the internals. To end-users (end-developers?), simplicity and coherence are more important.

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

rameshgupta
Offline
Joined: 2004-06-04
Points: 0

>I want to move a component like say JXTable from
>org.jdesktop.swing.JXTable to org.jdesktop.swing.table.JXTable.
>
>Advantages:
>-----------
>-- Reduces package interdependency
>-- easier to reduce the size of the deployment bundle based on usage
>-- Developers using a non-trivial component can look at the package >(and package doc) to get the whole story about using that component.
>-- Encourages greater use of package private classes.
>
>Disadvantages
>-------------
>-- This is not how Swing currently does it.
>-- Not scalable in the medium term. Small components placed in swing.*
>today may need to be placed in swing.foo.* tomorrow.

This last point is the Achilles’ heel of this strategy, because it makes the api brittle -- Changing the package of a class from swing.* to swing.foo.* after it has been in use for a while will break all applications that use that class.

I also don't believe that this strategy reduces package interdependencies -- It might actually increase them. For example, JXTreeTable will depend on swing.*, swing.tree.*, swing.table.*, swing.treetable.*, and others. Also, if JXTree, JXTable,and JXTreeTable are in the same package, then JXTreeTable is more likely to use package private classes than when they are in separate packages.

Reducing the size of a deployment bundle is orthogonal to the issue of changing the package structure. The issue here is one of partitioning classes into jar files depending on usage. Depending on the granularity of the partition, this can be a combinatorial nightmare. I think the current partitioning between swingx, jdnc_api, and jdnc_markup is quite reasonable. Do people really want to download a separate table.jar, tree.jar, treetable.jar, and so on? Where would you put data, highlighters, filters, and so on?

Ramesh