---------------------------------------------------------------- HintsAndTips.txt Late-breaking news, workarounds and useful tips ---------------------------------------------------------------- To jump to a specific section, search for "SECTION #", replacing # with the appropriate section number. ----------------- TABLE OF CONTENTS ----------------- SECTION 1. Helpful Tips and Workarounds A. General B. Install C. JDK D. AppBrowser E. Compiler F. Debugger G. Visual Design Tools and JavaBeans H. The jbInit Method I. Using Relative Paths in JBuilder J. Database K. Database - Resolving L. Working with Columns M. Help System N. Wizards O. KL Group components P. Using ObjectStore PSE with JBuilder Q. Deploying Applications and Applets SECTION 2: International Issues A. Install B. Compiler C. Visual Design Tools D. Database ----------------------------------------- SECTION 1. Helpful Tips and Workarounds ----------------------------------------- A. General ---------- For the latest information on JBuilder, please see the JBuilder page at http://www.borland.com. B. Install ---------- Be sure to uninstall any previous version of JBuilder. Manually delete the bin directory that will probably remain after you uninstall JBuilder .Delete the jbuilder.ini file. According to Windows conventions, JBuilder automatically updates your registry to add a file association for .java and .jpr files. This means JBuilder launches automatically when you double click one of these files in your Explorer. If you wish to use your own editor to browse .java or .jpr files from the Explorer, follow these steps: 1) Open your Explorer. 2) Choose the View | Options menu item. 3) Select the File Types tab. 4) Scroll down and select the "Java File" file type. 5) Click the Edit button. 6) Click the New button. 7) For the Action, specify Edit. 8) To specify the application to run, click the Browse button and select your favorite editor. 9) Click OK three times. You have just added an Edit command to your right-click menu in the Explorer for this particular file type. Selecting this command invokes your editor. Double-clicking still launches JBuilder. C. JDK ------ This release of Borland JBuilder is based on the Version 1.1.2_Borland of Sun's Java Development Kit. This version of the Java Development Kit contains JDK 1.1.2 functionality plus 1.1.3 AWT features, plus some Borland-found bug fixes needed for JBuilder to run correctly at development time. The target applications should be able to run on JDK 1.1.3 or later in all cases. Also, if you restrict yourself to the features of earlier versions, your classes should run without problems on earlier versions of the JDK, such as 1.02. Do not use any other JDK 1.1 release with JBuilder itself -- use only the JDK 1.1 included with JBuilder. You can deploy your target applications with any JDK version 1.1.3 or higher, however. D. AppBrowser ------------- If you remove a file from a project and then, in the same session, try to create a class with the same name as the removed file, an erroneous dialog box appears reporting that the file already exists. Your new file will be created correctly. (5233) JBuilder can hang when it encounters files with paths that contain a "#" character. The workaround is to remove the "#" character from the directory name. (6458) E. Compiler ----------- If you compile a project and get an error that a class file is not found, this is the problem: If that class is referenced in the code, it must exist whether or not compilation of it is necessary. In other words, class loading on demand is not implemented in the compiler. The workaround is to obtain those missing classes from the vendor. Alternatively, if the class is referred to, but never really used (for example if there is an unnecessary import statement), you could create a dummy class with the same package and name as the compiler complains about and place it in the classpath. (6887) For certain source code, such as an empty try and non-empty catch, the compiler generates correct but dead code. The JIT detects the dead code and gives the warning "JIT compiler: Bytecode does not conform to the specification." The code runs correctly, however. (5789) The compiler does not report an error when an inner class name is the same as its enclosing class. It should. (7763) JBuilder has problems if you put the root directory of a drive (e.g. c:\;...) in the source or class paths. Make sure that all nodes in these paths are either at least one directory down from the root, or are explicit archive filenames. (5893) F. Debugger ----------- Changes to an .html file, such as changes to an applet tag, are not acknowledged by the Debugger until the .html file is saved. (6711) For a class displayed in the list of non-traceable classes, after the class is loaded, the invalid breakpoint glyph should be displayed, but is not. Instead, the unverified breakpoint glyph is displayed. (6670) Breakpoint line glyphs are not displaying correctly while debugging. The workaround is to force the window to repaint. (6628) The error message "Unable to debug class" appears when you are debugging an applet and these conditions are true: 1. The project file is selected. 2. The .java file doesn't have a main. 3. The project property "Default Runnable File" is blank. 4. One or more .html files exist in the project file before the .html file that has the valid APPLET CODE tag. The workaround is to change one of these four things, or right click on the desired .html file in the Navigation pane and choose Debug. (7353) Conditional breakpoints take approximately one second per conditional evaluation cycle. If the condition is evaluated many times, the debugger may appear to be hung when it isn’t. You can use the Pause or Stop buttons if necessary. (7784) If you have .class files in a .zip or .jar file, you must set the Debugger option Compile before Debug to Yes. (4331) If your application throws an exception very early in operation before the Debugger sees the thread, JBuilder can hang. If you suspect this, try to suppress portions of the application's startup code that may be throwing an exception to find where it is happening, and then handle or prevent the exception. (7825) G. Visual Design Tools and JavaBeans ------------------------------------ You can quickly get to the online reference documentation for a component in the Inspector by clicking on a property in the Inspector and then pressing F1. The Designer only designs Beans, which must be public. If you have a class which is not public, the Designer will report a parse error. The workaround is to make your class public. The purpose of the UI Designer is to design visual Beans (subclasses of java.awt.Component) placed into Beans that are subclasses of java.awt.Container. Beans that don't meet these requirements will not appear in the UI Designer. Instead, they appear only in the Component Tree under the Other node. (7678) The following functionality of JavaBeans is not supported in this release of JBuilder: 1. Setting internally indexed properties using the Inspector. (Those that have the form "void setProperty(int, T)"). 2. The invoking of Customizers. 3. The creation of code for Applet and deserialized Bean use. Note that you can make this code change by hand. If you don't see what you expect in the Designer after dropping a control or setting a property, you can try refreshing the Designer by double-clicking the node labeled "this" in the Component Tree pane, or using the right-click Activate Designer menu item. If this doesn’t work, try touching the source code and then returning to the Designer. (7438) You cannot add a Bean to the Component Palette if it has the same name as another Bean already on the palette. The workaround is to rename the Bean. (7607) If you have a Bean in one file, which is referenced in another file and is currently being viewed in the Designer, changes made to the first Bean are not be reflected in the other Designer until you exit and restart JBuilder. The reason is the first time you use the Bean in the Designer, it is loaded by the VM and referenced by the Designer. Even though you change the Bean and recompile, the class is already loaded and is not replaced. This is true for any Bean which is being designed and used in the same session. (7679) The DecoratedFrame class will automatically close the application when the user clicks the X close button. If you have a multi-window application and don't want this behavior, simply set the exitOnClose property of your class that extends DecoratedFrame to false. In this case, if you want to do more than just System.exit() on this button, you must handle your own processing of this window close event. See the TextEdit tutorial sample file for an example of how to add a window close event handler. (7583) Double-clicking on a designer folder in the Component Tree does not bring up that designer. For example, even if you have a menu in the frame you are designing, double-clicking on the Menu folder causes the Content pane to merely go blank. To bring up the Menu Designer, you must double-click on the next level object down in the Component Tree, such as MenuBar. (6954) If you want to set a ListControl's navigateWithDataSet property to false, you must first attach the dataSet to the component. (7146) If you want to drop a visual component on a class that extends a class with a jbInit() method, you must move the instantiation of that visual component into the jbInit() method in the source code. (6596) If you have set a font property of a menu item and then add a sub-menu to that menu item, the setting of the font property is lost. The workaround is to reset the font property for that menu item. (5787) Setting the background color property of a column object in the Inspector also sets the foreground color to the same value in the Inspector. Changing the foreground color does not reflect your changes in the Inspector, although the correct code is generated. (7214) Setting a TextFieldControl's setReadOnly property to true after setting the TextFieldControl's setText property, causes the text not to be displayed in the UI Designer. The workaround is to set the setReadOnly property to true before setting the setText property. (7321) You will get an exception if you set the buttonType of a ButtonBar to the existing type, including setting it to the default value (TextAndImage) if it wasn't explicitly set. The workaround is to not set the default explicitly. You can also test the existing value first and elect not to set it. (7550) buttonBar.setButtonEnabled(int, boolean) throws an IllegalArgumentException if the buttonBar has not been shown at least once. The workaround is to call setButtonEnabled only after the buttonBar has been shown. (7745) If you add a frame to your project that extends a frame currently in your project and the frame which you are extending contains AWT components and your new frame does not, you must add the following line of code to your new frame in order to compile: import java.awt.*; (7831) When designing an application that has multiple menus in multiple frames, a bug occurs when you edit more than one of these menus through the Menu Designer during a single session. If you need to design multiple menus like this, it is best to close the project and reopen it before designing the second menu. (7780) Calling getSelectedLabel from a CheckboxPanel when none of the checkboxes are checked causes a NullPointerException. The workaround is to wrap try/catch around the call to catch the NullPointerExecption. Usually one of the radio buttons is initially checked, which is what you want. (7734) A ChoiceControl by default displays the first value in the string array that was used in the ChoiceControl's setItems method, but the ChoiceControl's model will be null. Set the ChoiceControl's model explicitly to have the ChoiceControl display its actual setting. (7656) The tab order of components in a frame or panel is determined by the order of the add() method calls in jbInit. This is initially determined by the order in which you drop controls into your design. To subsequently change the tab order, manually change the order of the add() calls in your source code. (7650) The setSelectedIndex property of a checkboxPanel requires a group, therefore its properties must be set in the following order: 1. The labels property. 2. The grouped property. 3. The setSelectedIndex property. (7889) Dropping controls to a layout in the Component Tree does not work correctly. The workaround is to select the layout in the Component Tree and drop the control onto the frame or panel. (7882) H. The jbInit Method -------------------- The contents of the jbInit method are arranged as follows: 1. Subcomponent initial property settings 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 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 jbInit, 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. I. Using Relative Paths in JBuilder ----------------------------------- Using the iconImageName as opposed to the iconImageURL: We recommend using the "xxxName" as a general resource identifier. The "xxxUrl" properties may become deprecated in the future. When running or debugging your application, the "current directory" is the project directory. Images and other 'resources' should be loaded in the following sequence: 1. Loaded as a resource. System uses classpath entries + name. 2. Loaded as a URL. 3. Loaded as a path (relative to current working directory or an absolute path) J. Database ----------- 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. The default value of the resolvable property for a calculated column is true, which causes an error when saving changes because you cannot resolve to a calculated column. The workaround is to set the resolvable property of the calculated column to false. (7869) Changing the getter for a DataSet in a DataModule and recompiling the DataModule source is not reflected in the Visual Design Tools when you switch back to a frame that has a reference to the DataModule. The workaround is to close and reopen the project to refresh the Visual Design Tools to show the current DataModule state. (4980) A partial locate on a column sorted in descending sequence finds only exact matches. (2397) You may get deprecation warnings when compiling applications using DataSet. (7083) Creating a DataModule class, and placing a queryDataSet in the subclass may generate code that accesses uninitialized variables in a derived class. For example: QueryDataSet queryDataSet1 = new QueryDataSet(); jbInit() { super.jbInit(); queryDataSet.setQuery(...) } When the subClass1 is instantiated, the sequence of execution is: 1. The constructor of subclass 2. Which calls the constructor of the superclass 3. Which initializes all the superclass variables 4. And then calls the jbInit() of the subclass 5. Which calls jbInit() of the superclass 6. And then calls queryDataSet's setQuery (which is not initialized) Since Java allows such a calling sequence, the queryDataSet1 variable of the subclass is never initialized and is always null. (6429) When a column's edit mask is removed through the Visual Design Tools, the call to setEditMask is not removed. The workaround is to remove that line of code from the source. (6584) When you use the Class wizard to make a new class which implements a DataModule, a static getDataModule method is not created. The workaround is to use the File|New...DataModule, or code that method by hand. (6897) To append a new pseudo-record to a DataSet when positioned on the bottom row of a grid control, press Ctrl-Down. (7002) If you want to set the ListControl property navigateWithDataSet to false, you must set the dataSet property of the ListControl first. (7146) The AccessEvent handler in GridControl does not properly handle two dataset.close() requests in succession. The workaround is to not add the extra close. (7289) If you link a DataSet to itself in a Master-Detail relationship, some editing operations fail. You can still use this type of link for read-only operations. Use a TableDataSet or QueryDataSet for the master, and a DataSetView for the detail, so they can navigate separately. DataSet.rowCount() doesn't change after a DataSet is emptied (using StorageDataSet.empty()), and a grid displaying the data isn't notified of the change. The workaround is to force the updates by closing and reopening the DataSet. (6841) There is currently a bug in the JavaSoft SimpleDateFormat class (in JDK 1.1.2) involving Timestamp values. The default displayMask for Timestamp in the English Locale is "MM/dd/yy hh:mm:ss a". When a Timestamp value containing all zeroes in the "mm:ss" part of the pattern is parsed (such as 02/26/97 12:00:00 am), a spurious NullPointerException is occasionally thrown. (5532) Use FieldControl rather than TextControl when binding separate field objects to a DataSet. This component is data-aware and inherits all the appropriate properties from its associated Column object. The TextFieldControl object, on the other hand, is a very thin wrapper on top of the AWT TextField component and is not aware of issues like Locale-specific formatting. Consequently, the TextFieldControl is not recommended for use with DataSet Columns. (5532) The FieldControl has a new property called postOnFocus, which provides the same functionality as that of the TextFieldControl. If this property is set to true (the default), when the FieldControl component loses focus to some other component in the current window, an endEdit occurs that posts the value, for example, to the DataSet. If this property is set to false, you must press the Enter key first to post values to DataSet. When you're defining a Master-Detail link between TableDataSets in the Designer, column names are not displayed in the MasterLink editor. The workaround is to add the code to set the MasterDetailLink manually. (7599) BLOB images are not displaying consistently in a gridControl. The workaround is to use fieldControls to display BLOB images. (7772) If you use an edit mask, values for LONGs that are greater than the maximum INT are truncated to INTs when you enter edit mode. Once in the edit mask, you can enter any LONG value, and it is retained when you end the edit. There's no truncation if you have only a display mask or no mask at all. (7548) The layout property of a buttonBar cannot be changed. If you try to change it in the Inspector you will find that you cannot move off of that property temporarily. The workaround is to select a different component and then reselect the buttonBar component. (7542) The preferred way to manage JDBC Connections is to use the Connection property of the Database component. If you have a specific need which is not met using this approach, there is an alternate constructor for the Database component that allows you to pass in your own JDBC Connection. Note that once you give a JDBC Connection to the Database object, the Database is free to close that Connection when necessary. This constructor is really reserved only for those situations where no other approach works. It is likely to become deprecated (that is, removed) in future releases. It will be replaced by more powerful Connection property binding methods. (7138) When a Master table is linked to itself, selecting the Delay Fetch option in the masterLink Descriptor UI followed by pressing TestLink causes a stack overflow. (7848) Assigning a non-default Locale to a DataSet does not reconfigure the formatter for each Column. The workaround is to call setLocale() for each column to force initColumn to rebuild the formatter. (5762) 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 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 table on the server has a unique row id. When you try to modify the dataset, 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 the MetaData functions used by JBCL. The solution is to set metaDataUpdate on the QueryDataSet to MetaDataUpdate.NONE, which bypasses obtaining MetaData information. What this means is that the following properties, which would otherwise have been set automatically, will now have to be set by hand. For Column, the properties are rowId, precision, scale, and searchable; for QueryDataSet, the properties are tableName and schemaName. For more information on MetaData, please refer to 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 app 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. K. 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 datatypes and fields which 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 for instance: - Column is of imprecise data types (such as floats and 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: Set metaDataUpdate to MetaDataUpdate.NONE, 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. Note that this means you will have to set other properties as well to make the query updatable, as described in "To Make a query updatable” in text above. 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. L. Working with Columns ----------------------- The Column objects within a DataSet can be assigned properties just like any other component in JBuilder. These properties include both metadata (such as data type, precision, etc.) as well as visual properties (font, color, etc.) To edit the properties of a Column, you open the DataSet by clicking the "+" icon next to the DataSet in the Component Tree. If the DataSet can be opened, the Component Tree shows all of the Column objects as child nodes of the DataSet. Now, you can click on any of these Column objects, and the Inspector displays its properties. If you change any of these properties, JBuilder generates code (which you can view in the Content pane) to assign that property value at runtime. Any column which has such source code associated with it is called a persistent Column, because these values have been explicitly made persistent via source code. Persistent Columns are shown by surrounding their name in the Component Tree with square brackets ("[like this]"). Note that there is always a node under all the other Columns. You add new Columns to a DataSet by editing any property of this component. This is typically how you go about defining the Columns in a TableDataSet or adding calculated or aggregate fields to any kind of DataSet. There is one side-effect of making a Column persistent that you should consider. All persistent Columns are logically moved to the start of the list of Columns. This means they will no longer appear in the order they are found, for example, in a QueryDataSet. The order the Columns are named in the setColumns() statement is the order these Columns will have at runtime, regardless of the order these Columns appear in a select statement of a query. Any Columns not listed in the setColumn() but appearing in the output of the query are appended to the end of the list of persistent Columns. If you do not like this new Column order, manually edit the code in the dataSet.setColumns() methods you find in your source code window to list the columns in the desired order. Though you are not required to set any Column properties in order to use them, you will probably find that certain properties (such as width) will give your presentation a more customized look at runtime. For more information on working with columns, see "Working with Columns" under "Accessing Data" in the Database Application Developer's Guide. M. Help System -------------- JBCL Reference: Simple properties are listed in the Properties section for each class. Array and indexed properties are listed in the methods section. (7137) Pressing Enter to bring up the content for an index entry actually brings up content for the next entry in the index. The workaround is to double-click on the desired index entry. (7370) JBuilder hangs when you try to get context-sensitive help from within the Help Viewer itself by pressing F1. (7255) N. 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. We also suggest that you only invoke the Deployment Wizard once per JBuilder session in this release, including wizard invocations you cancel. There are some problems with the Wizard that only show up if you invoke it more than once during a JBuilder session, such as zero-length manifest files, older versions of .mf files in the archive, or running low on memory. (7692) In the Expression Assistant of the Interaction Wizard Editor, the checkbox labeled This method exposed to interactions is not checked by default. Usually you want to check that option. (7036) In the Application Wizard, the case must match the actual case of the directory path when specifying the directory path of your project file. (6679) The Project, Application, and Applet Wizards require you to have more than one node in your source path. If you only have one node in your source path, the workaround is to add a dummy node (e.g. c:\jbuilder\myprojects; c:\temp). (7224) If the location of your project is not in or under a directory on your source path, using the Frame, Panel, Dialog or DataModule Wizards puts the new file in a package on your source path, not where your project is. The workaround is to add to your source path the location of your project, or some directory other than the root above its location. (5839) Be sure that the first entry on your source path is a directory and not a zip file. Wizards that create files assume the first node on the source path is a directory name. The actual filename is generated by taking this directory name and appending the package, if any, and treating the classname as the filename. (7727) Closing a project while a Wizard is starting up can hang JBuilder. (7567) If the root directory of any drive is selected in the Source Path selection dialog box, a backslash is included at the end of it. This can cause problems when Wizards are used to create files, as they automatically append another backslash to the path, resulting in a double backslash. The workaround is to remove the extra backslash from the path. (6636) To be able to drop a wrapped applet to a frame or panel, you must add your output path (usually "..\myclasses") to the IDEClassPath. With JBuilder not running, edit the file, ..\bin\JBuilder.INI. Find the line that begins with "IDEClassPath=". At the end of this line, add the string ";..\myclasses", substituting your own output path if it differs. (7893) On the Parameters page of the Applet Wizard, after entering a parameter, click away from that field to another field in the grid to commit your change. Pressing OK or Enter moves to the next page of the Wizard without committing your last change. (7907) After using the Resource Wizard to change your project, be sure to recompile the project by selecting either Build | Make Project, or Build | Rebuild Project. Otherwise, if you try to run or debug your project, strings may be missing from your user interface, and you may see the runtime message, "java.util.MissingResourceException: Can't find resource at... ." (7514) O. KL Group Components ---------------------- Adding event code to some components results in an error when compiling. The error reports that the event adapter should be declared abstract because it does not implement all the methods of an interface. This happens because the adapter for this event type is missing. The workaround is to invoke Wizards | Implement Interface, select the appropriate adapter class from the Class Name drop down, browse for jclass.awt.*, and select the appropriate interface in the Available Interfaces tree. After doing this, your code will compile. (7172) JCCheckbox doesn't display properly when set to MIDDLELEFT. The workaround is to set the property to TOPLEFT, and it displays as expected (7632) Setting some properties results in a null where the classname of the static constant should be. It will look something like this: nullPLACE_BOTTOM. The workaround is to change "null" to a class depending on the component. For Table, use jclass.table.JCTblEnum. For ChartComponent, use jclass.chart.JCChartComponent. For Chart axis, use jclass.chart.JCAxis. For Chart legend, use jclass.chart.JCLegend. Anything else should use jclass.bwt.BWTEnum. (7336) P. Using ObjectStore PSE with JBuilder -------------------------------------- Object Design (http://www.odi.com) has a Java object-oriented database product called "ObjectStore PSE" that can be used with JBuilder. To use PSE with JBuilder: 1. In File | Project Properties | Project add \pse.zip to the "Class Path:" field. 2. Build your application. 3. In a Command Console window, run the PSE class file post-processor (osjcfp) as specified in the PSE documentation. 4. Copy *ALL* of the post-processed (annotated) classes from the osjcfp output directory into your project directory, effectively replacing the non-annotated version of your classes with the newer annotated versions. 5. In JBuilder select File | Project Properties | Run/Debug (tab) and check to see that the Compile project before debugging option is NOT checked. Now you can Run | Debug your application. Yu cannot simply run your application in JBuilder, nor can you make changes to your classes without going through steps 3 and 4 above. Here's why: JBuilder prepends the Project directory to the front of the CLASSPATH directories. This causes the non-annotated classes to be loaded BEFORE the annotated classes. Currently, there is no way of short-circuiting this feature. Summary: To use PSE with JBuilder you must: 1. Place all annotated classes in the Project directory, overwriting the non-annotated versions. 2. Run | Debug only (with compiling turned off). Q. Deploying Applications and Applets ------------------------------------- For information about deploying Applications and Applets, see the “Deploying Java Programs” section in the JBuilder User's Guide. The online copy of that document contains later information than that found in the printed version. The information provided below is supplemental to the JBuilder 1.0 online documentation. It may be partially obsolete by the time you read it, so please visit the JBuilder Web page at http://www.borland.com for the latest updates of deployment documentation. Deploying an Application ------------------------ See the instructions in the online version of the “Deploying Java Programs” section in the JBuilder User's Guide. Note that for final deployment of JDK1.1 applications, you should now use JRE.EXE rather than JAVA.EXE to launch your application's class. JRE.EXE is a freely redistributable runtime VM, available in the JBuilder\bin directory, and also freely downloadable from the JavaSoft Web site. JAVA.EXE is not intended to be redistributed, rather it is for use as part of the development kit only. For more information, see the JRE download at: http://java.sun.com/products/jdk/1.1/index.html In summary, you can use JRE to launch the class containing your application's main() method. JRE looks for the remaining classes and archives in the locations indicated in the classpath. You can specify this with the -classpath command line argument to JRE. A simple example: 1. Close all existing projects 2. Use File|New... Application to create a new project and untitled1.Application1 in myprojects\untitled1 3. Design your application's Frame1 (for example, drop a button on it and hook up an event). 4. Compile your application. 5. Create a directory in which you will test an installation/deployment of your application, for example: c:\test 6. Install the Java Runtime Engine onto your path. (During test, you can run \jbuilder\bin\setvars.bat to get the JRE into your path and environment correctly.) 7a. If you are deploying your application as class files: create the directory: c:\test\untitled1. Then, enter this command: copy jbuilder\myclasses\untitled1\*.class c:\test\untitled1\. 7b. If you are running the Deployment Wizard to bundle your Application1, Frame1, and dependency classes into one .jar file, use this command: copy jbuilder\myclasses\untitled1.jar c:\test 8. If you excluded the JBCL and JGL dependencies from your untitled1.jar, use these commands: copy \jbuilder\redist\jbclrt.jar c:\test\. copy \jbuilder\redist\jgl.zip c:\test\. 9. Type: cd c:\test 10. Type: jre -cp .;jbclrt.jar;jgl.zip untitled1.Application1 11. Alternatively, on your development machine, you can skip step 8, and just use this command: jre -cp .;\jbuilder\lib\jbcl.zip;\jbuilder\lib\jgl.zip untitled1.Application1 Deploying an Applet as .class files (JDK 1.02 or 1.1) ----------------------------------------------------- 1. Build your Applet in JBuilder. Compile the project. For the purposes of these instructions, we will use an example of your project existing in jbuilder\myprojects\untitled1\untitled1.jpr, and your Applet1.java having the package name of untitled1. 2. Copy your HTML file to the target directory. For example, if the computer has a c:\http directory that is what the web server makes visible as the root of the web page directory structure, and if you have a subdirectory there called "joe" where you can put your files, you would use something like: copy c:\jbuilder\myprojects\untitled1\Applet1.html c:\http\joe\. 3. Copy your .class files to the appropriate subdirectory, based on their package’s name, of the location named in the CODEBASE tag. If you don’t do this, you get a cryptic error message from the AppBrowser, such as ClassFormatError. To continue the above example, let's say your Applet class is untitled1.Applet1, and your CODEBASE parameter in the APPLET tag is ".". You should use a copy command like this: copy c:\jbuilder\myclasses\untitled1\*.class c:\http\joe\untitled1 4. If your Applet uses JBCL, be sure to copy the necessary JBCL and JGL classes to the server also. If your Applet uses a JDBC connection, then be sure that the JDBC driver client classes are there also. 4a.Specifying a name for the JDBC driver name parameter of borland.jbcl.dataset.ConnectionDescriptor( )causes an applet security violation. Alternatively, pass an empty string as the driver name, and preload the driver class as follows: Class.forName(jdbcDriverName); database.setConnection(new borland.jbcl.dataset.ConnectionDescriptor(jdbcURL, jdbcUserName, jdbcPassword, false, "")); 5. Load c:\http\joe\Applet1.html in your Web browser as a local file for initial testing. 6. Test via the Web server, by loading the http URL that represents joe\Applet1.html in your Web browser Deploying an Applet as a Java archive file (JDK 1.1 only) --------------------------------------------------------- 1. Build your Applet in JBuilder. Compile the project. For the purposes of these instructions, we will use an example of your project existing in jbuilder\myprojects\untitled1\untitled1.jpr, and your Applet1.java having the package name of untitled1. 2. Run the Deployment Wizard, selecting the applet java file(s) and any necessary image files. To see them in the Deployment Wizard, add them to your project first. 2a Do NOT select the .jpr or any .html files. They should not be in your .jar file. 2b If you leave JBCL and JGL excluded, you will need to deploy three .jar files in step 3. 2c If you turn off the exclusion of JBCL and JGL, your archive will be larger, but will contain all the necessary .class files in a single .jar, and so you will need to deploy only the one .jar file. One way to get all the necessary JBCL images is to add the following two packages to the project: borland.jbcl.control.image borland.jbcl.view.image You could also add only selected images these packages instead. In this example, you could name your archive untitled1.jar. 4. Modify your HTML page to add an ARCHIVE parameter to the APPLET tag. The value of this parameter should be the name of the .jar file, or a comma-separated list of the jar files, that you created in step 2. For example: 3a If you deployed all of your .class files, including JBCL and JGL dependencies, into a single .jar file, use something like this: ARCHIVE="untitled1.jar" 3b If you excluded JBCL and JGL, then you will also need to deliver the JBCL and JGL files, using an ARCHIVE tag something like this: ARCHIVE="untitled1.jar,jbclrt.jar,jgl.jar" Check the redistribution details in your license agreement to see exactly what you can redistribute. 3c An intranet alternative to 3b would be to install the jbclrt.jar and jgl.jar files in the local classpath for the browsers that will be viewing your applet, and then just putting the applet jar file on the server. The parameter would then be just this: ARCHIVE="untitled1.jar" 3d In any case, your CODEBASE and CODE tags would remain something like this: CODEBASE="." CODE="untitled1.Applet1.class" 4. Copy your HTML file to the target directory. For example, if the computer has a c:\http directory that is what the web server makes visible as the root of the web page directory structure, and if you have a subdirectory there called "joe" where you can put your files, you would use something like: copy c:\jbuilder\myprojects\untitled1\Applet1.html c:\http\joe\. 5. Copy your archive file(s) to the server location indicated in the CODEBASE tag. For example: copy c:\jbuilder\myclasses\untitled1.jar c:\http\joe Note that since the archive already contains the structure for the untitled1 subdirectory, you do NOT place the archive file down in an untitled1 subdirectory, but directly into the directory indicated in CODEBASE. 5a If you are using step 3b, copy all of your archive files, including JBCL and JGL runtime archives, to the same location. 5b If your Applet uses JDBC data connections, be sure to copy the appropriate JDBC client driver class archive (e.g. Interclient.jar) to the server. 5c If you are using step 3c, copy your applet jar file to that location, and, separately, get your browser clients to all have the JBCL and JGL runtime archives listed explicitly in their classpaths. Check the browser(s) you will be using to see how this is done, or whether these archives may already be present in their delivered archives. For example, for MS Internet Explorer the local archives are listed under the registry entry: Hkey_Local_Machine/Software/Microsoft/Java VM 6. Load c:\http\joe\Applet1.html into your Web browser as a local file for initial testing. 7. Test via the web server by loading the http URL that represents joe\Applet1.html into your Web browser. Viewing JDK 1.1 Applets ----------------------- We anticipate that the popular Web browsers will be fully JDK 1.1 compatible by the time you are deploying JDK1.1 Applets. If, during early development, this is not widely the case yet, you can use the following tools to view JDK1.1 Applets in the meantime: (information here is from 7/97) 1. JDK1.1 Appletviewer, which is integrated into JBuilder and used for running and debugging applets, is fully 1.1 compliant. When you run or debug an Applet in JBuilder, you are actually seeing its UI in Appletviewer. Appletviewer can also be run standalone if you want to demo your Applet separately from JBuilder and have no 1.1 browser available. You can launch Appletviewer on the command line, pointing it at the HTML file containing the Applet tag, but it only shows the Applet itself, not any of the other HTML content. You may need to run jbuilder\bin\setvars.bat, with one parameter indicating the location of your JBuilder directory, in the same console session before running Appletviewer for it to know where all the class files are located. See the notes in setvars.bat for more information on its use. 2. HotJava, available from Sun, is an all-Java browser that should be fully 1.1 compliant. 3. Internet Explorer version 3.02 can be patched with the Microsoft SDK for Java to bring it up to JDK 1.1 compatibility. Internet Explorer version 4 contains a JDK 1.1-compatible VM. It also contains a Microsoft version of Appletviewer. 4. Netscape has announced upcoming JDK1.1 support in Navigator. 5. Search the Web sites of your favorite Web browsers to see the current status of their support for JDK 1.1. How to build and deploy a 1.02 Applet for a 1.02 browser -------------------------------------------------------- If you must create an Applet that will be used in a JDK1.02-only browser, and you don't have a 1.02 development tool, you can, with some extra efforts, create or maintain 1.02-compatible Applets in JBuilder, as follows: To maintain an existing applet, just be sure to stick with 1.02 Java features. See suggestions below. To create a new Applet for 1.02 use: 1. Use File | New Applet to create the html and java files. 1a Select the option for Generate Standard Methods. 1b Create any parameters needed. 2. In the java source for the Applet, do these things: 2a Remove the imports for borland.jbcl and java.awt.event stuff: import borland.jbcl.layout.*; import borland.jbcl.control.*; import java.awt.event.*; 2b Remove the XYLayout instantiation and usage lines: At the top of the class: XYLayout xYLayout1 = new XYLayout(); In jbInit: xYLayout1.setWidth(400); xYLayout1.setHeight(300); this.setLayout(xYLayout1); 3. Develop your applet using only 1.02 features. 3a Use only the components on the AWT tab of the palette. 3b Use the default layout (Flow) for the applet, or use 1.02-style layout management. Do not use XYLayout at all. 3c You will probably have to change all .add statements from something like this: this.add(button1, null); to something like this: this.add(button1); 3d Use only properties whose setter and getter methods were already defined in JDK1.02. For example, in JDK1.02, java.awt.Button had a label property (setLabel, getLabel), so it would be safe to use that one in the Inspector. If in doubt, refer to some 1.02-version documentation to know what methods you can call in 1.02. 3e Do not hook up events using the Events tab of the inspector (JBuilder's Inspector generates JDK1.1-style event mechanisms) Instead, use 1.02-style event handling only. 3f In general, code your application by hand. The Designers and Wizards generate 1.1 code. 4. Compile your Applet. 5. You can test it initially in JBuilder/AppletViewer as you would a JDK1.1 applet. 6. The code generated by JBuilder from 1.02-compliant source should be compatible with 1.02 virtual machines. As an additional precaution, and to verify that it conforms strictly to 1.02 patterns, you could also compile it with a JDK1.02 version of javac.exe and use the JDK1.02 class libraries. 7. Deploy your Applet as .class files. Do not use the Deployment wizard, because 1.02 browsers do not know how to read java archive files and don't recognize the ARCHIVE tag in HTML. ------------------------------- 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. ResourceBundle ResourceBundle must be explicitly rebuilt, rather than relying on the Build | Make Project command. To do this, display the pertinent file in the Source content pane, and select the menu command, Build | Rebuild "fileName.java". C. Visual Design Tools ---------------------- As for naming components with international characters, see the note regarding event handlers under the section above, "2. Local characters in Identifier names:". To use the UI Designer with ResourceBundle, you must add your output path (usually "..\myclasses") to the IDEClassPath. With JBuilder not running, edit the file, ..\bin\JBuilder.INI. Find the line that begins with "IDEClassPath=". At the end of this line, add the string ";..\myclasses", substituting your own output path if it differs. (7022) When using the IME to enter Chinese characters into the Inspector, you should use the keyboard. Using the mouse can fail to properly enter the character. (5465) There is a JDK limitation when creating localized applications whose menu commands have shortcuts such as Ctrl-S. For example, under a German locale, the shortcut should appear in the menu as Strg-S, but will always be listed as Ctrl-S. (6955) The KL Group components are backward-compatible with JDK 1.02. Therefore there are international limitations with these components. Particularly, the JCTextField and JCComboBox components are limited in how they accept international character input. D. Database ----------- 1. Schema file for TextDataFile When multi-byte field names are desired, you will need to use Unicode for the column names. You can first create your text file in the native encoding format and then use the command-line command Native2Ascii, a tool included with the JDK, to convert the file to Unicode.This command is explained in the JDK documentation. 2. Text file for TextDataFile When importing a text file with native encoding you must specify the encoding in the schema file. For example, if you are trying to import a file containing SJIS characters you must change your encoding in the schema file from 8859_1 to SJIS. /----------------------- END OF FILE --------------------------/