Purpose
Here is a text item's PJC that can be used in multi-records Forms tables.
It allows to have a coherent behaviour in a multi-record table for items that record number are greater than the number of records displayed.
In the standard way, you can set an Implementation Class to a PJC that extends the corresponding Forms item type (VTextField in this example), but you cannot use the Set_Custom_Property() built-in on a record number greater than the number of records displayed block's property.
For instance, it this property is set to 10 (ten records displayed by the block), the following instruction will raise an error:
Set_Custom_Property( 'BL.TEXT_ITEM', 11, 'SET_PROPERTY', '...' );
This is a problem because you cannot use a PJC on a multi-record block if the number of records fetched or created is greater than then number of records displayed.
This PJC can be used in this case because it holds a table of objects for each PJC's instance.
You can use it to give each record a special color (without having to use the Set_Item_Instance_Property() built-in with tens of visual attributes), or also have one different hint and tooltip for each record (which is not possible in standard).
How it works:
Within the PJC:
each PJC's instance (10 in this example) can handle 0 to n physical records.
You can see, on the screenshot above that the first line displays the record #9. If you scroll the block, it would display the 10th, then the 11th, and so on.
So, each PJC instance hold a table of objects. Each physical record must have a corresponding object in this table.
In this sample, each object contains the following values:
. tooltip
. hint
. background color
. foreground color
. int value
. float value
. string value
. label (button)
. font (button)
. icon (button)
. enable (button)
. visible (button)
Within the Forms module:
The trick is to re-draw all the displayed items (the page set) with their corresponding values.
This job is done in the When-New-Record-Instance block-level trigger:
Declare
LN$Pos pls_integer ;
LN$Max pls_integer := Get_Block_Property( :system.current_block, RECORDS_DISPLAYED) ;
LN$Top pls_integer := get_block_property( :system.current_block, TOP_RECORD) ;
LN$Rec pls_integer := Get_Block_Property( :system.current_block, CURRENT_RECORD) ;
Begin
---------------------------------------------------
-- Calculate the cursor position in the page set --
-- cannot be greater than the number --
-- of records displayed --
---------------------------------------------------
If get_block_property('DEPT',TOP_RECORD) > 1 Then
LN$Pos := LN$Rec - get_block_property('DEPT',TOP_RECORD) + 1 ;
Else
LN$Pos := LN$Rec ;
End if;
--------------------------------
-- Handle the graphic aspects --
-- for the entire page set --
--------------------------------
For i In 1 .. LN$Max Loop
Set_Custom_Property('DEPT.DNAME', i, 'PAINT_RECORD', to_char((LN$Top+i)-1) );
End loop ;
Synchronize;
End;
Post-Query trigger:
Declare
LN$Pos pls_integer ;
LN$Rec pls_integer := Get_Block_Property('EMP', CURRENT_RECORD) ;
LN$Max pls_integer := Get_Block_Property('EMP', RECORDS_DISPLAYED) ;
LC$C Varchar2(15) ;
Begin
LN$Pos := LN$Rec - (trunc(LN$Rec/LN$Max) * LN$Max) ;
If LN$Pos = 0 Then LN$Pos := LN$Max ; End if ;
If LN$Pos > 0 Then
Set_Custom_Property('EMP.BT', LN$Pos, 'SET_LOG', 'true' );
-- Add the new item --
Set_Custom_Property('EMP.BT', LN$Pos, 'SET_NEW_REC', to_char(LN$Rec) );
Set_Custom_Property('EMP.ENAME', LN$Pos, 'SET_NEW_REC', to_char(LN$Rec) );
-- Set some properties --
Set_Custom_Property('EMP.BT', LN$Pos, 'SET_LABEL', to_char(LN$Rec)
|| ',' || :EMP.ENAME );
If :EMP.JOB = 'MANAGER' Then
Set_Custom_Property('EMP.BT', LN$Pos, 'SET_FONT', to_char(LN$Rec)
|| ',Arial,bold,14' );
Set_Custom_Property('EMP.BT', LN$Pos, 'SET_FGCOLOR', to_char(LN$Rec)
|| ',0,0,255' );
ElsIf :EMP.JOB = 'CLERK' Then
Set_Custom_Property('EMP.BT', LN$Pos, 'SET_ICON', to_char(LN$Rec)
|| ',C:/dev/Forms/PJCBeans/LAF/icons/ic1-16.png' );
ElsIf :EMP.JOB = 'ANALYST' Then
Set_Custom_Property('EMP.BT', LN$Pos, 'SET_ICON', to_char(LN$Rec)
|| ',C:/dev/Forms/PJCBeans/LAF/icons/ic2-16.png' );
End if ;
If :GLOBAL.I > 250 Then :GLOBAL.I := 5 ;
Else :GLOBAL.I := :GLOBAL.I + 5 ;
End if ;
LC$C := To_Char(LN$Rec) || ','
|| To_Char(255) || ','
|| To_Char(255-:GLOBAL.I) || ','
|| To_Char(255-:GLOBAL.I) ;
Set_Custom_Property('EMP.BT', LN$Pos, 'SET_BGCOLOR', LC$C );
LC$C := To_Char(LN$Rec) || ','
|| To_Char(255) || ','
|| To_Char(255) || ','
|| To_Char(255-:GLOBAL.I) ;
Set_Custom_Property('EMP.ENAME', LN$Pos, 'SET_BGCOLOR', LC$C );
Synchronize;
End if ;
End;
When-Create-Record trigger:
Declare
LN$N pls_integer ;
LN$Rec pls_integer := :system.cursor_record ;
LC$C Varchar2(15) ;
Begin
if get_block_property('EMP',TOP_RECORD) > 1 Then
LN$n := :system.cursor_record - get_block_property('EMP',TOP_RECORD) + 1 ;
else
LN$N := :system.cursor_record ;
end if;
If LN$N > 0 Then
Set_Custom_Property('EMP.BT', LN$n, 'SET_LOG', 'true' );
-- Add the new item --
Set_Custom_Property('EMP.BT', LN$n, 'SET_NEW_REC', to_char(LN$Rec) );
End if ;
End;
The Java code
MultiTextField.java MultiProps.java MultiButton.java
The implementation class of the Text Item
oracle.forms.fd.MultiTextField
The implementation class of the Button
oracle.forms.fd.MultiButton
The methods you can call
- Add a new record object
Set_Custom_Property( 'BL.TEXTITEM', disp_rec, 'SET_NEW_REC', 'num_rec' ) ;
- Set the Foreground color
Set_Custom_Property( 'BL.TEXTITEM', disp_rec, 'SET_FGCOLOR', 'num_rec,r,g,b' ) ;
- Set the Background color
Set_Custom_Property( 'BL.TEXTITEM', disp_rec, 'SET_BGCOLOR', 'num_rec,r,g,b' ) ;
- Set the hint
Set_Custom_Property( 'BL.TEXTITEM', disp_rec, 'SET_HINT', 'num_rec,hint_text' ) ;
- Set the tooltip
Set_Custom_Property( 'BL.TEXTITEM', disp_rec, 'SET_TOOLTIP', 'num_rec,tooltip_text' ) ;
- Set a int value
Set_Custom_Property( 'BL.TEXTITEM', disp_rec, 'SET_INT_VALUE', 'num_rec,int_value' ) ;
- Set a float value
Set_Custom_Property( 'BL.TEXTITEM', disp_rec, 'SET_FLOAT_VALUE', 'num_rec,float_value' ) ;
- Set a char value
Set_Custom_Property( 'BL.TEXTITEM', disp_rec, 'SET_CHAR_VALUE', 'num_rec,char_value' ) ;
- Set the label (button)
Set_Custom_Property( 'BL.BUTTON', disp_rec, 'SET_LABEL', 'num_rec,label' ) ;
- Set the font (button)
Set_Custom_Property( 'BL.BUTTON', disp_rec, 'SET_FONT', 'num_rec,Arial,bold,12' )
- Set the icon (button)
Set_Custom_Property( 'BL.BUTTON', disp_rec, 'SET_ICON', 'num_rec,/icon.png' )
- Set button enable/disable
Set_Custom_Property( 'BL.BUTTON', disp_rec, 'SET_ENABLE', 'num_rec,false' )
- Set the button visible/hidden
Set_Custom_Property( 'BL.BUTTON', disp_rec, 'SET_VISIBLE', 'num_rec,true' )
The methods you can get
Varchar2 := Get_Custom_Property( 'BL.TEXTITEM', disp_rec, 'GET_HINT' ) ;
Varchar2 := Get_Custom_Property( 'BL.TEXTITEM', disp_rec, 'GET_TOOLTIP' ) ;
Varchar2 := Get_Custom_Property( 'BL.TEXTITEM', disp_rec, 'GET_INT_VALUE' ) ;
Varchar2 := Get_Custom_Property( 'BL.TEXTITEM', disp_rec, 'GET_FLOAT' ) ;
Varchar2 := Get_Custom_Property( 'BL.TEXTITEM', disp_rec, 'GET_CHAR' ) ;
Varchar2 := Get_Custom_Property( 'BL.BUTTON' , disp_rec, 'GET_LABEL' ) ;
Varchar2 := Get_Custom_Property( 'BL.BUTTON' , disp_rec, 'GET_FONT' ) ;
The property is read for the physical record number indicated by the SET_INDICE property, so you have to set this property before.
e.g. :
-------------------------------------------------
-- Get the hint of the current physical record --
-------------------------------------------------
Set_Custom_Property('BL.TXT', LN$Pos, 'SET_INDICE', to_char(:system.cursor_record) );
Message(Get_Custom_Property('BL.TXT', LN$Pos, 'GET_HINT' ));
The sample dialog
. Download the pjcmultirec.zip file
. Unzip the files
. copy the multirecord.jar file in the /forms/java directory
. Edit your /forms/server/formsweb.cfg file to add the jar file
. Open the PJCMULTIREC.fmb module (Oracle Forms 9.0.2)
. Compile all and run the module