JBuilder 1.0 applications will compile and run despite the following new
deprecation warnings:
All existing borland.sql.dataset.QueryDescriptor objects are now deprecated
because the final parameter is now an int instead of a boolean.
To maintain existing behavior, use
DataSetLoadOption.LOAD_ALL_ONCE
instead of false, use
DataSetLoadOption.LOAD_ASYNCHRONOUSLY.
dataset.setBinaryStream() is deprecated, use dataset.setInputStream instead.
Variant.BINARY_STREAM is deprecated, use Variant.INPUTSTREAM instead.
The SelectableTextItemPainter class has been deprecated. A stub class
still exists which extends Object instead of TextItemPainter. Code which
instantiates a SelectableTextItemPainter will still work (uses the
deprecated stub class), but should eventually be changed from:
... new SelectableTextItemPainter(...)
to:
... new SelectableItemPainter(new TextItemPainter(...))
setScrollPosition(Point) is deprecated.
setAsInt() is removed from the Variant, ByteFormatter, IntegerFormatter and ShortFormatter
classes. The getAsInt() method on Variant that can be used for similar purposes.
Package changes
---------------
1. COM.objectspace.JGL is now com.objectspace.JGL in the new JGL version 3.1 library.
2. Code casting existing JBCL 1.0 components may need to be re-cast when using
JBCL 2.0 components due to the class hierarchy switch extending JComponent
instead of Panel.
3. JDBC-specific classes in borland.JBCL.dataset have been moved to a new
package, borland.sql.dataset. Separating general dataset functionality
from a specific provider/resolver implementation will simplify future
support of multi-tier designs and other provider/resolver
implementations. The classes moved include Database, QueryDataSet,
ConnectionDescriptor, QueryDescriptor, and QueryResolver. JBuilder
projects that use these classes will have to be edited and recompiled.
These are the changes you must make:
- When components in the classes listed are named with explicit package
references, you will see an error like "Cannot access class
borland.JBCL.dataset.ConnectionDescriptor...". To resolve this
error, change the package name.
- When the package name is implicit, the error will be something like
"Class Database not found...". To resolve this, add an import
statement for borland.sql.dataset.*;.
Project changes
---------------
JBuilder 2.0 will read in projects created by JBuilder 1.0x and convert them to the
JBuilder 2.0 JPR format. When you open an old project file, JBuilder 2.0 will make a
backup copy of it to a file with the form: oldname-v1.0.~jp
References to libraries found in the old project that have new counterparts will be
automatically mapped to the newer version (JBCL to JBCL2, JGL1 to JGL 3.1, etc).
If there is a library found that does not have a newer counterpart in JBuilder
(e.g., some other 3rd party library), JBuilder 2 will preserve the reference if the
library still exists and build dependency files for it.
Many changes have happened between JBCL1 and JBCL2 (JBCL2 is based on the Swing (JFC)
Architecture and uses a new version of JGL which isn't backwards compatible with the
earlier versions). If you do not want to upgrade your projects to use JBCL2, it is
recommended that you use JBuilder 1.0x to maintain your older projects with JBCL1.
There are two topics in the Help System which will help you understand the project changes
in JBuilder 2.0: The "Setting project properties" topic in the "Creating and managing projects" chapter of Getting Started with JBuilder and the "Problems compilng imported projects" topic
in the "Compiling Java programs" chapter of Building Applications with JBuilder.
Formats in text files
---------------------
Because of changes in JDK formatting, JBuilder 2.0 may not be able to read text
data files written with JBuilder 1.0x if they contain Float, Double, BigDecimal,
or date/time columns without user-defined export masks. The error message "Invalid
format for <column_name> column at row 1" points to this problem. To resolve it,
set the exportDisplayMask property of the column to match the contents of the text
file. (The export mask also governs import.) For example, the mask to read a
Timestamp column is "yyyy-MM-dd HH:mm:ss.S".
If a column that you want to define an export mask for is not persistent, you will
have to define a Column object; set its columnName, dataType, and exportDisplayMask
properties; and use dataset.setColumns() to associate it with its DataSet. This
isn't hard, but it can be tedious, and might affect the order of columns in the
dataset. An alternative is to edit the text file's schema file carefully, adding
the export mask to the end of the column's FIELD definition. One complication here
is that some characters in the mask are represented in unicode; for example, the
The Provider and Resolver abstract classes have slightly different method signatures, the
methods overridden in QueryProvider, ProcedureProvider, QueryResolver, ProcedureResolver
are changed accordingly.
QueryResolver and ProcedureResolver now have a database property. If it's
not set when you try to resolve, the operation will fail with
a DataSetException "Cannot resolve data, since Database property is not
set on Resolver".
DataSets
--------
The borland.sql.dataset.DataSetLoadOptions class has been renamed to Load, and the constants
defined in it have also been simplified. They are now Load.ALL, Load.ASYNCHRONOUS,
Load.AS_NEEDED, and Load.UNCACHED.
In the StorageDataSet class, the setColumns() method no longer clones
the columns passed to it. This change saves a little memory and makes
changing properties of bound columns simpler (though they can only be
changed when the data set is closed). It should have no effect on existing
applications unless they add the same columns to more than one data set.
To conform to standards, ReadWriteRow's setByte() method takes a byte
and its setShort() method takes a short. They used to take ints.
StorageDataSet's setUpdatable() and isUpdatable() methods, which were
public but documented as internal, have been removed. There is no
simple way to determine if a table can be updated.
Database TransactionIsolation constants have been deleted; use the
constants in the Connection class instead.
The DataFile interface in JBCL's dataset package has an additional
method. To pass syntax checking, classes that implement DataFile must
define the new method.
The UseTablename property for Database is false by default. In JBuilder 1.0,
it was true by default. Note that DataGateway requires this property to be
true to work with Paradox and dBASE tables.
QueryDataSet.getParameterRow() now returns a ReadWriteRow, instead of a
ParameterRow. If you have code which declares a ParameterRow and assigns
it to a call to getParameterRow(), you must change its type to be
ReadWriteRow instead of a ParameterRow.
The FieldView, ListView, GridView, and TreeView classes (JBCL components
that support edit-in-place) now throw an Exception in the endEdit(...)
methods. Any code that directly calls one of these methods now must
surround the call with a try...catch block, or it must use the new
safeEndEdit(...) methods.
JBInit method
-------------
The jbInit method is now declared to be "private" rather than "public". Code
which extends a class containing a jbInit method built under JBuilder 1.0
Professional or Standard will encounter a compile error if components are
added to the child class. To fix this problem, edit the superclass to make
its jbInit method private.
JBCL changes
------------
ListControl and TreeControl are a subclass of the java.awt.Container. The methods remove(int) and removeAll() are in java.awt.Container. These methods tell the component to remove the specified subcomponent (or all of them). In ListControl and TreeControl, JBuilder 1.0
overrode these methods (errantly) to remove the data items. JBuilder 2.0 will not override
these methods.
GridView, ListView and TreeView no longer have any inherited implementation for the following methods. See methods available in JScrollPane for workarounds:
int getScrollbarDisplayPolicy()
int getHScrollbarHeight()
int getVScrollbarWidth()
java.awt.Adjustable getVAdjustable()
java.awt.Adjustable getHAdjustable()
E. Using Swing and JBCL Components
-------------------------
Heavyweight vs. Lightweight
The Swing (JFC) Architecture introduces the concept of heavyweight and lightweight components.
A heavyweight component uses a native peer to paint, but a lightweight component handles
painting itself and has no external dependency. This difference leads to some interesting
side effects at runtime with regard to painting. JavaSoft has also changed how events are
handled (e.g. mouse events) with lightweight components and there are some differences in
Z-ordering as well.
A good reference on this topic is: "Mixing heavy and light components" by Amy Fowler on the
JavaSoft web page. See http://www.javasoft.com/products/jfc/swingdoc-current/mixing.html.
As a general rule of thumb it is a good idea to avoid mixing heavyweight and lightweight
components in the UI.
Because JBCL2 uses the architecture from JFC in many places, you may encounter some of the
heavyweight vs. lightweight issues. Where ever possible, lightweight components were used but
there are some cases where there was no appropriate JFC component to use (or there was missing
functionality or support in the current JFC which could limit our customers). In those cases
the components are still heavyweight. The following is a list of JBCL2 controls split between
heavyweight and lightweight.
Heavyweight:
CheckboxControl
CheckboxPanel
ChoiceControl
LabelControl
LocatorControl
TextAreaControl
TextFieldControl
PopupPickListItemEditor
Lightweight:
ButtonControl
FieldControl
TextControl
ListControl
GridControl
ImageControl
TransparentImageControl
ButtonBar
ShapeControl
StatusBar
TreeControl
BevelPanel
GroupBox
SplitPanel
TabsetView
TabsetPanel
If you setXXX(), (e.g., setBackground()or setText()), in a Swing or a Swing based component and don't see the change at runtime, you may have to add a repaint() call. In many cases, Swing
does not call repaint() when a property is set. This is usually a problem for properties done via user-entered code (e.g., in an event) and should not show up in the UI Designer. In your code, add a call to repaint(). If you are setting multiple properties, set them all and do one repaint() instead of a repaint() for each.
If you are using Swing (JFC) in an applet, your applet must extend from JApplet.
Certain Swing components (such as JButton) expose 2 properties to represent their textual
label: 'text' and 'label'. JBuilder automatically uses the 'text' property when such a component is added to the UI Designer. However, the 'label' property is also available in the Inspector, and using this 'label' property will generate a compiler warning, since the setLabel() method has been deprecated. Until Swing components hide their deprecated properties in their BeanInfo, it is a good idea to avoid using the 'label' property in these particular components.
F. Deploying Applets and Applications
-------------------------------------
JBuilder 2.0 adds the ability to specify a particular JDK to use with a project. Choosing
a particular JDK will also switch the version of AppletViewer used by that project to the
one that comes with the selected JDK. Some JDK 1.02 applets won't run correctly from within
the IDE due to a problem with the version of AppletViewer that comes with JDK 1.02.
That version of AppletViewer assumes that it is being launched from the same directory as
the HTML file containing the Applet. JBuilder (and subsequent versions of AppletViewer)
uses the CLASSPATH to allow for Applet launching to be more flexible.
If in deploying your application or applet, images used by JBCL are not added to the archive,
you may want to keep those resources in a package of their own. The Deployment Wizard only deploys "solid" instances of classes found in the code and will miss resources like images and other items that are loaded dynamically (e.g., via Class.forName() ). The best solution is to keep those resources in a package of their own. For example, the images used by JBCL are in the package borland.jbcl.control.image. Add that package to your project via File | Open/Create
and it will appear in the list of files in the Deployment Wizard. Selecting a package in the list of files to deploy will place all files in that package into the archive.
If images used by your classes don't get added to the archive, place your images in their own package as described in the above tip or add them to the project. If you add them to your project, we suggest adding a project folder to store the images and minimize clutter in the Navigation Pane.
If your images don't show up at runtime, it may be because the images are not in the proper location relative to the class file that uses them. This often happens when you are storing
the images with the source code. Place the images in your project and when you build the
project JBuilder will copy them to the appropriate location on your OutPath so the images
will be available at runtime.
Deploying Look and Feel with the Deployment Wizard
Many Look and Feel classes are loaded dynamically which means the Deployment Wizard cannot find them as it builds the archive. If at runtime you find there are missing Look and Feel
classes, possible solutions are:
1. Add the appropriate Look and Feel archive from the \redist directory to your deployment set. If the problem is only limited to Look and Feel classes, add the appropriate Look and Feel package to your project. Once the package is in the project the Deployment Wizard will add all classes from that package to your archive.
2. Locate the missing classes in swingall.jar and add them to your archive using WinZip or some other archive management tool.
3. Deploy swingall.jar with your applet or application.
4. (Applets Only) Use the Activator Plug-in from Javasoft. This Browser PlugIn includes swingall.jar and provides JDK 1.1 functionality regardless of which browser you are using.
G. Known Problems
-----------------
G1. Visual Design Tools and JavaBeans
-------------------------------------
If you ever see one of your components as a red box showing its class name at the top, you are in a situation where JBuilder has not been able to create an instance of that component for the designer. This is referred to as "The Red Bean". Some reasons you might see a Red Bean are:
1) That class has no default (parameterless) constructor
2) That class threw exceptions on every constructor JBuilder tried
3) That class is the 'this' object and it extends an abstract class
Items (1) and (2) can be fixed only by supplying a proper default constructor (or subclassing that class in order to provide a default constructor). Item (3) is more complex. Whenever JBuilder needs to instantiate an object to be the "this" object, it encounters a paradox. How can it instantiate the object you are designing? To circumvent this problem, JBuilder will always attempt to instantiate the superclass of the "this" object. In the event the superclass is abstract, it cannot be instantiated. Since it is clear developers cannot use the Red Bean in such cases, JBuilder has an escape mechanism.
In the file lib\jbuilder.properties, you will find a line that looks like:
This line says that whenever you are forced to instantiate com.sun.java.swing.JComponent (which is abstract), you will find an acceptable concrete proxy class for it in borland.jbcl.control.JComponentProxy.
You may add your own proxy objects using this pattern. The proxy class does not need to do anything other than:
1) Extend the abstract class in question
2) Be concrete (i.e. not be declared abstract itself)
You may also want to examine the source for forland.jbcl.control.JComponentProxy to see a working example.
If you delete a subcomponent in a DataModule (such as selecting it in the Component Tree
and pressing DEL), the extra "getter" method which was generated to expose this subcomponent
will not be deleted. You will have to delete this method manually. (12876)
Selecting "Activate Designer" from the "Menu" folder in the Structure pane doesn't always display your menu. The workaround is to activate the designer from a menu node. (13352)
Sometimes undo in the designer will undo more than the last operation. If this happens,
use re-do to restore the extra undone operations. (13349)
There is a known problem that if you are using a JTabbedPane in designing one component, go to design a second component, and then go back to the first, the tabs of the TabbedPane will display multiple times. The workaround is to dirty the source code and go back into the UI Designer, forcing a re-paint.
JdbNavToolBar may be shown in the wrong position in design mode, however, it will be in the
correct position when the application is run. (11464)
JdbToggleButton, JdbCheckBox, and JdbRadioButton don't display "true" values when on the first row after initially opening the dataSet. Navigating in the dataSet fixes this. (13072)
G2. The jbInit Method
---------------------
The contents of the jbInit method are arranged as follows:
1. Subcomponent initial property settings are in order by subcomponent and
then by property. (Properties are ordered as defined by the BeanInfo class,
or as the getter methods are found through reflection). Event listener
addXxxListener calls are also placed here, ordered as if they were
property settings.
2. Additional method calls for wiring subcomponent relationships are created
by the designers. These include container.add(component, constraints)
calls as well as menu and data module assembly. Generally these are ordered by
subcomponent, and then child (Z) order.
Any hand rearranging of the above methods will likely be undone the next
time a designer manipulates something nearby. The changes won't hurt
anything, but you can't rely on them remaining.
Additional hand-coded method calls or other statements can be placed
anywhere within the jbInit method, but it is recommended that they be
placed at the end. They may get moved by the designers, but this is much
less likely to happen if they are at the bottom.
G3. Database
------------
It is advisable to compile a DataModule whenever you create one or modify one, since
JBuilder generally needs its class file to instantiate the DataModule properly. (12980)
Be sure to explicitly call the closeConnection() method of on your Database
objects when you are through with them or you will leave orphaned JDBC
connections on your server.
If you get the error message "No suitable driver" when testing the database
connection in the Inspector, and your URL is specified correctly, it could mean
that the IDEClassPath doesn't contain any driver class files. The IDEClassPath
is used by the UI Designer to locate class files. Modify IDEClassPath in
jbuilder.ini to include the location of the driver classes.
Additional connectivity troubleshooting information is available in online
help. Look under Troubleshooting JDBC Connections in the Database Application
Developer's Guide.
Providing problem: Query is read-only, even though the table on the server has a
unique row id. When you try to modify the data set, you get a message that
reports: "Cannot be saved. None of its updatable columns have a table name."
This may mean that the driver does not support one or more of the MetaData functions
used by JBCL. The solution is to provide some metadata manually.
For more information on MetaData, please refer to the metaDataUpdate Property Editor
entry in the Master Index of the Help System and Working with Columns in the Database Application Developer's Guide.
To make a query updatable:
- If UpdateMode is ALL_COLUMNS (default), set tableName on queryDataSet.
- If the application has a QueryResolver, and UpdateMode is KEY_COLUMNS, set rowId
on the columns used as an index to the table.
- If you have a BLOB column, set the searchable property to false. This means
never use this column in a WHERE clause of an update query. Most databases
don't support this for BLOBs.
G4. Database - Resolving
-----------------------
While troubleshooting resolution problems, keep in mind that it is not
necessarily columns that you have edited that are causing an error. For
instance, the problem might stem from columns which are included in the
WHERE clause of the update query.
If you get a message to the effect that no rows were affected by the update
query, it could just mean that someone modified the original row, causing
the WHERE clause to fail. Use QueryDataSet.refetchRow() to get the original
row from the server. If it is not the case that the original row has been
modified, the following are some other possible causes.
Columns of certain data types and fields that are calculated on the server
could cause the comparison in the WHERE clause of the update query to fail.
You could run into this problem, if these conditions are true:
- Column is of an imprecise data type (such as float or doubles).
- Column is a fixed length string (some drivers don't pad strings with blanks,
which leads to failures in comparison).
- Column is calculated on the server, and successive saveChanges calls (without
an intervening refresh) are made.
There are two possible solutions:
- In the MetaDataUpdate property editor, uncheck "Searchable", and set the
searchable property of the column in question to false, so that the column
is not included in the WHERE clause of the update query.
- Add a QueryResolver to the app, and set UpdateMode on the QueryResolver to
KEY_COLUMNS. This is done by instantiating a QueryResolver component, and
setting the resolver property of the QueryDataSet to that QueryResolver.
Problem: You get error messages from the server that are not due to constraint
or integrity violations -- the text of the message will vary from server to
server.
Possible Explanation 1: If you have a manually added or calculated field in
your app, this column is being included in the update query (in the SET and/or
WHERE clauses) and this is causing the resolution to fail. Workaround: Set
the resolvable property of the column to false. This prevents JBuilder from
trying to resolve changes to this column back to the server. Note: To prevent
unwanted edits to columns, set the editable property to false for that column.
Possible Explanation 2: It may be that your driver does not support prefixing
field names with table names (for example, testtable.column1). The workaround
is to set useTableName in the database to false.
Possible Explanation 3: MetaDataUpdate has been set to NONE, but searchable
has not been set to false for BLOB columns. In this case the workaround is to
set the searchable property to false. See the "Providing problem" in text above
for more details.
G5. Wizards
----------
Be sure that you have built all your .class files before running
the Deployment Wizard. If you see the "Can't find .class files"
message from the Wizard, you have probably forgotten to compile
your project first.
Additionally, be sure to add any .properties, .txt, and .schema files you
wish to deploy to your project so that they can be seen by the Deployment
Wizard. Note that you may first need to use Tools|Treat As Text in order to
add those files to your project.
G6. KL Group Components
----------------------
The customizer for KL Groups chart does not fire PropertyChangeEvents. This means that when the customizer is used in the designer there is nothing that JBuilder can listen for to allow the changes made in the Customizer to persist. (11956)
G7. Debugger
------------
Setting breakpoints in inner classes may give the warning "Some breakpoints found on lines
which do not contain debug information." The work around is to set the breakpoint before
the inner class. (10811)
If you have two classes with the same names but in different packages, a breakpoint may not
stop in the class you desired. The workaround is to reference the classes by their fully qualified names. (12581)
The debugger may treat some handled exceptions as if they were unhandled and log these in the execution log. A workaround is to tell the debugger to stop whenever it encounters an
unhandled exception. (13325)
G8. CodeInsight
---------------
For performance reasons, users with a slower machine (< 133mhz machine)may want to turn off
all of the CodeInsight checkboxes on the CodeInsight tab of the IDE options dialog. You can still use CodeInsight, but it will be on demand (by hitting hotkeys Ctrl+Space, Ctrl+Shift+Space, or Ctrl+Alt+Space).
The performance upon hitting these keys will be less than for someone using "Background Research". The benefit is that you won't have slower performance in other places (if any).
Using "Auto-Code Completion" and "Auto-Parameter List" without "Background research" is not recommended, so you should turn these off.
"Syntax Highlight declaration errors" won't work without "Background Research".
G9. IDE
-------
Paths that contain spaces and # symbols cannot be used in Java programs. (12993)
"Browse symbol at cursor" brings up empty navigator, structure, and content panes if the object being browsed has a fully qualified package path. The workaround is to convert the explicit package path to an import statement in the file. Then remove the explicit package name
before the class name. (13341)
G10. JBCL
---------
Field Ditto in a lookup column throws an exception for columns of numeric type which are
displayed as strings. Ditto tries to copy the String, rather than the actual column value, which causes the problem. One work around is to use Row Ditto. (13346)
JBCL ChoiceControl leaves the current item displayed in the control if a subsequent query is executed and choiceControl1.setItems() is called. The workaround is to set the control's
dataSet to null prior to population. (13177)
G11. Samples
------------
The sample file, samples\borland\samples\apps\chess\client\Chessviewer.java, will not
due to a spurious import statement. To fix the problem, comment out the line:
import welcome.Application1;
-------------------------------
SECTION 2. International Issues
-------------------------------
A. Install
----------
Due to JDK limitations, installation into a directory path
containing non-ASCII characters is not supported. (3235)
B. Compiler
-----------
1. Native encoded source files:
By default the compiler uses the encoding appropriate for your
environment. The JDK convention is to assume 8859_1 for most Windows
environments (Cp1252). If you use Cp1252 characters within the
range of x7F through x9F, then you should explicitly set the
encoding to be Cp1252. (5882)
To select the encoding used by the compiler, click on the IDE
Options item in the Tools menu, then select the encoding from
the list provided. For the command line compiler, use the -encoding option.
2. Local characters in Identifier names:
You can use local characters, including multi-byte characters,
in identifier names. However, due to a JDK limitation,
you can only use ASCII characters in class and package
names. Therefore it is suggested that only ASCII
characters be used as component names. This is because any
event handler classes will use the component name. (6362)
3. Non-English versions of JBuilder
Compiler messages from the command-line compiler are
displayed using the wrong character set. As a workaround,
and to display all compiler messages in English
(including the IDE compiler), rename or move the file,
<JBuilder_directory>\lib\bcj.properties, and relaunch JBuilder. (13410)
4. Compiler encoding under Asian Windows environments
Under some Asian Windows environments, the compiler in JBuilder
uses a different default encoding from that used by
the JAVAC compiler in JDK 1.1.6. (13233)
Under those environments, some characters in the JDK1.1.6 default
encoding are not in the JBuilder compiler's default encoding.
If the default encoding is used with the JBuilder compiler,
these characters will not be correctly compiled. To correct this
problem, you can specify the compiler encoding explicitly.
For compilation from the IDE, select "File | Project Properties...",
select the Compiler tab, and finally, change the encoding from
"Default" to the desired encoding. For the command line compiler,