{"id":51,"date":"2009-08-24T13:05:19","date_gmt":"2009-08-24T12:05:19","guid":{"rendered":"http:\/\/www.jroller.com\/peter_pilgrim\/entry\/xenondatagrid_m2_nelson_framework_milestone"},"modified":"2009-08-24T13:05:19","modified_gmt":"2009-08-24T12:05:19","slug":"xenondatagrid-m2-nelson-framework-milestone-2wip","status":"publish","type":"post","link":"https:\/\/www.xenonique.co.uk\/blog\/2009\/08\/24\/xenondatagrid-m2-nelson-framework-milestone-2wip\/","title":{"rendered":"XenonDataGrid M2, Nelson Framework (Milestone 2)*WIP*"},"content":{"rendered":"<h1>XenonDataGrid M2, Nelson Framework (Milestone 2)*WIP*<br \/>\n<\/h1>\n<p><\/p>\n<p>\nHi All \n<\/p>\n<p>\n<\/p>\n<p>Yours truly I have just made Milestone 2.0 release of the <a title=\"Nelson Framework JavaFX Data Grid Component\" href=\"https:\/\/kenai.com\/projects\/nelson\/pages\/Home\" id=\"y3wr\">Nelson Framework JavaFX Data Grid Component<\/a>. <\/p>\n<p>Changes<\/p>\n<ul>\n<li>You can now scroll through a data grid.<\/li>\n<li>There is a new reordering implementation of renderer cells in the grid layer<\/li>\n<li>There is a new data structure Mapping and MappingGroup, which maintain position to index coordinate information.\n<\/li>\n<li>Also the &#8220;cellLayer&#8221; has renamed to &#8220;bodyLayer&#8221;. The MasterLayer type is now composed of a <b>corner<\/b>, <b>row header<\/b>, <b>column header<\/b> and <b>body<\/b> cell layers<\/li>\n<li>The javafx package structure has now been revised and refactored into separate comprehensible packages.<\/li>\n<li>Incremental cell selection strategy has been disabled in the DefaultSelectionStrategy. (It is because the reordering of rows and columns breaks the design and U\/X).\n<\/li>\n<\/ul>\n<p>Starting with the root package:<\/p>\n<p><\/p>\n<div>\n<table class=\"\" id=\"s7vr\" border=\"1\" bordercolor=\"#000000\" cellpadding=\"3\" cellspacing=\"0\" width=\"100%\">\n<tbody>\n<tr bgcolor=\"#0000ff\">\n<td style=\"color: rgb(255, 255, 255);\" width=\"50%\"><b>Package<br \/>\n<\/b><\/td>\n<td style=\"color: rgb(255, 255, 255);\" width=\"50%\"><b>Description<br \/>\n<\/b><\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">com.xenonsoft.nelson.scene.layout<\/td>\n<td width=\"50%\">This contains the XenonDataGrid AND AbstractXenonDataGrid component<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">com.xenonsoft.nelson.scene.layout.grid<\/td>\n<td width=\"50%\">This package contains the table model and constraints class.<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">com.xenonsoft.nelson.scene.layout.grid.event<\/td>\n<td width=\"50%\">\nThis package contains event handling types<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">com.xenonsoft.nelson.scene.layout.grid.layer<\/td>\n<td width=\"50%\">This package contains the layer classes and mixins<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">com.xenonsoft.nelson.scene.layout.grid.layout<\/td>\n<td width=\"50%\">This package contains the data grid layout type, strategy and algorithms<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">com.xenonsoft.nelson.scene.layout.grid.renderer\n<\/td>\n<td width=\"50%\">This package contains the renderer and drawable types.<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">\ncom.xenonsoft.nelson.scene.layout.grid.selection<\/td>\n<td width=\"50%\">\nThis package contains the data grid selection context, strategy and algorithm.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2>Examples <\/h2>\n<p>\nClick on the Screenshots to run the file or the JNLP files to run the examples<\/p>\n<h3>Example 1<\/h3>\n<p>This is the same as the previous article. Non-scrollable, draggable row and columns. This test verifies the refactoring did not break the U\/X of the initial example.<\/p>\n<p><a title=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-01-1.0-M2.jnlp\" href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-01-1.0-M2.jnlp\" id=\"uffx\">http:\/\/xenonsoft.com\/jws\/XDG-Example-01-1.0-M2.jnlp<\/a><\/p>\n<h3>Example 2<\/h3>\n<p>Here is a brand new example to demonstrate scrolling. <i>Drag a body cell to scroll around the data set<\/i>, draggable row and columns header cells.<\/p>\n<p><a title=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-02-1.0-M2.jnlp\" href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-02-1.0-M2.jnlp\" id=\"ko3-\">http:\/\/xenonsoft.com\/jws\/XDG-Example-02-1.0-M2.jnlp<\/a><\/p>\n<div id=\"utnu\" style=\"text-align: left;\"><a href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-02-1.0-M2.jnlp\"><img style=\"width: 325px; height: 217px;\" src=\"https:\/\/docs.google.com\/File?id=df5jk3g7_302gh6bpzsh_b\"><\/a>\n<\/div>\n<h3>Example 3<\/h3>\n<p>Here is a brand new example to demonstrate scrolling. <i>The user can use ScrollBars in order to scroll around the data set<\/i>, draggable row and columns header cells.<\/p>\n<p><a title=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-03-1.0-M2.jnlp\" href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-03-1.0-M2.jnlp\" id=\"ayr2\">http:\/\/xenonsoft.com\/jws\/XDG-Example-03-1.0-M2.jnlp<\/a> <\/p>\n<div id=\"g28t\" style=\"text-align: left;\"><a href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-03-1.0-M2.jnlp\"><img style=\"width: 325px; height: 217px;\" src=\"https:\/\/docs.google.com\/File?id=df5jk3g7_305hc379tdk_b\"><\/a><\/div>\n<h3>Example 4<br \/>\n<\/h3>\n<p>Here is a brand new example to demonstrate scrolling. The user can use ScrollBars in order to scroll around the data set, <u><i>draggable column header only<\/i><\/u>. Double click a body cell in order to observe a perspective spin animation applied to the lead cell.<\/p>\n<p><a title=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-05-1.0-M2.jnlp\" href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-05-1.0-M2.jnlp\" id=\"y4n7\">http:\/\/xenonsoft<\/a><a title=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-04-1.0-M2.jnlp\" href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-04-1.0-M2.jnlp\" id=\"si5b\">.com\/jws\/XDG-Example-04-1.0-M2.jnlp<\/a><\/p>\n<p><\/p>\n<div id=\"n1wn\" style=\"text-align: left;\"><a href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-04-1.0-M2.jnlp\"><img style=\"width: 325px; height: 217px;\" src=\"https:\/\/docs.google.com\/File?id=df5jk3g7_304qv8qg9fb_b\"><\/a><\/div>\n<h3>Example 5<br \/>\n<\/h3>\n<p>Here is a brand new example to demonstrate scrolling. The user can use ScrollBars in order to scroll around the data set, <u><i>draggable row header only<\/i><\/u>. Double click a body cell in order to observe animation effect, which happens in the <b><i>pop up<\/i><\/b> pane.<\/p>\n<p><a title=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-05-1.0-M2.jnlp\" href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-05-1.0-M2.jnlp\" id=\"x-kw\">http:\/\/xenonsoft.com\/jws\/XDG-Example-05-1.0-M2.jnlp<\/a><\/p>\n<p><\/p>\n<div id=\"wwwt\" style=\"text-align: left;\"><a href=\"http:\/\/xenonsoft.com\/jws\/XDG-Example-05-1.0-M2.jnlp\"><img style=\"width: 325px; height: 217px;\" src=\"https:\/\/docs.google.com\/File?id=df5jk3g7_303vpdwwmg2_b\"><\/a><\/div>\n<p><\/p>\n<h2>DESIGN NOTE<\/h2>\n<p>\nThere a five special scene graphs in the current design of the <b>XDG<\/b>, which are javafx.scene.Group nodes and are public-read access only. Actually there are currently declared in the <b>AbstractXenonDataGrid<\/b>. There are used to display cells, background and are very much like the layers in the old <b>JLayerPane<\/b>. The intention is allow animation and effect to be easily applied to a XDG component.<\/p>\n<p><\/p>\n<div>\n<table class=\"\" id=\"hg5i\" border=\"1\" bordercolor=\"#000000\" cellpadding=\"3\" cellspacing=\"0\" width=\"648\" height=\"144\">\n<tbody>\n<tr bgcolor=\"#0000ff\">\n<td style=\"color: rgb(255, 255, 255);\" width=\"50%\"><b>Name<br \/>\n<\/b><\/td>\n<td style=\"color: rgb(255, 255, 255);\" width=\"50%\"><b>Description<br \/>\n<\/b><\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">backPane\n<\/td>\n<td width=\"50%\">a pane reserved for a background scenegraph node. (No Pun intended, this property name is shorter than &#8220;backgroundPane&#8221;)\n<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">centralPane\n<\/td>\n<td width=\"50%\">a pane reserved for the layout of grid layer cells. The central pane sits above the backPane.\n<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">editorPane\n<\/td>\n<td width=\"50%\">a pane reserved for the editor cell (TBD). The editor pane sits above the centralPane.\n<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">glassPane\n<\/td>\n<td width=\"50%\">a pane reserved for the special FXs and animation. The glassPane sits above the&nbsp; editorPane. (The current implementation of reordering of rows and columns, in the AbstractXenonDataGrid, uses the glassPane)\n<\/td>\n<\/tr>\n<tr>\n<td width=\"50%\">popupPane\n<\/td>\n<td width=\"50%\">a pane reserved for the popup components. The popupPane sits above the glassPane.\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>See my other <a title=\"AudioBoo: Five Recommendations for JavaFX Table UI Component\" href=\"https:\/\/audioboo.fm\/boos\/44029-five-recommendations-for-javafx-table-ui-component\" id=\"z4cg\">AudioBoo: Five Recommendations for JavaFX Table UI Component<\/a>.<\/p>\n<h2>Understanding The Code<\/h2>\n<p>Here is the source code for the scrollable data grid, example 2 above.<\/p>\n<blockquote><p>\/\/ BigTableXDGTable.fx<br \/>\npackage com.xenonsoft.nelson.scene.layout;<\/p>\n<p>import javafx.stage.Stage;<br \/>\nimport javafx.scene.Scene;<br \/>\nimport javafx.scene.text.Font;<br \/>\nimport javafx.scene.paint.Color;<br \/>\nimport javafx.scene.paint.LinearGradient;<br \/>\nimport javafx.scene.paint.Stop;<br \/>\nimport javafx.scene.control.ScrollBar;<\/p>\n<p>import com.xenonsoft.nelson.scene.layout.XenonDataGrid;<br \/>\nimport com.xenonsoft.nelson.scene.layout.grid.TableModel;<br \/>\nimport com.xenonsoft.nelson.scene.layout.grid.layer.MultiGridLayer;<br \/>\nimport com.xenonsoft.nelson.scene.layout.grid.layer.GridLayer;<br \/>\nimport com.xenonsoft.nelson.scene.layout.grid.renderer.XenonGridCellRenderer;<br \/>\nimport com.xenonsoft.nelson.scene.layout.grid.renderer.XenonGridCellHeaderRenderer;<br \/>\nimport com.xenonsoft.nelson.scene.layout.grid.selection.SelectionContext;<\/p>\n<p>\/**<br \/>\n&nbsp;* @author Peter Pilgrim<br \/>\n&nbsp;*\/<br \/>\ndef MARGIN_WIDTH&nbsp; = 5.0;<br \/>\ndef MARGIN_HEIGHT = 5.0;<br \/>\ndef OFFSET = 25.0;<br \/>\ndef GAP_SIZE = 3.0;<\/p>\n<p>\/\/ XDG size<br \/>\n<b>def GRID_ROWS=8<\/b>;<br \/>\n<b>def GRID_COLUMNS=8<\/b>;<\/p>\n<p>\/\/ Model matrix size<br \/>\n<b>def MATRIX_ROWS=50<\/b>;<br \/>\n<b>def MATRIX_COLUMNS=50<\/b>;<br \/>\ndef mt = new Matrix( MATRIX_ROWS, MATRIX_COLUMNS );<br \/>\nfor ( r in&nbsp; [0..mt.getRows()-1] ) {<br \/>\n&nbsp;&nbsp;&nbsp; for ( c in&nbsp; [0..mt.getColumns()-1] ) {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mt.setData( r, c, &#8220;Cell_{r}_{c}&#8221;);<br \/>\n&nbsp;&nbsp;&nbsp; }<br \/>\n}<\/p>\n<p>def font: Font = Font { size: 12 };<br \/>\ndef headerFont: Font = Font { name: &#8220;Arial Bold&#8221; size: 12 };<\/p>\n<p>def backFill = LinearGradient {<br \/>\n&nbsp;&nbsp;&nbsp; startX: 0.0, startY: 0.0, endX: 0.0, endY: 100<br \/>\n&nbsp;&nbsp;&nbsp; proportional: false<br \/>\n&nbsp;&nbsp;&nbsp; stops: [<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stop { offset: 0 color: Color.GRAY },<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stop { offset: 0.2 color: Color.BLACK }<br \/>\n&nbsp;&nbsp;&nbsp; ]<br \/>\n}<\/p>\n<p>var scene: Scene;<br \/>\nvar <b>dataGrid: XenonDataGrid<\/b>;<br \/>\nvar vertSB: ScrollBar;<br \/>\nvar horzSB: ScrollBar;<\/p>\n<p>var <b>myScrollRow <\/b>: Float = 0 on replace {<br \/>\n&nbsp;&nbsp;&nbsp; <b>dataGrid.scrollRow<\/b> = myScrollRow as Integer;<br \/>\n};<\/p>\n<p>var <b>myScrollColumn <\/b>: Float = 0 on replace {<br \/>\n&nbsp;&nbsp;&nbsp; <b>dataGrid.scrollColumn <\/b>= myScrollColumn as Integer;<br \/>\n};<\/p>\n<p>\nStage {<br \/>\n&nbsp;&nbsp;&nbsp; title: &#8220;Xenon Data Grid Demo #2 (Scrollable)&#8221;<br \/>\n&nbsp;&nbsp;&nbsp; width: 750<br \/>\n&nbsp;&nbsp;&nbsp; height: 500<br \/>\n&nbsp;&nbsp;&nbsp; scene: scene = Scene {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fill: Color.web(&#8220;#F0F0F0&#8221;)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; content: [<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;vertSB = ScrollBar {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;layoutX: bind scene.width &#8211; OFFSET\/2<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;layoutY: MARGIN_HEIGHT<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;width: OFFSET<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;height: bind scene.height &#8211; ( 2 * MARGIN_HEIGHT + OFFSET + GAP_SIZE)<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;min: 0<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>max: mt.getRows() &#8211; GRID_ROWS<\/b><br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;vertical: true<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>value: bind myScrollRow with inverse<\/b><br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;},<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;horzSB = ScrollBar {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;layoutX: MARGIN_WIDTH<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;layoutY: bind scene.height &#8211; OFFSET<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;width: bind scene.width &#8211; ( 2 * MARGIN_WIDTH + OFFSET + GAP_SIZE)<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;height: OFFSET<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;min: 1<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>max: mt.getColumns() &#8211; GRID_COLUMNS<\/b><br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;vertical: false<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>value: bind myScrollColumn with inverse<\/b><br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;},<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;dataGrid = XenonDataGrid {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;debug: true;<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;layoutX: MARGIN_WIDTH<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;layoutY: MARGIN_HEIGHT<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;width: bind scene.width &#8211; (2 * MARGIN_WIDTH + OFFSET + GAP_SIZE )<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;height: bind scene.height &#8211; ( 2 * MARGIN_HEIGHT + OFFSET + GAP_SIZE )<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;headerCellFont: headerFont<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;cellFont: font;<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>masterLayer<\/b>: <b>MultiGridLayer <\/b>{<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>cornerLayer:&nbsp; GridLayer<\/b> {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;debug: true<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;rowSize: 1<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;columnSize: 1<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;renderers: [<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>XenonGridCellHeaderRenderer <\/b>{<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;backgroundFill: Color.DARKGRAY<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;foregroundFill: Color.LIGHTGRAY<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;]<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>tableModel: TableModel <\/b>{<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;rowSize: 1 columnSize: 1 data: &#8220;Corner&#8221;<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>rowHeaderLayer:&nbsp; GridLayer<\/b> {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;debug: true<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;rowSize: GRID_ROWS<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;columnSize: 1<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;renderers: [<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for ( r in&nbsp; [0..&lt;GRID_ROWS] ) {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>XenonGridCellHeaderRenderer <\/b>{<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;backgroundFill: backFill<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;foregroundFill: Color.WHITE<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;]<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>tableModel: TableModel<\/b> {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;rowSize: mt.getRows()<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;columnSize: 1<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;data: for ( r in&nbsp; [0..mt.getRows()-1] ) {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&#8220;Row {r}&#8221; } }<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>columnHeaderLayer:&nbsp; GridLayer<\/b> {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;debug: true<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;rowSize: 1<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;columnSize: GRID_COLUMNS<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;renderers: [<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for ( c in&nbsp; [0..&lt;GRID_COLUMNS] ) {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>XenonGridCellHeaderRenderer <\/b>{<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;backgroundFill: backFill<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;foregroundFill: Color.WHITE<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;]<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>tableModel: TableModel<\/b> {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;rowSize: 1<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;columnSize: mt.getColumns()<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;data:<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for ( c in&nbsp; [0..mt.getColumns()-1] ) {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&#8220;Column {c}&#8221; <br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>bodyLayer:&nbsp; GridLayer<\/b> {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;debug: true<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;rowSize: GRID_ROWS<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;columnSize: GRID_COLUMNS<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;renderers: [<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for ( r in&nbsp; [0..&lt;GRID_ROWS] ) {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for ( c in&nbsp; [0..&lt;GRID_COLUMNS] ) {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>XenonGridCellRenderer <\/b>{<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;backgroundFill: if ( r mod 2 == 1 ) Color.LIGHTGREEN else Color.LIGHTGRAY<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;]<\/p>\n<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>tableModel: TableModel<\/b> {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;rowSize: mt.getRows()<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;columnSize: mt.getColumns()<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;data:<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for ( r in&nbsp; [0..mt.getRows()-1] ) {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for ( c in&nbsp; [0..mt.getColumns()-1] ) {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ( c == 2)<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&#8220;LONGTEXT {<b>mt.getData( r, c).toString()<\/b>}&#8221;<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<b>mt.getData( r, c).toString()<\/b> <br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ]<br \/>\n&nbsp;&nbsp;&nbsp; }<br \/>\n}<\/p>\n<p><b>dataGrid.selectionStrategy.onUnselection = function ( ctx: SelectionContext ) <\/b>{<br \/>\n&nbsp;&nbsp;&nbsp; FX.println(&#8220;old selection ( {ctx.selectedRowMin},&nbsp; {ctx.selectedColumnMin} ) &#8211; ( {ctx.selectedRowMax},&nbsp; {ctx.selectedColumnMax} )&#8221;);<br \/>\n}<\/p>\n<p><b>dataGrid.selectionStrategy.onSelection = function ( ctx: SelectionContext, oldCtx: SelectionContext )<\/b> {<br \/>\n&nbsp;&nbsp;&nbsp; FX.println(&#8220;new selection ( {ctx.selectedRowMin},&nbsp; {ctx.selectedColumnMin} ) &#8211; ( {ctx.selectedRowMax},&nbsp; {ctx.selectedColumnMax} )&#8221;);<br \/>\n}<\/p>\n<p>\/\/ END\n<\/p><\/blockquote>\n<p>\nIn this example, we create a Java object type, Matrix, which represents our large table (50 rows down and 50 rows across, a grand total of 2500). XDG does not care where the data comes from, because it is contained in a TableModel type. Our scene contains three UI components, two scroll bars, horizontal and vertically respectively and the XeNoNDataGrid.<\/p>\n<p>We have two script variables, myScrollRow and myScrollColumn, to listen to the changes in the scrollbar. There are two triggers on them, which update the XDG scroll position. Two indirect script variable are used indirectly instead of binding, because it allows for future updates in the reverse direction &#8211; XDG implementation can update the scroll position. <\/p>\n<p>Pay particularly attention to the code, which declares each ScrollBar and set the maximum value. We avoid out of bound runtime exceptions if we can limit the coordinates to the confines of the table model<\/p>\n<p>So we declare the Scene and scrollbars. We declare the XDG with a <b>MultiGridLayer<\/b>. We can optionally define the corner, column header and\/or row header layers, but we must declare the body layer. The body layer is a <b>GridLayer <\/b>type, which accepts a sequence of renderer cells and a table model. Notice we set up the rowSize and columnSize of the grid layer&#8217;s renderers, which different to the user defined table model bounderies. It is this difference that provides the scrolling ability.<\/p>\n<p><\/p>\n<h2>Conclusion<\/h2>\n<p>\nThe article introduced the XenonDataGrid and its capabilities in scrolling data sets. The Milestone M2 code is <a title=\"downloadable from Project Kenai in binary and source release\" href=\"https:\/\/kenai.com\/projects\/nelson\/downloads\" id=\"p8:x\">downloadable from Project Kenai in binary and source release<\/a>.<\/p>\n<p>\n<b>TODO<\/b>: Milestone 3 will feature the ability to edit the data and it will show off editor renderer cell(s). There will be a fix to the ProportionalResizeLayoutStrategy (buggy). There will be ability to set the minimum and maximum width and heights of header cells. Finally there will possibly be a better selection model based on ranges. <\/p>\n<p>\n<\/p>\n<p>\nThis is Peter Pilgrim. Out.\n<\/p>\n<h2> STOP PRESS <\/h2>\n<p>There is a bug in the reordering of the rows and column, which I won&#8217;t fix it in the M2 release. The solution is to change this line 183 in the TableUtils.fx<\/p>\n<blockquote><p>\n    var value Integer = (mapping.getByB( j ) as IntegerMapping ).getB();\n<\/p><\/blockquote>\n<p>to <\/p>\n<blockquote><p>\n    var value Integer = (mapping.getByA( j ) as IntegerMapping ).getB();\n<\/p><\/blockquote>\n<p>Download the source code, build the distribution, then recompile the code and build the JAR. This reminds to ask Stephen Chin&#8217;s permission to put the JFXtras 0.5 JARs into a Maven Repository in the future.<\/p>\n<p>See you for the M3 release<br \/>\n<br clear=\"all\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>XenonDataGrid M2, Nelson Framework (Milestone 2)*WIP* Hi All Yours truly I have just made Milestone 2.0 release of the Nelson Framework JavaFX Data Grid Component. Changes You can now scroll through a data grid. There is a new reordering implementation of renderer cells in the grid layer There is a new data structure Mapping and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"_links":{"self":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/51"}],"collection":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=51"}],"version-history":[{"count":0,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/51\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=51"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=51"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=51"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}