TabSplitter Release Notes
The following list describes the changes made between TabSplitter version 1.0 and version 2.0. I attempted to minimize the user-impact of changes as much as possible, but it wasn't always possible...
Note that TabSplitter is still free for any use you desire (as long as you don't sell it as its own product.)
Updates since 2.0 Release:
v2.0.19 - 2/28/98
This version enables the popup menu when executing under VisualAge for Java. The popup menu bug that was introduced in VisualAge for Java version 1.0 patchset2 has been corrected. This version of TabSplitter will work with VisualAge for Java in either of the following configurations:
- VisualAge for Java version 2.x (see note on main page)
- VisualAge for Java version 1.0 without the patchset 2
- VisualAge for Java version 1.0 patchset 2 with the following fix:
- ftp://ftp.software.ibm.com/ps/products/vajava/fixes/VaJavaFixManager.ZIP
- ftp://ftp.software.ibm.com/ps/products/vajava/fixes/patchset2/1EP17UH.zip
- (there's an html file in the VaJavaFixManager.ZIP file that describes how to apply the fix.)
v2.0.9 - 2/18/98
This version corrects the following problem and adds a feature:
- SplitterLayout's SplitterBars sometimes left a residual dark gray area after being dragged. This has been fixed.
- SplitterBars are now highlighted (in yellow -- I'll make it customizable later) when the mouse rolls over them.
- A SplitterLayout demo page was added.
v2.0.6 - 2/9/98
This version was released to work around VisualAge for Java Patchset 2 popup menu bug. This version is only available as a VisualAge interchange file, and should only be used if you are running VisualAge for Java v1.0 patchset 2. It will disable popup menus when running TabSplitter inside VisualAge. The popup will be available when running outside VisualAge for Java. (It checks for a uvm class -- if you have exported the uvm packages, it will disable popups there as well.) The file to download is tabsplitter-sp2.dat.zip
v2.0.5 - 1/30/98
This version corrects the following problems:
- Adding tab text via setTabText(int, String) didn't check to see if tabText was null or even big enough to hold the indicated position. Doh!
- When merging tabs, the newly-merged components were setVisible(true) before the CardLayout's show(String) method was called. This is a problem, because that show(String) method doesn't do anything if a component is already visible, which means it doesn't setVisible(false) the previously-selected components, which means that if you tried to switch tabs after certain merge scenarios, nothing would happen...
User Impacts
There are three things which will impact your use of TabSplitter:
- The package has changed from com.magelang to com.magelang.tabsplitter. I decided to do this to make it easier to organize the MageLang support classes (com.magelang) when several MageLang developers may be working on code at the same time. Sorry for any inconvenience this may cause.
- The tabColor property has been deprecated. It will now set/get the first element of the tabColors property. Use tabColors instead...
- Several users had added their own methods to select tabs, handle events and other fun things. Unfortunately I could not implement the changes in the same way that everyone wanted. If you need help or advice when converting from TabSplitter version 1.0 to version 2.0, please let me know!
Heads Up!
TabPanel and TabSplitter are not thread-safe! This means that if you have some thread adding or removing components and are selecting components at the same time, results can be unpredicatable.
The reason I don't make it threadsafe by default is that most usages probably won't require it. Be careful if you muck with it through multiple threads (and remember that the AWT event-processing thread is a separate thread...)
If you want to make TabPanel/TabSplitter thread-safe:
- Make all public methods synchronized
- Change fireTabSelected (in TabPanel) to the following code:
protected void fireTabSelected(TabSelectionEvent e) { if (aTabSelectionListener == null) return; Vector targets; synchronized(this) { targets = (Vector)aTabSelectionListener.clone(); } int currentSize = targets.size(); for (int index = 0; index < currentSize; index++){ TabSelectionListener l = (TabSelectionListener)targets.elementAt(index); if (l != null) l.tabSelected(e); } }
Known Problems
- Documentation is still a bit light... I decided to get the components out so people can bang on them a bit and get the docs done as soon as I had a chance.
- I haven't had time to test serialization of it. As far as I know, the right stuff has been made transient, and I know it doesn't throw an exception during writeObject. I briefly tried to readObject it and got an exception about "expecting code". I'll have to play with it later...
- Internet Exploder version 4 seems to have a problem with the new event model. It seems that when you press the right mouse button over an unselected tab to bring up the pop-up menu, it selects the tab. This behavior does not happen under Netscape
- It seems that BeanBox and Visual Cafe for Java 2.1 do not like my properties very much. Per my read of the Bean spec, a bean builder tool should walk up the inheritance hierarchy of the bean and get properties from each class'
BeanInfo. I generated BeanInfo classes in VisualAge for Java and all seems well there.
VisualCafe and BeanBox only display the properties for the direct BeanInfo, and not those defined in the superclass. This means that if you add a TabSplitter, you won't see the properties such as tabColors, borderColor and so on. I'm not sure how to handle this yet, so I'll have to play around in these environments for a bit. - Visual Cafe for Java 2.1 does not display the Tab Color editor properly. It comes up ok on VisualAge for Java and the BeanBox.
- In Visual Cafe for Java, I think you'll have to set the properties of the TabSplitter manually in your code.
Changes
Ok. Here's the list of stuff that's changed since version 1.0:
- TabSplitter has been split into two classes: TabPanel and TabSplitter. TabPanel provides all the run tabbed panel behavior, while TabSplitter adds the merging functionality.
- TabPanel has been designed to be standalone; you do not need any other classes to run it (beside the JDK). Several people asked for a version without merging and standalone. Here it is, and the .class file is only around 11K. (To use TabSplitter you'll need all classes in the com.magelang.tabsplitter package.)
- Directional arrows are now only shown when they are needed. These are the little triangles that point left and right and are used to slide the tabs so you can see those that are hidden. The left one will only appear when the first visible tab is not the first tab, and the right one will only appear if the tabs get chopped at the end of the row.
- When dragging a tab (in TabSplitter), if you drag it over a directional arrow the tabs will scroll. This allows you to merge two tabs that aren't visible at once.
- A tabColors property has been added, superceding the old tabColor property. The tabColors property is an array of colors, and can be used to give each tab a different color. If you have more tabs than colors, the colors will be reused again (in order). This one was especially for all you OS/2 and Lotus fans!
- A custom property editor for tabColors is provided. It appears as a TabPanel where each tab contains a simple color selector. (For now, just the "basic" colors. I'll update it soon to allow SystemColors and RGB values as well.) This property editor should work in most bean editors. I developed it in VisualAge for Java, and tried it under Symantec Visual Cafe 2.1. Seems to work fine in both cases. (Though I must complain that VisualCafe wimps out a bit -- it will not display the paintValue version of the properties; it just says "Custom").
- SplitterBar orientations can now be changed. Each SplitterBar used in TabSplitter has a little "x" button on it that, when clicked, will change the splitter orientation from horizontal to vertical and vice-versa.
- A popup menu will appear when the right mouse button (Meta-click on the Mac) is pressed over the tab area. This menu contains a list of all tabs (which will directly jump to the selected tab) and (for TabSplitter only) the "swap orientation" option.
- TabText determination is now smarter/trickier. It works as follows:
- If the component had text passed into its add() call, and that text is not the same as the component's getName() value, that text will appear on the tab. Otherwise, continue to step 2.
- If the component implements TabNamedComponent, its getTabName() method will be used to get the text that appears on the tab. Otherwise, continue to step 3.
- If the tabText property was set and is non-null for tab number in question, its value will be used. Otherwise, continue to step 4.
- Call getName() on the component and use that value.
- Tabs now resize based on the font set for the TabPanel/TabSplitter.
- A silly bug regarding placement of the SplitterBar "ghost" when dragging it has been resolved.
- When merging and separating tabs in TabSplitter, order is preserved as much as possible. When all tabs are separated, the order of the components should be the same as when they were originally added to the TabSplitter. When two tabs are merged, their order within the SplitterPanel is the same as their respective order before the merge.
- show() methods are now provided to programmatically select a tab to display. These methods are:
- show(int n)
- TabPanel will show the nth tab (the first is tab 0)
- TabSplitter will show the tab that contains the nth component added to the TabSplitter
- show(Component n)
- Show the tab that contains the referenced component
- show(String name)
- Show the tab that contains the component that has the named text as its tab. Note that TabSplitter will show a SplitterPanel tab if the named tab has been merged into it.
- show(int n)
- An event, TabSelectionEvent, is fired any time the selected tab is changed. This event lists the name, number, and visible components on the selected tab.
- Looks like I got component removal to work properly. I think it needs more thorough testing to be absolutely sure...
Please email Scott Stanchfield with any problems immediately! I'll get them fixed as soon as I can so I don't have to type upa description under "known problems"...