# Visual Café Tips

### A User's Guide for Users of Visual Café 1.x

[Last Updated: 28-Apr-97]

Visual Café 1.x is perhaps the leading Java IDE available. Since its release in late December 1996, I have had occasion to use it quite heavily, and have accumulated just enough knowledge to make me a little dangerous. I have been an avid reader of Symantec's Visual Café newgroups, where many of the tidbits on this page have been discussed.

The purpose of this page is to fill a void. While Symantec has overall produced a fine Java development tool, documentation has lagged, and many users sometimes have to figure out how to use some Visual Café features the hard way, or struggle when working with with the many visual components that come with the tool. Please note: this page does not cover Visual Café Pro features/issues, except where similar to Visual Café. I don't consider myself an expert, but in many cases I have been able to assist others on the newsgroups simply because I had seen their problem before just a couple of weeks earlier. I do suggest, if you cannot find an answer here, that you ask your question in one of the Visual Café newgroups, rather than to me directly.

As I spend more time on it I will try to better organize the topics covered on this page. I will also try to keep this page updated with as much useful information as I can. I invite anyone who wishes to send me additional info or corrections to do so. This is not a FAQ, but if it serves that purpose so be it. BTW, Symantec does have a FAQ.

> > Cheers!

> > Daniel Kirkdorffer

1. Working with Visual Café Components

   1. Animator
   2. BorderPanel
   3. FormattedTextField
   4. ScrollingPanel
   5. TabPanel
   6. Timer
   7. Steps for creating and using Java components in Visual Café

2. Other Visual Café Grinds

   1. Images not showing in ImageButton components
   2. Deleting rows in MultiList components
   3. Package statements impeding code generation
   4. Accessing card Panel components of cardlayouts
   5. Special Visual Café code generation blocks
   6. Further info on Visual Café code-visual synchronization
   7. Dealing with the addNotify() statement
   8. Context based Visual Café menu options
   9. Form Desinger grid spacing
   10. When in doubt check the code!

3. Useful Java Info

   1. JDK 1.02 Event Differences by Browser
   2. Tabbing from component to component
   3. No Horizontal Scroll Bars in TextArea in Netscape
   4. Choice and List components not correctly positioning themselves
   5. Label components not supporting colors
   6. Using javadoc
   7. Little known Netscape Java Console commands

4. Miscellaneous

   1. Redistributing Symantec's JIT and Components
   2. Publishing your work
   3. Determining what classes you use with bundler.exe
   4. Determining which version of Visual Café you have
   5. Getting the latest version
   6. Visual Café Books

1. ### Working with Visual Café Components

   1. Animator

      Symantec's Animator is a little rough around the edges mostly because it doesn't apply the double buffering technique for reducing flicker. However this is pretty easy to implement by extending Animator as shown:

          import java.awt.*;

          /**

           * This animator extends Symantec's Animator class to implement

           * "double buffering" techniques to remove flickering when images

           * change.

           *

           * @author      Daniel Kirkdorffer

           *              Email: DanKirkd@aol.com

           *              URL: http://members.aol.com/dankirkd/

           */

          public class MyAnimator extends symantec.itools.multimedia.Animator {

              // Off screen objects

              Image offscreenImage;

              Graphics offg;

              /**

               * Constructor.

               */

              public MyAnimator() {

                  super();

              }

              /**

               * Overrides Animator paint() to implement double buffering (drawing

               * image to the off screen buffer first, then drawing that image

               * to the screen).

               */

              public synchronized void paint(Graphics g) {

                  if (offscreenImage == null) {

                      offscreenImage = this.createImage(size().width,size().height);

                      offg = offscreenImage.getGraphics();

                  }

                  if (super.currentImage != null) {

                      offg.setColor(getBackground());

                      offg.fillRect(0,0,size().width,size().height);

                      offg.drawImage(super.currentImage, 0, 0, this);

                      g.drawImage(offscreenImage, 0, 0, this);

                  }

              }

              /**

               * Overrides Animator update() to avoid unnecessary clearing

               * of image between paints.

               */

              public void update(Graphics g) {

                  paint(g);

              }

          }

      A few useful methods are:

      > startAnimation() - to start the animation thread.
      > stopAnimation() - to stop the animation thread.
      > setDelay(int) - to set the delay between animation frames (in milliseconds).
      > setRepeatMode(boolean) - set to true to make the animation continuously loop.

   2. BorderPanel

      Version 1.0 and 1.0c Bugs:
      Symantec's BorderPanel component, while extremely useful, must be used with great care. Problems related to Inset Padding cause the Form Designer to shift components in BorderPanel components using null layout up and left. In version 1.0 this happens just by opening the Form Designer. In the no longer available 1.0c preview patch, the components wouldn't shift when the Form Designer was opened, but would shift if you changed any of the component's properties. There really are few good solutions to avoid these problems while we wait for a fix from Symantec. You could avoid using the Form Designer as much as possible, but that defeats the point of using a visual design tool. You could also not use the component, but it is such a nice component isn't it. The best solution may simply to be vigilant and to remember to unshift shifted components. An approach I often take is to place component's borders so they straddle the edge of the BorderPanel in some way. Should they shift at least one of the coordinates will go negative. I use a parsing routine to find these and unshift such components accordingly.

      Addendum:
      The BorderPanel bugs described above have been fixed in version 1.0d!

   3. FormattedTextField

      Symantec's FormattedTextField is a rudimentary component one can use to mask data input to, for example, only accept numerics, or only a certain number of characters. A common question is "what are the masks?" These are only documented by looking at the code in \VisualCafe\Java\Src\symantec\itools\awt\FormattedTextField:

              public final char ESCAPE                = '/';

              public final char DIGIT                 = '9';

              public final char SIGN                  = '+';

              public final char DIGIT_OR_SIGN         = '-';

              public final char ALPHA_UPPER           = 'A';

              public final char ALPHA_LOWER           = 'a';

              public final char ALPHA_TO_UPPER        = 'U';

              public final char ALPHA_TO_LOWER        = 'L';

              public final char ALPHANUMERIC_UPPER    = 'X';

              public final char ALPHANUMERIC_LOWER    = 'x';

              public final char ALPHANUMERIC_TO_UPPER = 'N';

              public final char ALPHANUMERIC_TO_LOWER = 'n';

              public final char ANY                   = '*';

      You may find, like I have, that you need extra masks. Furthermore, in version 1.0 and 1.0c, FormattedTextField eats tab key presses (this has since been corrected in version 1.0d). The following code shows how you can extend FormattedTextField to add your own masks, and ignore tab key presses:

          import java.awt.*;

          /**

           * MyFormattedTextField extends from Symantec's FormattedTextField with

           * the purpose of overriding its keyDown event handling to not

           * trap TABs.

           *

           * NOTE:

           * Use of a MyFormattedTextField may require a trim() of

           * data returned via getText().  This is necessary

           * because FormattedTextField leaves

           * residual blank spaces for unused mask positions.

           * ex: mask "NNNNNN", with "ABCD" entered will

           * yield "ABCD  " so we may want to trim the trailing spaces.

           * Keep this in mind when processing input.

           *

           * @author      Daniel Kirkdorffer

           *              Email: DanKirkd@aol.com

           *              URL: http://members.aol.com/dankirkd/

           */

          public class MyFormattedTextField extends symantec.itools.awt.FormattedTextField {

              // Additional Masks

              public final char DECIMAL_POINT             = '.';

              public final char DIGIT_OR_DECIMAL_POINT    = 'D';

              /**

               *  Constructor

               */

              public MyFormattedTextField() {

                  super();

              }

              /**

               *  Overrides FormattedTextField validChar method to

               * allow us to handle extra formatting requirements.

               * All base requirements are handed up the hierarchy.

               */

              protected int validChar(String s, int start, char mc) {

                  int len = s.length();

                  for (int i = start; i < len; ++i) {

                      char c = s.charAt(i);

                      switch (mc) {

                          // Code for additional masks

                          case DECIMAL_POINT :

                              if (c == '.')

                                  return i;

                              break;

                          case DIGIT_OR_DECIMAL_POINT :

                              if (Character.isDigit(c) || c == '.')

                                  return i;

                              break;

                          // Send base masks to super class to process

                          default :

                              return super.validChar(s, i, mc);

                      }

                  }

                  return -1;

              }

              /**

               *  Calls FormattedTextField keyDown only if

               * TAB key wasn't pressed.

               * @param	evt The Event.

               * @param	key	The key pressed down.

               * @return	True (event handled) or False (event not handled)

               */

              public boolean keyDown(Event evt, int key) {

                  if (evt.id == Event.KEY_PRESS) {

                      if (key != '\t')

                          return super.keyDown(evt, key);

                  }

                  return false;

              }

          }

      Issues:
      When using either FormattedTextField or the above subclass you should be aware of a few things:

      - FormattedTextField includes a setEditFont(Font) method that actually calls TextField's setFont(Font) method. FormattedTextField also overrides the setFont(Font) method as follows:

                public void setEditFont(Font f) {

                    super.setFont(f);

                    invalidate();

                }

                public void setFont(Font f) {

                }

        This means that to set the font you have to use the Edit Font property as the Font property for FormattedTextField will be ignored.
      - If you set an Echo for a FormattedTextField the Echo character displays in each position of your mask on initial display, rather than on a character by character basis at input time.
      - Ed Bassett has pointed out that setting any text through the Property List for a FormattedTextField that has a mask will not work. My investigation shows that the reason for this is the Mask property spawns a setMask() method call, which in turn calls setFillMask(), which calls setText(). Visual Café generates the setMask() code after the Text property generated setText() code, which means that setMask() will blank out whatever the text was being initially set to. You can get around this problem by including a `setText("My Text");` statement after Symantec's "INIT_CONTROLS" code block.
      - Another problem, alluded to in the comments in MyFormattedTextField (above), is when one sets a mask like `"99999"` (such as that used for a Zip code), FormattedTextField will pad the string with spaces, so that if one enters `"85"` a getText() returns `"85 "`. If one tries to override getText() in an extended version of FormattedTextField (such as in MyFormattedTextField), another problem is created because in FormattedTextField there is a method called processChar() which has the following statement:

                    String s = stripMask(getText());

        that expects a blank padded space to be returned and without the padding the code 2 lines down:

                    String l = selStart > 0 ? s.substring(0, selStart) : "";

        produces an out of bounds error. What this means is one has to do a `getText().trim()` on FormattedTextField components everywhere a `getText()` would have sufficed.

   4. ScrollingPanel

      The trick with using Symantec's ScrollingPanel component is understanding what it really is first. You use the ScrollingPanel component to present a "window" of sorts to an area that normally wouldn't fit in that space. The ScrollingPanel component allows you to scroll up and down, and left and right to access the entire area encompassed within it. So to get started all you need to do is:

      1. Drag the ScrollingPanel component onto the Form Designer.
      2. Place a Panel within it, and size it so that it is larger than the ScrollingPanel component. This should create visible scroll bars in the Form Designer, and you will notice that the outline for the ScrollingPanel seems to extend outside of the component.
      3. Now all you have to do is place the contents of the ScrollingPanel onto the Panel. Note: there is no reason why you can't use a Canvas inside the ScrollingPanel instead of a Panel, or any other visual component for that matter.

      Bugs:
      One problem that exists with ScrollingPanel components is that they sometimes lose their scroll bars. One way this can happen is if you create a component that uses a ScrollingPanel, and then place that component inside another Panel, or component extended from Panel.

   5. TabPanel

      Symantec's TabPanel component has confused many Visual Café users. However it is pretty simple to use really. Follow these steps to get started:

      1. Drag the TabPanel component onto the Form Designer.
      2. For each tab you wish to have, drag a Panel component onto the TabPanel. Make sure you don't place the new Panel components within each other, but drop them outside of the internal tab areas. Alternatively you can more easily drop the Panel components onto the TabPanel component object in the Project window.
      3. Once you have the number of tabs you desire, you can label each tab by selecting the TabPanel component and entering Tab Labels through the Property List window. Use Ctrl-Enter to move to a new line when entering the tab labels.
      4. You can switch which tab is on top in the Form Designer by clicking on the tab labels.
      5. Version 1.0d also allows you to set a default tab.

      A few useful methods are:

      > showTabPanel(int) - to display a specific tab (zero indexed). Note: if you have nested TabPanel components, doing a showTabPanel(int) on the internal TabPanel will not jump display into that level, but instead prepare a subtab for display when the outer tabs are shown.
      > getPanelLabels() - to return a String array of tab labels.
      > getCurrentPanelNdx() - to return the tab index of the current tab. You could use this in conjunction with getPanelLabels() to get the current tab's label, for example.

   6. Timer

      The Timer component is not very well documented in Visual Café. However the following information should help people get started with it.

      Relevant variables:

      - delay - The amount of time in milliseconds before the Timer will fire.
      - target - The component that receives eventType when the Timer goes off.
      - repeat - Determines whether the Timer will be reset after it goes off.
      - eventType - Event to send target when timer goes off.

      Relevant constructors (as taken from source code):

               Component  target;

               int        eventType;

               boolean    repeat;

               boolean    repeating;

               boolean    execute;

               Thread     thread;

               int        delay;

               public Timer(Component t)

               {

                   this(t, 1000);

               }

               public Timer(Component t, int d)

               {

                   this(t, d, false);

               }

               public Timer(Component t, int d, boolean r)

               {

                   this(t, d, r, Event.ACTION_EVENT);

               }

               public Timer(Component t, int d, boolean r, int e)

               {

                   target    = t;

                   delay     = d;

                   repeat    = r;

                   execute   = false;

                   thread    = new Thread(this);

                   eventType = e;

                   thread.start();

               }

   7. Steps for creating and using Java components in Visual Café

      Disclaimer: These instructions are not official Symantec guidelines and ignore the setting up and use of features such as Description (.desc) files. The steps below focus on creating Panel components, and attempt to circumvent certain Visual Café shortcomings.

      1. Component Creation:

         1. Create a new class, extended from a base class. In Visual Café select Insert/Class, name the class, set the path or let it default to your project folder, and select the base class to extend from. This will create an "Object" in your project. Double-click on the object name to bring up a form for GUI design work. Double-click on the form when it displays to display the underlying code. This should look like the following:

                class MyPanel extends java.awt.Panel

                {

                }

            It is important that this is a "public" class, so add that keyword. You also need to add comment tags that Visual Café uses to identify where to stick code it generates. Finally add the "constructor method". You needn't add any other code at this time as Visual Café will add the "import" statement, and other code it needs. Your code should then look like the following:

                public class MyPanel extends java.awt.Panel

                {

                    //{{DECLARE_CONTROLS

                    //}}

                    public MyPanel() {

                        //{{INIT_CONTROLS

                        //}}

                    }

                }

         2. You can now start placing components such as buttons, textfields, labels, etc. in your component panel. Visual Café will update your code as you do so. If you had not added the comment tags, as described in the previous step, no code would be generated during GUI design.

         3. In some case you will have to comment out an addNotify( ); statement that Visual Café adds to the "INIT CONTROLS" section of its generated code. Since this is always re-added each time you make a change to the GUI (i.e. each time Visual Café regenerates the underlying code), you'll want to comment it out after the last change you make. There is no way to disable the generation of addNotify( ); statements.

         4. Record on paper the final Width and Height of the component when you are done. This information will be used to set an initial component size when you add the component to the Component Library (step B.iii).

         5. Save the class using File/Save MyPanel.java (or some other means).

         6. Compile MyPanel.java. You can do this at a DOS prompt or by compiling/executing the project as a whole. You may want to put your component .class file in a central common component folder. You'll also want to make sure that your CLASSPATH includes the folder you store the .class file in (either by setting the Class Path for your project, or updating the CLASSPATH environment variable in \VisualCafe\Bin\sc.ini). You can simply embed your system CLASSPATH environment variable within the path Visual Café uses using the %CLASSPATH% notation.

      2. Loading components into the Component Library:

         1. Select Insert/Component into Library... and find the .class file you just created. Select it and click the Open button.

         2. Select the Component Library group to insert the component into and click OK.

         3. You now can set initial Width and Height properties for the component which will be used each time you select it for use. Click on the component in the Component Library window to display its properties in the Property List window, and modify the component Width and Height to be those you would have recorded in step A.iv. This approach does not imply that other approaches might not be acceptable or better.

         4. Right click on the component palette toolbar and select Customize Palette... From the Available Components canvas, select the new component and then select the destination palette in the Palette canvas, then press the Add button. Press Apply and/or press OK. You are now ready to use the component.

      3. Using the component:

         Components will typically be added to Frames or Panels, however you can also choose to work within an Applet. Simple drag the component from the Component Palette into your GUI Form Designer window. This will instantiate an object based on that component class. Modifications to the component class made separately will equally affect Frames and Panels the component resides in. Interaction between "complex" components and other components will have to be coded manually.

2. ### Other Visual Café Grinds

   1. Images not showing in ImageButton components

      A common problem people have when dealing with components that display images, like the ImageButton component, is that the path to the image at run time may differ from that at design time. Typically the desired run time path is a relative URL like "images/image.gif", whereas the one at design time might be "file:/C:/mydirectory/images/image.gif". If you don't need to see a design time rendering of the image, then you are best off using the run time path at all times, otherwise you may have to always modify the path before compiling the run time version.

      Note: To enter a relative path you need still need to bring up the URL dialog, as you cannot enter the URL directly into the Property List window. Symantec provides the following lines of code to handle relative URLs:

              	// Take out this line if you don't use symantec.itools.net.RelativeURL

                  symantec.itools.lang.Context.setDocumentBase(getDocumentBase());

   2. Deleting rows in MultiList components

      There is no direct way to delete one row from a MultiList component. Instead many have suggested you clear() and reload the rows you wish to keep.

   3. Package statements impeding code generation

      Version 1.0 and 1.0c Bugs:
      There is a problem with code generation when the class is part of a package.

      Addendum:
      This bug has been fixed in version 1.0d!

   4. Accessing card Panel components of cardlayouts

      One of the more obscure navigational mechanisms in Visual Café concerns navigating through different card Panel components of a cardlayout in the Form Designer. To move from one card Panel to another you have to right mouse button click on the card Panel in the Form Designer. A menu option will then allow you to either move to the next or previous card Panel. You can rotate through all card Panel components this way. One problem with this can occur when you have other components entirely covering the surface of a card Panel, at which point you will be unable to select the card Panel from the Form Designer, and thus unable to move to another card. Therefore always ensure you have a area of card Panel "real estate" available to click on if you can. Hopefully Symantec will eventually provide an alternative mechanism for moving through card Panel components.

   5. Special Visual Café code generation blocks

      Visual Café will generate code for you based on changes you make in the Form Designer or Property List window. It places the generated code in code blocks delimited by special comment tags:

          //{{DECLARE_CONTROLS

          //}}

          //{{INIT_CONTROLS

          //}}

      You can move these special comment tag delimiters to anywhere in your source file, as long as you don't nest them. If you remove the tags, Visual Café will not be able to generate the code that would have been placed within them. The code generated by Symantec within these tags should be left alone. Furthermore, you should avoid adding extra code within the tags as it will be deleted the next time the code is regenerated. There are other code blocks and special comment tags Symantec uses to delimit them, such as for menus and interactions.

      Important: There is a 32K limit to the amount of generated code Visual Café can write within either the DECLARE_CONTROLS and INIT_CONTROLS code blocks. Once that limit is reached, you will have to resort to mechanisms that will limit your code, such creating components.

   6. Further info on Visual Café code-visual synchronization

      Ed Bassett (ebassett@dtlnet.com) has submitted a number of useful insights and explanations about how Visual Café manages the synchronization of code with Form Designer and Property List changes. Ed writes:

      > Comments that look similar to the delimiters used for VC's autogenerated code blocks can cause the synchronization to break. Specifically, comments that have double braces following the double slashes are the troublemakers. The difference between comments that cause a break and ones that don't is kind of subtle. Here are some examples:

      > Blocks like this work fine:

      >         //{{ This works -- there are characters following the opening braces

      >         //}}

      > Blocks like these cause a synchronization break:

      >         //{{

      >         // This doesn't work -- there are no characters on the first line

      >         // following the braces

      >         //}}

      > or:

      >         //}} This doesn't work -- there are no opening braces

      > or:

      >         //{{ This doesn't work -- there are no closing braces

      > How did I figure this out? Call me a silly newbie or a consistency freak, but for some reason I decided to make some comment blocks for my custom code that looked like (i.e., had a similar style as) the VC-generated comment blocks. This worked fine for a while...until I messed one up and made it look like this instead:

      >         //}} This comment block starts with closing braces; oops, it doesn't work!

      >         //}}

      > Then my code and the visual tools lost synchronization...and it took me quite a while to figure out what I had done wrong.

      > VC provides no warning and no real way to track down why the code doesn't parse. It compiles and runs fine (since the comments comply with the Java language spec). However, the visual tools and the code are no longer synchronized.

      > Lesson for users: despite the Java language spec, do not make comment blocks in VC that include the double-slash--double-brace combination unless you are VERY CAREFUL to form them just right so VC doesn't get confused by them.

      > BTW, for curious users out there...as part of trying to fix the code synchronization problem caused by my comment delimiters, I found out a bit about the behavior of the "two-way editing" tools provided by VC. Here are some observations.

      > Changes made in the source code editor:

      > 1. Sensical edits (e.g, changing a property value, adding/deleting a component) made in the source code window will appear on the Form Designer as soon as you select "Project|Parse All" or click on the Form Designer window. These changes that manifest themselves in both source code and visual tools are "permanent" in the sense that they will not be overwritten when the code is re-generated (see below).
      > 2. Non-sensical edits made to the source code window (e.g., hacking up a line of code so it's no longer legal Java) will cause the synchronization to temporarily break. Selecting "Project|Parse All" or clicking on the Form Designer will cause NO update of the visual tools while the synchronization is broken.
      > 3. Some changes (e.g, re-ordering two lines of code or adding new code with no visual manifestation) will work fine, but are only temporary. Since they have no manifestation in the visual tools (i.e., they do not change the appearance or properties of an object), they will be overwritten when code is re-generated.
      > 4. Incomplete edits (i.e., creating a new component in the "INIT_CONTROLS" block but not declaring it in the "DECLARE_CONTROLS" block) that have a visual manifestation will show up in the visual tools when you select "Project|Parse All" or click on the Form Designer window. The "missing" code will not be filled in until the code is re-generated (see #1 below). This can cause an error if you try to compile at this stage. You can either complete all the code manually, or cause a code re-generation by going to the visual tools and making some change to any object.

      > Changes made in the Form Designer:

      > 1. Any change to an object will cause the whole autogenerated code block (i.e., code for all objects) to be re-created. This occurs immediately without any need to run "Project|Parse All" or to click on the source code editor window. Any changes you made during a temporary synchronization break (see #2 above) or changes that have no visual manifestation (see #3 above) will be overwritten.
      > 2. If the synchronization is broken for reasons other than non-sensical code in the autogenerated block (for instance because of bad comment blocks as described above), then changes made in the visual tools will NOT cause a code regeneration. This provides a good way to test if your synchronization is broken: with both the source code and Form Designer windows visible, make a change in the Form Designer (e.g., moving a component) and see if the corresponding code (e.g., the coordinates in the reshape arguments) changes. If nothing happens, it is likely your synchronization is broken.

      Thank you Ed!

   7. Dealing with the addNotify() statement

      A major annoyance in Visual Café is that it always generates an addNotify(); statement, when much of the time you don't want one. The result is that either your code fails because the addNotify() was called before a peer was created, or else your component class prematurely displays floating on your desktop instead of its intended position in your GUI. You can try overriding the addNotify() method, or else remove or comment the statement out. To override the addNotify() method add the following code to your class:

          public void addNotify() {

              if (getParent() != null) super.addNotify();

          }

      If you choose instead to remove or comment the addNotify(); statement out, be aware that Visual Café will eventually undo your change, because the code falls within its special comment tags that delimit the section of code that gets regenerated after every change you make (see previous topic).

      Addendum:
      Indications are that Symantec may replace the addNotify(); code that Visual Café generates with `if (getParent() != null) addNotify();` instead. This should get around the above problems. Hopefully this change will be in a future patch.

   8. Context based Visual Café menu options

      One peculiarity in Visual Café that might take a little getting used to, is that the menu options you are presented with depend on the the context of your action, or which window (Project, Property List, Form Designer, etc...) you happen to have active at the time. For example, the Object menu options become available once you've created a new project, or opened an existing one, and Layout menu options are accessible only when the Form Designer window is selected/active. There are some inconsistencies to this approach, however. For instance, to add a component to the Component Library (see Steps for creating and using Java components in Visual Café) you want to use the Insert/Component into Library... menu option. However, Visual Café requires that you have the Project window open for you to be able to select Insert options, even though you may not be working on a project, but simply want to add components to the Component Library. A good rule of thumb if you can't find a menu option, or find that it is disabled, is to click on a work area window to see if it appears, or becomes enabled.

   9. Form Desinger grid spacing

      Grid spacing can be controlled from the Layout menu option. However, this menu option is only accessible when the Form Designer is open and active. Once visible, select Grid Options.... A small dialog will appear with which you can change the size of the grid spacing (to any width and height pixel value from 2 to 32). You can also choose to have objects in the Form Designer snap to the grid. Note: The Form Designer grid is limited to top level components. You will not benefit visually from grid spacing within container objects.

   10. When in doubt check the code!

       Symantec has supplied all the source code for its classes in the \VisualCafe\Java\Src folder. It can sometimes be very useful to look directly at the source code when trying to determine what's going on. Although you may be tempted to make changes directly to that code, you should not. Better instead to subclass and override methods, or else notify Symantec about possible bugs or improvements that you have discovered.

3. ### Useful Java Info

   1. JDK 1.02 Event Differences by Browser

      The following table highlights how different browsers respond to different events for various components. A lot of JDK 1.02 problems with events can be explained by closely examining the information below.
      (Note: The above table originates from Java- AWT: Is it really cross-platform? by Dave Schultz.)

   2. Tabbing from component to component

      An unfortunate limitation of JDK 1.02 is the lack of tabbing support. When I say tabbing I am not referring to TabPanel components, but to the ability to tab back and forth between fields and buttons using the Tab key. Symantec has provided a KeyPressManagerPanel component that you lay all your components on, and which should address most tabbing needs. However KeyPressManagerPanel is hard pressed when it comes to handling complex component structures (such as components within components), and offers up unsatisfying results in such cases. It also doesn't handle movement within radio button or checkbox groupings, which in a typical Windows environment you should be able to use the arrow keys to move within.

      To address this problem I have extended a TabOrder class that was originally written by Bryan Buchanan. The basic approach is that a tab order of visible, enabled and editable components is stored in a Vector. You either hard code the addElement() statements for your Vector (the basic usage), or use various methods that will determine for you the components that can be tabbed to (advanced usage). I have produced a javadoc help file which contains detailed instructions about how to implement tabbing using the TabOrder class. You are also welcome to the source code. Please retain all authoring comments.

      > TabOrder.class - The TabOrder class file.
      > TabOrder.java - The TabOrder Java source code file.
      > TabOrder javadoc help - The javadoc generated TabOrder HTML help file.
      > ZIP Archive - All of the above files in a ZIP archive.

   3. No Horizontal Scroll Bars in TextArea in Netscape

      A known JDK 1.02 problem in Netscape is that the horizontal scroll bar for a TextArea never displays.

   4. Choice and List components not correctly positioning themselves

      On Microsoft Windows platforms, Choice and List components incorrectly display their size and position if not used in conjunction with a layout manager. This is a JDK 1.02 problem. One solution is to place the Choice or List component inside a Panel of the same size as the component. This restricts the component, as it has nowhere to go, and thus positions where you position the Panel. Another work around is to reissue a reshape() in your code after the component has been "added". You would do this outside of Visual Café's special comment tag delimiters.

   5. Label components not supporting colors

      On Microsoft Windows platforms, Label components do not support foreground and background colors. However you should be able to use the Visual Café WrappingLabel as a work around. WrappingLabel extends from Canvas which allows you to apply color.

   6. Using javadoc

      SUN's JDK comes with a very useful tool called javadoc. Javadoc will look for specially formatted comment blocks within your source code and generate very nice, cross referenced, and easily updated help files in HTML format. For an example sample I suggest you look at the source code and javadoc HTML associated with my TabOrder class discussed above. For details about the syntax to follow when creating javadoc comments in your source code, and in generating the HTML, read the javadoc - The Java API Documentation Generator document.

   7. Little known Netscape Java Console commands

      When trying to debug your applets in Netscape, a few little known commands can be issued while in the Java Console that could help you out. There are 10 "applet debug level" settings that will provide you with extra information, such as which class files are being loaded. To activate these simply type "0" through "9" on your keyboard while the Java Console is the active window. The Java Console will echo back the applet debug level selected. In addition "D" provides extra information about your applet, "F" echoes back "Performing finalization...", and "G" can be used to perform garbage collection.

      Netscape Communicator (NN 4.0) has an extended set of Java Console commands to choose from. They are:

            c:   clear console window

            d:   dump applet context state to console

            f:   finalize objects on finalization queue

            g:   garbage collect

            h:   print this help message

            m:   print current memory use to console

            q:   hide console

            s:   dump memory summary to "memory.out"

            t:   dump thread info to "memory.out"

            x:   dump memory to "memory.out"

            X:   dump memory (detailed) to "memory.out"

            l:   save all classes loaded by an applet to a directory

            0-9: set applet debug level to <n>

4. ### Miscellaneous

   1. Redistributing Symantec's JIT and Components

      According to Symantec you are NOT allowed to redistribute Symantec's JIT, just the classes you create with Visual Café. Symantec's components are redistributable.

   2. Publishing your work

      When executing your applet or application outside of Visual Café you need to make sure that any Symantec classes can be found. You should copy the symantec class file directories at \VisualCafe\Java\Lib to the directory your HTML file, or startup class file resides in. For example, if your code is in the \MyCode directory, you should copy the entire \VisualCafe\Java\Lib\symantec directory tree so that you have \MyCode\symantec. You can determine which class files you don't need, using Symantec's bundler.exe program for instance, and remove those files should you so desire (see the next item for more on bundler.exe).

      With JDK 1.02 applets in Netscape, you can also choose to create an uncompressed zip file containing your class files. The benefit here is that to load all your class files, the browser will only have to make one connection to your server, instead of one connection for each class file, which does add considerable overhead at startup. You can use a product like Winzip to make your zip file. If you consider the directory containing your HTML file, or startup class file, as your root directory, your should make sure that you save path information relative to this root directory. For example, if you include the TabPanel component, the path should read "symantec\itools\awt\" in your zip file. Select the "Save Extra Folder Info" option in Winzip to ensure paths are stored. Again, you can restrict yourself to only those classes needed by your applet. To correctly access class files in zip files use the "ARCHIVE" attribute in the APPLET tag, like so:

          <APPLET CODE="MyApplet.class" ARCHIVE="MyClasses.zip" WIDTH=200 HEIGHT=200>

          </APPLET>

      Netscape will search for "MyApplet.class" in the "MyClasses.zip" file. You should also know that Microsoft IE browsers don't understand the ARCHIVE attribute (Microsoft instead wants you to create CAB files - go to Microsoft's site concerning the creation of CAB files). So you may want to also supply the class files the unzipped way. MS IE will then be able to find everything it needs. It is conceivable that should you create a CAB version, and a zipped version, you may still want an unzipped version for browsers that don't understand CAB or ZIP files! Hopefully one day the cold war will be over.

      Up until now, if you wanted to distribute a Java application, the remote desktops would have to have the JDK class files, and any third party class files in their CLASSPATH, requiring local configuration. SUN has recently announced a runtime version of the JDK, which would be lighter weight as it would not include such things as the debugger or compiler. There is also the firmware solution, the Java "chip", which is being incorporated into many network computers (NCs). Another approach might be to consider using Marimba's Castanet. The Castanet Tuner can become your runtime environment, eliminating the need to distribute the JDK classes, and minimizing the impact of distributing you application and any updates.

   3. Determining what classes you use with bundler.exe

      Visual Café comes with what Symantec calls an "early version" of a utility called "bundler". Bundler will create a list of all class files, including base JDK classes, Symantec classes, and third party classes, that are needed when executing your applet or application. To use it, in DOS, using the file names in the previous topic's example, run the following:

          \VisualCafe\Bin\bundler.exe -make -cdb MyApplet.cdb -depend listname.dep MyApplet.java

      where MyApplet is your starter class file, and listname.dep is where your output will go. When looking at the list of class files in listname.dep, you can ignore all the base JDK classes, as those will be available through your browser. For further information on the bundler utility, check out the \VisualCafe\readme.txt file.

   4. Determining which version of Visual Café you have

      This one is often asked, and of course the answer is simply to select "About Visual Café" from the "Help" menu pulldown. The version number displays in the bottom left corner of the splash graphic that appears.

   5. Getting the latest version

      Symantec released the Visual Café 1.0d patch 8-Apr-97. It is available from ftp://itools.symantec.com/pub/windows/vcafe/. The update patch can be had in two versions, one that patches version 1.0, and one that patches version 1.0c (a previously available "preview" release). The patch fixes a lot of bugs, so if you don't have it you should get it!

   6. Visual Café Books

      Symantec has indicated that a number of books are in the works. The table below lists these plus info from Amazon.com, and other sources as of 28-Apr-97:

      BOOK | PUBLISHER | AUTHOR | INFO
      --- | --- | --- | ---
      Discover Visual Café | IDG Books | Wall & Griffith | ISBN: 0764530623; $24.99
      Synopsis: Get up and running with this hot new development environment for Java. Readers learn about the Visual Café features they'll use the most in a practical, straightforward approach. The CD contains all sample code and tools for easier programming.
      Visual Café Personal Trainer | IDG Books | Unknown | No longer listed.
      Visual Café Programming FrontRunner | Coriolis | Dan Shafer | ISBN: 1576100596; $29.99
      Synopsis: Visual Café is the new visual Java development environment created by Symantec. With Café, novice Java programmers can get up to speed in no time using features like Cafe's AppExpress tool. This hands-on guide is designed to get Café users up to speed quickly, yet at the the same time provide unique insights, tips, techniques, and real-world programming examples that developers are hungry for.
      Symantec Visual Café Sourcebook | John Wiley & Sons | Jardin & Dixon | ISBN: 0471178047; $39.99 (Available June 1st)
      Synopsis: This book teaches programmers how to use Symantec Visual Café to create Java applets. For Java neophytes, the book also provides a thorough introduction to the language. Advanced Java programmers can learn how to use Visual Café to create their own Java development tools.
      Author's Note: Symantec Visual Café Sourcebook is geared for novice programers and advanced developers alike. The book covers all aspects of Java development, from creating an Applet to muti-threaded debugging. Little is provided in the way of a Java language reference. However, I teach you how to develop Java Applets and applications without getting too much into the code. You will like it! And here is an open offer: If you get stuck, drop me a line and I would love to help you. Cary A. Jardin cjardin@xprime.com
      Visual Café Programming for Dummies | IDG Books | Tittel & Gaither |
      C/S Developers' Guide | M&T Books | David McClanahan |
      Teach Yourself Java in Visual Café in 21 Days | sams.Net Publishing | Mike Cohn | ISBN: 1575213036; $39.99 (Available June 1st); Includes a CD
      Synopsis: Teach Yourself Visual Café in 21 Days teaches the reader how to program with Java to create both applets and applications. It will present information on what Visual Café is and how to use it to develop. The CD-ROM contains all the source code and sample programs from the book.
      Visual Café Unleashed | sams.Net Publishing |  |
      Visual Café | Addison Wesley Germany | Guido Krueger |
      Visual Café Pro | WROX Press UK | Roger Lee |

      In addition, I have been told that MindQ has a Visual Café CBT for $39 (introductory price).

Visual Café Tips, Copyright © 1997 - Daniel A. Kirkdorffer

To Daniel Kirkdorffer's (DanKirkd@aol.com) Gallimaufry