Purpose
This is a Javabean component that displays a JTable inside/outside of a Forms module.
It allows saving the data modified through the JTable into the database.
(A special version - fjtable16.jar - permits to sort the JTable on any column, if you use the Sun Java Plug-in 1.6 or later)
The java code
FJTable.java
Forms configuration
- . Copy the fjtable.jar file in the /forms/java directory
(If you use the Sun JRE 1.6, use the fjtable16.jar instead that allows sorting the JTable) - . Edit the /forms/server/formsweb.cfg file to add the jar file to the archive and archive_jini tags
with JInitiator or Sun Plug-in < 1.6
archive_jini=f90all_jinit.jar,……,fjtable.jar
archive=f90all_jinit.jar,……,fjtable.jar with Sun Plug-in >= 1.6
archive_jini=f90all_jinit.jar,……,fjtable16.jar
archive=f90all_jinit.jar,……,fjtable16.jar
Implementation Class property
oracle.forms.fd.FJTable
Properties you can set
The horitontal/vertical lines
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_HORIZONTAL_LINE', 'true|false' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_VERTICAL_LINE', 'true|false' ) ;
The data separator's character
Set_Custom_Property( 'BL1.JTABLE', 1, 'SETSEPARATOR', 'char_separator' ) ;
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SETSEPARATOR', '^' ) ;
The table frame bounds (for seperate frame)
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETBOUNDS', 'x,y,w,h');
The header colors
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETHEADBG', 'rgb color');
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETHEADFG', 'rgb color');
e.g.
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETHEADFG', '255,0,128');
The selected area colors
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SET_SELECTION_BACKGROUND', 'rgb color');
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SET_SELECTION_FOREGROUND', 'rgb color');
e.g.
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SET_SELECTION_BACKGROUND', '255,0,128');
The number of columns/rows of the table
Set_Custom_Property( 'BL1.JTABLE', 1, 'SETARRAYSIZE', 'cols,rows' ) ;
This method must be used first, before defining header, datas, format, etc.
The columns header
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETHEADER', 'col1[^coln]');
e.g.
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETHEADER', 'EmpNO^Ename^DeptID);
Set the data
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETDATA', 'data1[^datan]');
To seperate the data, use the separator indicated in the SETSEPARATOR() method.
e.g.
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETDATA', '1^Hello there^2000);
Set the relative cell value
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SET_CELL_VALUE', '-sep-Row-sep-Cell-sep-data[-sep-set_focus]');
-sep- is the separator character used in the method. It must be indicated at the very first character, then after, used in the string to seperate the values.
Row is the row number (starts with 1)
Cell is the cell number (starts with 1)
set_focus (not required) set the focus to the cell if true
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_VALUE', '^1^3^new data' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_VALUE', '|1|3|new data' ) ;
-- set the cell value then move the focus to this cell --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_VALUE', '^1^3^new data^true' ) ;
Set the current cell Value
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SET_CURRENT_CELL_VALUE', 'data');
It uses the current selected cell.
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CURRENT_CELL_VALUE', 'new data' ) ;
The table title (for seperate frame)
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETTITLE', 'the_title');
The default date format (java format)
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_DATE_FORMAT', 'format' ) ;
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_DATE_FORMAT', 'dd/MM/yyyy' ) ;
You must use a Java format compatible with the PL/SQL one to avoid insertion/update error at commit time.
Here is a When-New-Form-Instance code sample used for this purpose:
-- Java format masks --
:GLOBAL.LC$DJavaFormat := 'dd/MM/yyyy' ; // date format
:GLOBAL.LC$NJavaFormat := '#0.00' ; // numeric format
:GLOBAL.LC$IJavaFormat := '##########' ; // integer format
-- PL/SQL format masks --
:GLOBAL.LC$DPLSFormat := 'dd/mm/yyyy' ;
:GLOBAL.LC$NPLSFormat := '999,990.00' ;
:GLOBAL.LC$NUMSEPARATORS := '.,' ;
set_application_property(PLSQL_DATE_FORMAT, :GLOBAL.LC$DPLSFormat);
set_application_property(BUILTIN_DATE_FORMAT, :GLOBAL.LC$DPLSFormat);
forms_ddl('ALTER SESSION SET NLS_DATE_FORMAT = '''|| :GLOBAL.LC$DPLSFormat || '''');
forms_ddl('ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '''|| :GLOBAL.LC$NUMSEPARATORS || '''');
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_DECIMAL_SEPARATORS', :GLOBAL.LC$NUMSEPARATORS ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_DATE_FORMAT', :GLOBAL.LC$DJavaFormat ) ;
The default number format (java format)
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_NUM_FORMAT', 'format' ) ;
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_NUM_FORMAT', '###,##0.00' ) ;
The numeric separators
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_DECIMAL_SEPARATORS', 'decimal_character,group_character' ) ;
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_DECIMAL_SEPARATORS', '.,' ) ;
The column types
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_COLS_TYPE', 'type[,type[,...]]' ) ;
each column can have a type description, CHAR, INTEGER, NUMBER, IMAGE or DATE
If this method is not used, the default type is CHAR for every column.
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_COLS_TYPE', 'CHAR^INTEGER^CHAR^CHAR^DATE^NUMBER' ) ;
The column moving property
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_REORDER_COLUMNS', 'true|false' ) ;
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_REORDER_COLUMNS', 'false' ) ;
The column resizing property
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_RESIZE_COLUMNS', 'true|false' ) ;
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_RESIZE_COLUMNS', 'false' ) ;
The row height
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_ROW_PROPERTY', 'HEIGHT|new_size' ) ;
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_ROW_PROPERTY', 'HEIGHT|40' ) ;
The cell property
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'column_name|property_set' ) ;
note : the columns must have been defined by the SETHEADER method, before you can use the SET_CELL_PROPERTY method.
property_set could be one of the following:
-
ENABLE : true or false
-
FORMAT : format mask (Java syntax)
-
ALIGNMENT : LEFT or CENTER or RIGHT
-
FONT : font_name | font_size | font_wheight (N, B, I, BI)
-
BG_COLOR : red_value,green_value,blue_value
-
FG_COLOR : red_value,green_value,blue_value
-
WIDTH : width_in_pixel
-
MIN_WIDTH : minimum width allowed for the column
-
MAX_WIDTH : maximum width allowed for the column
-
RESIZE : true or false
-
TITLE : new_title
Because you can have commas in the property value (in number format for instance), the separator character is | (alt-124) for this method.
e.g.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'MGR|ENABLE|false' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'SAL|FORMAT|0,000,000.00' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'HIREDATE|ALIGNMENT|CENTER' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'EMPNO|FONT|Tahoma|14|B' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'HIREDATE|BG_COLOR|230,230,255' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'EMPNO|WIDTH|50' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'EMPNO|MIN_WIDTH|40' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'EMPNO|MAX_WIDTH|100' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'EMPNO|TITLE|New title' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'EMPNO|RESIZE|false' )
The data colors
-- background color --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SETDATABG', '255,255,255' ) ;
-- foreground color --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SETDATAFG', '0,0,0' ) ;
The image size
Use this method to scale the images retrieved from the database.
This method has to be used before the data are fetched, so before using the Set_Data() method.
-- Image width 200 pixel and keep height aspect ratio --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_IMAGE_SIZE', '200,-1' ) ;
-- prepare column width for images --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_ROW_PROPERTY', 'HEIGHT|80' ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'PHOTO|WIDTH|200' ) ;
Send an image to the Java Bean (JTable)
Use this method to send the content of a Blob database column, supposed to store an image.
The process is split into 3 phases:
- prepare the Java Bean to process the image by giving its JTable coordinates (Row,Cell)
- send the chunks of data to the Bean
- stop the sending process
---------------------
-- send an image --
---------------------
-- prepare the SQL order to select the required database row --
LC$Query := 'Select PHOTO From IMAGES Where PK=12';
-- query the database --
If Pkg_Read_Blob_Image.Select_Blob(LC$Query) Then
-- set the JTable image index --
-- e.g. Row 1, Cell 2 --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_IMAGE', '[INDEX_IMAGE],1,2) ;
Loop
-- get image chunk from the Blob column --
LC$Image := Pkg_Read_Blob_Image.Get_B64_Chunk ;
If LC$Image Is Not Null Then
-- send chunk to the Java Bean --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_IMAGE', LC$Image ) ;
Else
-- stop the sending process --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_IMAGE', '[END_IMAGE]' ) ;
Exit ;
End if ;
End loop ;
End if ;
Needs the PKG_READ_BLOB_IMAGE given package compiled under the corresponding Oracle user.
- The Blob column is selected with the Select_Blob() package's function (the given SELECT order must retrieve one and only one row).
- The chunks of data are read from the Blob column with the Get_B64_Chunk() package's function.
The grid color
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETGRIDFG', '120,120,40');
The table updatable flag
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETUPDATE', 'true|false');
Init (reset all values)
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'INIT', '');
Set the cell coordinate we want to get the value
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETCELLPOS', 'row,cell');
row and cell start with 1 (cell can be given by name as well as position).
Set the row coordinate we want to get the values
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SETROWPOS', 'row');
row starts with 1.
Get the current column name (title)
v_colname := get_custom_property( 'BLOCK.BEAN_ITEM', 1, 'GETCELLNAME');
Show the table
set_custom_property( 'BLOCK.BEAN_ITEM', 1, 'SHOW', 'seperate_flag');
seperate_flag can be true or false
Special JRE 16 version properties
Total line
Add a total line at table bottom
-- total line operator labels --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_TOTAL_LINE_LABELS', 'COUNT=Count,SUM=Sum,AVG=Average,MAX=Min,MIN=Max' ) ;
-- total line operators --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_TOTAL_LINE', 'col1=COUNT,col2=SUM,col3=AVG' ) ;
Operators allowed:
Only COUNT can be used on non-numeric columns.
This method must be used after the table header is defined.
Headers' height
Set the main table header height
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_HEADER_HEIGHT', '20' ) ;
Set the total table header height
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_TOTAL_HEADER_HEIGHT', '0' ) ;
Check Boxes
-- Set the checkbox property for a column --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'col5|CHECKBOX|O,N' ) ;
parameter is: column_name | CHECKBOX | value_when_checked,value_when_unchecked
This methods has to be used after the SETHEADER() and SET_COLS_TYPE() methods, but before the SETDATA() method.
e.g.:s
...
-- Set the hearders' columns
Set_Custom_Property( 'BL1.JTABLE', 1, 'SETHEADER', ... ) ;
-- Set the hearders' columns type
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_COLS_TYPE', ... ) ;
-- Set the checkbox property --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_CELL_PROPERTY', 'col5|CHECKBOX|O,N' ) ;
-- set the DATA --
Set_Custom_Property( 'BL1.JTABLE', 1, 'SETDATA', ... ) ;
Set_Custom_Property( 'BL1.JTABLE', 1, 'SETDATA', ... ) ;
...
General table background color
Set_Custom_Property( 'BL1.JTABLE', 1, 'SETTABLEBG', '200,255,255' ) ;
Maximim column width
Indicates that none of the columns can exceed the given size (in pixel)
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_COLS_MAX_WIDTH', '200' ) ;
Filter
This is usefull to filter the data displayed in the table.
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_FILTER', '[colname,]regex|null' ) ;
filter on "C" for all column:
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_FILTER', 'C' ) ;
filter on "C" for COL1 column:
Set_Custom_Property( 'BL1.JTABLE', 1, 'SET_FILTER', 'COL1,C' ) ;
regex must be a valid Regular Expression.
Use the special value 'null' to clear the filter
You can test these new properties by running the JTABLE16.fmb provided in the zip file.
It uses the "FJTABLE_TEST" table, that you can find the creation script (fjtable_test.sql) in the zip too.
Use the fjtable16.jar file in your /forms/java folder and archive tag.
Properties that can be read
Get a particular cell value (located by the SETCELLPOS property)
varchar2 := get_custom_property( 'BLOCK.BEAN_ITEM', 1, 'GETCELLVAL');
Get a particular row values (located by the SETROWPOS property)
varchar2 := get_custom_property( 'BLOCK.BEAN_ITEM', 1, 'GETROWVAL');
Get the list of changed rows
varchar2 := get_custom_property( 'BLOCK.BEAN_ITEM', 1, 'GET_ROWS_CHANGED');
This list is comma delimited. you can get the tokens by using the provided Forms' PKG_TABLE.Split() function.
Events raised
A cell has been updated : POST_CHANGE
A row has been selected : NEW_RECORD_INSTANCE
A cell has been selected : NEW_ITEM_INSTANCE
Mouse clicked : WHEN-MOUSE-CLICK
Mouse doubleclicked : WHEN-MOUSE-DOUBLECLICK
You can know what cell has been edited through the TABLE_EVENT_MSG parameter:
When-Custom-Item-Event:
DECLARE
eventName varchar2(30) := :system.custom_item_event;
eventValues ParamList;
eventValueType number;
LC$Value varchar2(256);
BEGIN
IF (eventName='POST_CHANGE') THEN
eventValues := get_parameter_list(:system.custom_item_event_parameters);
get_parameter_attr(eventValues,'TABLE_EVENT_MSG',eventValueType, LC$Value);
Clear_Message;
Message('POST-CHANGE:'|| LC$Value);
Synchronize ;
ElsIf (eventName='NEW_RECORD_INSTANCE') THEN
eventValues := get_parameter_list(:system.custom_item_event_parameters);
get_parameter_attr(eventValues,'TABLE_EVENT_MSG',eventValueType, LC$Value);
:GLOBAL.CURRENT_ROW := LC$Value ;
Clear_Message;
Message('When-New-Record-Instance:'|| LC$Value);
Synchronize ;
ElsIf (eventName='NEW_ITEM_INSTANCE') THEN
eventValues := get_parameter_list(:system.custom_item_event_parameters);
get_parameter_attr(eventValues,'TABLE_EVENT_MSG',eventValueType, LC$Value);
:GLOBAL.CURRENT_CELL := LC$Value ;
Clear_Message;
Message('When-New-Item-Instance:'|| LC$Value);
Synchronize ;
End if ;
If (eventName='WHEN-MOUSE-DOUBLECLICK') THEN
eventValues := get_parameter_list(:system.custom_item_event_parameters);
get_parameter_attr(eventValues,'TABLE_EVENT_MSG',eventValueType, LC$Value);
Clear_Message;
Message('When-Mouse-DoubleClick:'|| LC$Value);
Synchronize ;
ElsIf (eventName='WHEN-MOUSE-CLICK') THEN
eventValues := get_parameter_list(:system.custom_item_event_parameters);
get_parameter_attr(eventValues,'TABLE_EVENT_MSG',eventValueType, LC$Value);
Clear_Message;
Message('When-Mouse-Clicked:'|| LC$Value);
Synchronize ;
END IF;
END;
The sample dialog
- Download the JTable.zip file
- Unzip the JTable.zip file
- Compile both PKG_READ_BLOB_IMAGE.pks and PKG_READ_BLOB_IMAGE.pkb scripts in the database
- Copy the fjtable.jar file in your /forms/java/ directory (the JAR file must be signed)
(use the fjtable13.jar in the archive_jini if you use the JInitiator)
- Edit your /forms/server/formsweb.cfg file
- Open the JTABLE.fmb module (Oracle Forms 9.0.2)
- Compile all and run the module
_bug_fck