Introduction:
Among the many useful classes provided by JBuilder is one called FontChooser which
makes it easy to display a dialog box from which a user can select a font.
In a recent project in which I used FontChooser, I encountered some limitations with
this class. I wished to change its default behavior in two ways by:
- changing
the default size of the dialog box, and
- adding a checkbox with which the user
could indicate a default setting.
One might think that the solution to this would be to derive a new class from
FontChooser, but things are not as simple as that. First of all,
FontChooser is not a Dialog, nor even a Panel; it's just an Object. When
the user makes the call to FontChooser.showDialog(), an instance of a
FontChooserDialog is created to display the information represented by the
FontChooser. There are two problems here: first, FontChooserDialog
is a non-public class defined in FontChooser.java which means that access to it
is restricted to members of the same package, com.borland.dbswing; second, even
if we could derive from the FontChooserDialog class, the FontChooser class
provides no way to assign it as its dialog.
This note will demonstrate a loophole in the member access settings in
FontChooser.java that let me workaround these limitations and provide the
functionality I needed.
Caveats:
The example code for this note was written and tested with JBuilder 9
Enterprise. It is important to remember that there is no guarantee that
this code will work with future versions of JBuilder as Borland may change
com.borland.dbswing.FontChooser at some point in the future.
As software source code copyrighted by Borland, there are licensing issues
and limitations with respect to using FontChooser.java. Please check the
license terms that come with your version of JBuilder before redistributing any
program or code based on the specific code provided here. The
MyFontChooser.java code derived from FontChooser.java is meant solely as an
example of how to workaround member access settings in certain situations.
The Sample Program:
The source code (https://codecentral.borland.com/codecentral/ccWeb.exe/listing?id=21058) for a sample Java application, the
FontChooserDemoApplication, demonstrates how to use a class called MyFontChooser
that is derived from FontChooser. There's not much to the program:
run it and choose the Options | Fonts... menu item to see the modified font
display dialog.

How It Works:
MyFontChooser.java overrides the FontChooser.showDialog() method to apply a
"PreferredSize" property to the dialog box and to apply the
"Reset fonts to defaults" functionality if the checkbox is selected
when the OK button is pressed. Rather than cut and paste functionality
from the FontChooserDialog class defined in FontChooser.java, I just use this
class.
But what a minute... didn't I say earlier that deriving from the FontChooser
class wouldn't work?
Well that's true... except if the MyFontChooser class is defined within the
same package as FontChooser, namely com.borland.dbswing. Just because this
package comes from somewhere else, there's nothing to prevent the compiler from
being fooled that code that I write is part of that package.
Most of the code written is in showDialog() and most of that simply
duplicates functionality in the base class version.
There are a few differences because of the new functionality added. The
rest of the differences are the result of using accessor functions to obtain
private members in the base class. For example, code that reads
if (availableFonts != null) {
dialog.setAvailableFonts(availableFonts);
}
in the base class version of the function, needs to be replaced by
Font[] availableFonts = getAvailableFonts();
if (availableFonts != null)
{
dialog.setAvailableFonts(availableFonts);
}
in the derived class.
See MyFontChooser.java for the rest of the details.
See the jMenuItemFonts_actionPerformed
method in FontChooserDemoFrame.java for sample code on using this class and how
to set its preferred size.
Also, don't be fooled by the "frame" and
"setFrame()" members in FontChooser. The "frame"
is merely used as a window relative to which the FontChooserDialog is
positioned. Take a look at showDialog() and you'll see that if you prefer
to, say, always have the dialog centered in the screen, then the dependency on
the "frame" could easily be removed.
Summary:
This example was not presented as a recommended way of working around member
access restrictions placed by a base class but as a reminder that the member access constructs in the programming
language are really guidelines as to how the members are to be used.
Unless a member is labeled "private", it can be accessed by using
the same trick I used for dbswing (i.e., by deriving a new class within the same
package).
Don't confuse member access rules with security; for example, user name and
password credentials stored as non-private members of a (non-final) class can be
read using this technique.
A better solution for attaining the functionality I want added would be to
have the class vendor, Borland, make changes to FontChooser and
FontChooserDialog that let developers customize them (hint, hint). In
particular, this would include changing FontChooserDialog to public (so that it
can be derived from) and changing FontChooser so that the showDialog() can
display an assigned dialog (derived from FontChooserDialog).
Questions, comments, and suggestions may be sent to the
author at [email protected] ; use the title of the article or the words BDN
Article in the email subject.
Connect with Us