How to override javascript library object this.function(arg, function(){ - javascript

I'm trying to override a function in the blessed-contrib tree module. However I think I'm missing something in the way of object inheritance. Any help would be greatly appreciated.
Original code:
function Tree(options) {
//...
this.rows = blessed.list({
top: 1,
width: 0,
left: 1,
style: options.style,
padding: options.padding,
keys: true,
tags: options.tags,
input: options.input,
vi: options.vi,
ignoreKeys: options.ignoreKeys,
scrollable: options.scrollable,
mouse: options.mouse,
selectedBg: 'blue',
});
this.append(this.rows);
this.rows.key(options.keys, function() {
var selectedNode = self.nodeLines[this.getItemIndex(this.selected)];
if (selectedNode.children) {
selectedNode.extended = !selectedNode.extended;
self.setData(self.data);
self.screen.render();
}
self.emit('select', selectedNode, this.getItemIndex(this.selected));
});
//...
I'm trying to override the this.rows.key(options.keys, function() { function in my own code. I'm trying to do something like the following but I'm not sure how the object path works for something that is ultimately of blessed-contrib.tree.list type in this case.
My code looks something like this:
"use strict";
var blessed = require('blessed'),
contrib = require('blessed-contrib');
//...
//create layout and widgets
var grid = new contrib.grid({rows: 1, cols: 2, screen: screen})
var tree = grid.set(0, 0, 1, 1, contrib.tree,
{
style: {
text: "red", fg: 'blue',
selected: {
bg: 'yellow', fg: 'white'
}
},
// keys: ['+', 'space'],
vi: true,
template: { lines: true },
label: 'Filesystem Tree'
})
// monkeypatch contrib.tree.rows.key(options.keys, function() {}
// save the original
var old_tree_rows_key = tree.rows.key;
//tree.rows.key = function(options_keys) {
tree.rows.key = function(options_keys) {
var selectedNode = self.nodeLines[this.getItemIndex(this.selected)];
// handle items in options.keys array on my own for custom purposes
// ...
// Code I want commented out:
// if (selectedNode.children) {
// selectedNode.extended = !selectedNode.extended;
// self.setData(self.data);
// self.screen.render();
// }
self.emit('select', selectedNode, this.getItemIndex(this.selected));
};
//...

Ok, Thanks #Bergi! His clue led me to javascript - Why is it impossible to change constructor function from prototype?. I was thinking that I should have deeper access to the object and that I wouldn't have to copy the entire constructor -but I was wrong.
my final code looks like this:
"use strict";
var blessed = require('blessed'),
contrib = require('blessed-contrib'),
Node = blessed.Node,
Box = blessed.Box;
//...
// monkeypatch contrib.tree constructor to change keyhandler
// save the original
var old_tree = contrib.tree.prototype;
//function Tree(options) {
contrib.tree = function(options) {
if (!(this instanceof Node)) return new contrib.tree(options);
var self = this;
options = options || {};
options.bold = true;
this.options = options;
this.data = {};
this.nodeLines = [];
this.lineNbr = 0;
Box.call(this, options);
//...
this.rows.key(options.keys, function() {
var selectedNode = self.nodeLines[this.getItemIndex(this.selected)];
// if (selectedNode.children) {
// selectedNode.extended = !selectedNode.extended;
// self.setData(self.data);
// self.screen.render();
// }
self.emit('select', selectedNode, this.getItemIndex(this.selected));
});
//...
};
// restore binding
contrib.tree.prototype = old_tree;
var tree = grid.set(0, 0, 1, 1, contrib.tree,
{
style: {
text: "red", fg: 'blue',
selected: {
bg: 'yellow', fg: 'white'
}
},
// keys: ['+', 'space'],
vi: true,
template: { lines: true },
label: 'Filesystem Tree'
})
//...

Related

How to mannage refs in react

This below code is to create svg shapes via React components.
Explanation of the code : I am doing composition in the react components first I have a parent g node and after that I have a child g node and in each child g node i have svg path.
what i am doing is : i am creating the shape and after that i am transforming that shape.
i have to transform the each shape individual the problem is that if we do this using the state of the parent it will work fine for the last element but what about is we want to change the transformation of the first element i.e we want to resize the shape
var ParentGroupThread = React.createClass({
getInitialState: function() {
return {
path: {}
};
},
render: function() {
Interfaces.DrawingThreads.ParentGroupThread = this;
var totalDrawing = Object.keys(this.state.path).length;
var drawings = [];
var pathState = this.state.path;
for (var i = 0; i < totalDrawing; i++) {
Interfaces.DrawingThreads.ParentThreadRef = pathState[i].ParentThreadId;
Interfaces.DrawingThreads.ThreadRef = pathState[i].threadIdPath;
drawings.push(React.createElement(ParentThread, {
ParentThreadId: pathState[i].ParentThreadId,
threadIdPath: pathState[i].threadIdPath,
d: pathState[i].d,
fillPath: pathState[i].fillPath,
strokePath: pathState[i].strokePath,
storkeWidthPath: pathState[i].storkeWidthPath,
classNamePath: pathState[i].classNamePath,
dataActionPath: pathState[i].dataActionPath,
dash: pathState[i].dash
}));
}
return React.createElement('g', {
id: 'ParentGroupThread',
key: 'ParentGroupThread_Key'
}, drawings);
}
});
var ParentThread = React.createClass({
getInitialState: function() {
return {
transformation: ''
};
},
render: function() {
Interfaces.DrawingThreads.ParentThread[Interfaces.DrawingThreads.ParentThreadRef] = this;
return React.createElement('g', {
id: this.props.ParentThreadId,
key: this.props.ParentThreadId + '_Key',
ref: this.props.ParentThreadId
},
React.createElement(Thread, {
threadIdPath: this.props.threadIdPath,
key: this.props.threadIdPath + '_Key',
d: this.props.d,
fillPath: this.props.fillPath,
strokePath: this.props.strokePath,
storkeWidthPath: this.props.storkeWidthPath,
transformPath: this.props.transformPath,
classNamePath: this.props.classNamePath,
dataActionPath: this.props.dataActionPath,
transformation: this.state.transformation,
dash: this.props.dash
})
);
}
});
var Thread = React.createClass({
getInitialState: function() {
return {
transformation: ''
};
},
render: function() {
Interfaces.DrawingThreads.Thread[Interfaces.DrawingThreads.ThreadRef] = this;
return React.createElement('path', {
id: this.props.threadIdPath,
d: this.props.d,
fill: this.props.fillPath,
stroke: this.props.strokePath,
strokeWidth: this.props.storkeWidthPath,
className: this.props.classNamePath,
'data-action': 'pathhover',
strokeDasharray: this.props.dash,
vectorEffect: 'non-scaling-stroke',
transformation: this.state.transformation,
ref: this.props.threadIdPath
});
}
});
ReactDOM.render(React.createElement(ParentGroupThread), document.getElementById('threads'));

Javascript simple MVC + module pattern implementation

Here is a very basic attempt to create a "hello world"-like JS app using the module and MVC patterns.
var appModules = {};
appModules.exampleModul = (function () {
var _data = ['foo', 'bar']; // private variable
return {
view: {
display: function() {
$('body').append(appModules.exampleModul.model.getAsString());
},
},
model: {
getAsString: function() {
return _data.join(', ');
},
}
};
})();
appModules.exampleModul.view.display();
This works fine, but I'm not happy how I have to reference the model function from the view, using the full object path: appModules.exampleModul.model.getAsString(). How can I expose the public model methods to the view, so I could simply use something like model.getAsString()? Or do I need to organize the code differently?
One option is you can convert those objects into private implementations.
appModules.exampleModul = (function() {
var _data = ['foo', 'bar'];
// private variable
var _view = {
display : function() {
$('body').append(_model.getAsString());
},
};
var _model = {
getAsString : function() {
return _data.join(', ');
},
};
return {
view : _view,
model : _model
};
})();
You could do something like this:
var appModules = {};
appModules.exampleModul = (function () {
var _data = ['foo', 'bar']; // private variable
return {
view: {
display: function() {
$('body').append(this.model.getAsString());
},
},
model: {
getAsString: function() {
return _data.join(', ');
},
}
};
})();
var display = appModules.exampleModul.view.display.bind(appModules.exampleModul);
display();
Which isn't really the prettiest of solutions, but does offer a more generic solution inside the display function!

Constructing fuelux datagrid datasource with custom backbone collection

I am trying to build datagrid with sorting, searching and paging enabled. Therefore, I am using fuelux-datagrid.
MY backbone view looks like this:
var app = app || {};
$(function ($) {
'use strict';
// The Players view
// ---------------
app.PlayersView = Backbone.View.extend({
template: _.template( $("#player-template").html() ),
initialize: function () {
if(this.collection){
this.collection.fetch();
}
this.listenTo(this.collection, 'all', this.render);
},
render: function () {
this.$el.html( this.template );
var dataSource = new StaticDataSource({
columns: [
{
property: 'playername',
label: 'Name',
sortable: true
},
{
property: 'age',
label: 'A',
sortable: true
}
],
data: this.collection.toJSON(),
delay: 250
});
$('#MyGrid').datagrid({
dataSource: dataSource,
stretchHeight: true
});
}
});
});
The player template just contain the template as given in fuelux datagrid . My routing code somewhere instantiate app.playerview with collection as
new app.PlayersView({
collection : new app.PlayersCollection
}));
My players collection contains list of player model as below
[{
"id":1,
"playername":"rahu",
"age":13
},
{
"id":2,
"playername":"sahul",
"age":18
},
{
"id":3,
"playername":"ahul",
"age":19
}]
My datasource class/function to construct datasoruce with columns and data method is as given in datasource constructor
However, I get the error the " datasource in not defined ". Can anybody help me?
I just wanted to hack the code so that instead of datasource constructed from local data.js in given example, I want to construct the datasource so that it takes data from playercollection.
Also, how to add the one extra column so that we can put edit tag insdie and its should be able to edit the particular row model on clicking that edit.
I have been stucking around these a lot. It would be great help to figure out the answer.
I was stucking around datasource.
I modified the datasource as follows and then it worked.
var StaticDataSource = function (options) {
this._formatter = options.formatter;
this._columns = options.columns;
this._delay = options.delay || 0;
this._data = options.data;
};
StaticDataSource.prototype = {
columns: function () {
return this._columns;
},
data: function (options, callback) {
var self = this;
setTimeout(function () {
var data = $.extend(true, [], self._data);
// SEARCHING
if (options.search) {
data = _.filter(data, function (item) {
var match = false;
_.each(item, function (prop) {
if (_.isString(prop) || _.isFinite(prop)) {
if (prop.toString().toLowerCase().indexOf(options.search.toLowerCase()) !== -1) match = true;
}
});
return match;
});
}
// FILTERING
if (options.filter) {
data = _.filter(data, function (item) {
switch(options.filter.value) {
case 'lt5m':
if(item.population < 5000000) return true;
break;
case 'gte5m':
if(item.population >= 5000000) return true;
break;
default:
return true;
break;
}
});
}
var count = data.length;
// SORTING
if (options.sortProperty) {
data = _.sortBy(data, options.sortProperty);
if (options.sortDirection === 'desc') data.reverse();
}
// PAGING
var startIndex = options.pageIndex * options.pageSize;
var endIndex = startIndex + options.pageSize;
var end = (endIndex > count) ? count : endIndex;
var pages = Math.ceil(count / options.pageSize);
var page = options.pageIndex + 1;
var start = startIndex + 1;
data = data.slice(startIndex, endIndex);
if (self._formatter) self._formatter(data);
callback({ data: data, start: start, end: end, count: count, pages: pages, page: page });
}, this._delay)
}
};
Infact, I just removed following code and its associated braces.
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['underscore'], factory);
} else {
root.StaticDataSource = factory();
}
}(this, function () {
I dont know what exactly the above code is doing an what dependdencies they have over.

KnockOutJS trigger parent function on child subscribe

I am currently trying to learn KnockOutJS. I thought it would be a great idea to create a simple task-list application.
I do not want to write a long text here, let's dive into my problem. I appreciate all kind of help - I am new to KnockOutJS tho!
The tasks are declared as followed:
var Task = function (data) {
var self = this;
self.name = ko.observable(data.name);
self.status = ko.observable(data.status);
self.priority = ko.observable(data.priority);
}
And the view model looks like this
var TaskListViewModel = function() {
var self = this;
self.currentTask = ko.observable();
self.currentTask(new Task({ name: "", status: false, priority: new Priority({ name: "", value: 0 }) }));
self.tasksArr = ko.observableArray();
self.tasks = ko.computed(function () {
return self.tasksArr.slice().sort(self.sortTasks);
}, self);
self.sortTasks = function (l, r) {
if (l.status() != r.status()) {
if (l.status()) return 1;
else return -1;
}
return (l.priority().value > r.priority().value) ? 1 : -1;
};
self.priorities = [
new Priority({ name: "Low", value: 3 }),
new Priority({ name: "Medium", value: 2 }),
new Priority({ name: "High", value: 1 })
];
// Adds a task to the list
// also saves updated task list to localstorage
self.addTask = function () {
self.tasksArr.push(new Task({ name: self.currentTask().name(), status: false, priority: self.currentTask().priority() }));
self.localStorageSave();
self.currentTask().name("");
};
// Removes a task to a list
// also saves updated task list to localstorage
self.removeTask = function (task) {
self.tasksArr.remove(task);
self.localStorageSave();
};
// Simple test function to check if event is fired.
self.testFunction = function (task) {
console.log("Test function called");
};
// Saves all tasks to localStorage
self.localStorageSave = function () {
localStorage.setItem("romaTasks", ko.toJSON(self.tasksArr));
};
// loads saved data from localstorage and parses them correctly.
self.localStorageLoad = function () {
var parsed = JSON.parse(localStorage.getItem("romaTasks"));
if (parsed != null) {
var tTask = null;
for (var i = 0; i < parsed.length; i++) {
tTask = new Task({
name: parsed[i].name,
status: parsed[i].status,
priority: new Priority({
name: parsed[i].priority.name,
value: parsed[i].priority.value
})
});
self.tasksArr.push(tTask);
}
}
};
self.localStorageLoad();
}
What I want to do in my html is pretty simple.
All tasks I have added are saved to localStorage. The save function is, as you can see, called each time an element has been added & removed. But I also want to save as soon as the status of each task has been changed, but it is not possible to use subscribe here, such as
self.status.subscribe(function() {});
because I cannot access self.tasksArr from the Task class.
Any idea? Is it possible to make the self.tasksArr public somehow?
Thanks in advance!
Try this:
self.addTask = function () {
var myTask = new Task({ name: self.currentTask().name(), status: false, priority: self.currentTask().priority() })
myTask.status.subscribe(function (newValue) {
self.localStorageSave();
});
self.tasksArr.push(myTask);
self.localStorageSave();
self.currentTask().name("");
};

Avoid page flickering when updating a YUI DataTable

I am using jlinq a library for extending linq to json and hence i filter my json data. Consider i have a json data that draws a yui datatable on page load with 100 rows. I am doing a clientside filter which will reduce my json data and i am now redrawing the same datatable. What happens is it works pretty well but with an annoying flickering effect...
I call the below method from onkeyup event of the filter textbox,
function showusersfilter(txt) {
var jsondata = document.getElementById("ctl00_ContentPlaceHolder1_HfJsonString").value;
jsondata = jQuery.parseJSON(jsondata);
var results = jLinq.from(jsondata.Table)
.startsWith("name", txt)
.select();
var jsfilter = { "Table": results };
var myColumnDefs = [
{ key: "userid", label: "UserId", hidden: true },
{ key: "name", label: "Name", sortable: true, sortOptions: { defaultDir: YAHOO.widget.DataTable.CLASS_DESC} },
{ key: "designation", label: "Designation" },
{ key: "phone", label: "Phone" },
{ key: "email", label: "Email" },
{ key: "role", label: "Role", sortable: true, sortOptions: { defaultDir: YAHOO.widget.DataTable.CLASS_DESC} },
{ key: "empId", label: "EmpId" },
{ key: "reportingto", label: "Reporting To", sortable: true, sortOptions: { defaultDir: YAHOO.widget.DataTable.CLASS_DESC} },
{ key: "checkbox", label: "", formatter: "checkbox", width: 20 }
];
var jsonObj = jsfilter;
var target = "datatable";
var hfId = "ctl00_ContentPlaceHolder1_HfId";
generateDatatable(target, jsonObj, myColumnDefs, hfId);
}
My textbox looks
<asp:TextBox ID="TxtUserName" runat="server" CssClass="text_box_height_14_width_150" onkeyup="showusersfilter(this.value);"></asp:TextBox>
and my generatedatatable function,
function generateDatatable(target, jsonObj, myColumnDefs, hfId) {
var root;
for (key in jsonObj) {
root = key; break;
}
var rootId = "id";
if (jsonObj[root].length > 0) {
for (key in jsonObj[root][0]) {
rootId = key; break;
}
}
YAHOO.example.DynamicData = function() {
var myPaginator = new YAHOO.widget.Paginator({
rowsPerPage: 25,
template: YAHOO.widget.Paginator.TEMPLATE_ROWS_PER_PAGE,
rowsPerPageOptions: [10, 25, 50, 100],
pageLinks: 10
});
// DataSource instance
var myDataSource = new YAHOO.util.DataSource(jsonObj);
myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
myDataSource.responseSchema = { resultsList: root, fields: new Array() };
myDataSource.responseSchema.fields[0] = rootId;
for (var i = 0; i < myColumnDefs.length; i++) {
myDataSource.responseSchema.fields[i + 1] = myColumnDefs[i].key;
}
// DataTable configuration
var myConfigs = {
sortedBy: { key: myDataSource.responseSchema.fields[1], dir: YAHOO.widget.DataTable.CLASS_ASC }, // Sets UI initial sort arrow
paginator: myPaginator
};
// DataTable instance
var myDataTable = new YAHOO.widget.DataTable(target, myColumnDefs, myDataSource, myConfigs);
myDataTable.resizeHack = function()
{ this.getTbodyEl().parentNode.style.width = "100%"; }
myDataTable.subscribe("rowMouseoverEvent", myDataTable.onEventHighlightRow);
myDataTable.subscribe("rowMouseoutEvent", myDataTable.onEventUnhighlightRow);
myDataTable.subscribe("rowClickEvent", myDataTable.onEventSelectRow);
myDataTable.subscribe("checkboxClickEvent", function(oArgs) {
var hidObj = document.getElementById(hfId);
var elCheckbox = oArgs.target;
var oRecord = this.getRecord(elCheckbox);
var id = oRecord.getData(rootId);
if (elCheckbox.checked) {
if (hidObj.value == "") {
hidObj.value = id;
}
else {
hidObj.value += "," + id;
}
}
else {
hidObj.value = removeIdFromArray("" + hfId, id);
}
});
myPaginator.subscribe("changeRequest", function() {
if (document.getElementById(hfId).value != "") {
if (document.getElementById("ConfirmationPanel").style.display == 'block') {
document.getElementById("ConfirmationPanel").style.display = 'none';
}
document.getElementById(hfId).value = "";
}
return true;
});
myDataTable.handleDataReturnPayload = function(oRequest, oResponse, oPayload) {
oPayload.totalRecords = oResponse.meta.totalRecords;
return oPayload;
}
return {
ds: myDataSource,
dt: myDataTable
};
} ();
}
EDIT:
I even used a delay on the keyup event still the flickering occurs,
var timer;
function chk_me(){
clearTimeout(timer);
timer = setTimeout(function validate(){ showusersfilter(document.getElementById("ctl00_ContentPlaceHolder1_TxtUserName").value);}, 1000);
}
Why do you create a new dataTable each time you filter your data ? You do not need this task. Just supply The filtered data to its dataTable by using sendRequest method of its dataSource
I have create this jsonObject To simulate filtered data
var jsonObject = {
"root":[
{id:"5", userid:"1", name:"ar", designation:"1programmer", phone:"15484-8547", email:"1arthurseveral#yahoo.com.br", role:"1developer", empId:"1789", reportingto:"116"},
{id:"5", userid:"2", name:"br", designation:"2programmer", phone:"25484-8547", email:"2arthurseveral#yahoo.com.br", role:"2developer", empId:"2789", reportingto:"216"},
{id:"5", userid:"3", name:"cr", designation:"3programmer", phone:"35484-8547", email:"3arthurseveral#yahoo.com.br", role:"3developer", empId:"3789", reportingto:"316"},
{id:"5", userid:"4", name:"dr", designation:"4programmer", phone:"45484-8547", email:"4arthurseveral#yahoo.com.br", role:"4developer", empId:"4789", reportingto:"416"},
{id:"5", userid:"5", name:"er", designation:"5programmer", phone:"55484-8547", email:"5arthurseveral#yahoo.com.br", role:"5developer", empId:"5789", reportingto:"516"}
],
"another":[
{id:"5", userid:"5", name:"er", designation:"5programmer", phone:"55484-8547", email:"5arthurseveral#yahoo.com.br", role:"5developer", empId:"5789", reportingto:"516"},
{id:"5", userid:"4", name:"dr", designation:"4programmer", phone:"45484-8547", email:"4arthurseveral#yahoo.com.br", role:"4developer", empId:"4789", reportingto:"416"},
{id:"5", userid:"3", name:"cr", designation:"3programmer", phone:"35484-8547", email:"3arthurseveral#yahoo.com.br", role:"3developer", empId:"3789", reportingto:"316"},
{id:"5", userid:"2", name:"br", designation:"2programmer", phone:"25484-8547", email:"2arthurseveral#yahoo.com.br", role:"2developer", empId:"2789", reportingto:"216"},
{id:"5", userid:"1", name:"ar", designation:"1programmer", phone:"15484-8547", email:"1arthurseveral#yahoo.com.br", role:"1developer", empId:"1789", reportingto:"116"}
]
};
When initializing
(function() {
var Yutil = YAHOO.util,
Ywidget = YAHOO.widget
DataTable = Ywidget.DataTable,
Paginator = Ywidget.Paginator,
DataSource = Yutil.DataSource;
YAHOO.namespace("_3657287"); // QUESTION ID - SEE URL
var _3657287 = YAHOO._3657287;
/**
* paginator
*/
var paginator = new Paginator({
rowsPerPage:25,
template:Paginator.TEMPLATE_ROWS_PER_PAGE,
rowsPerPageOptions:[10, 25, 50, 100],
pageLinks:10
});
/**
* dataSource
*
* As you have static data, I pass an empty "jsonObject" to its constructor
*/
var dataSource = new DataSource({root:[]});
dataSource.responseType = DataSource.TYPE_JSON;
dataSource.responseSchema = {resultsList:"root", fields:[]};
var columnSettings = [
{key:"userid", label:"UserId"},
{key:"name", label:"Name"},
{key:"designation", label:"Designation"},
{key:"phone", label:"Phone"},
{key:"email", label:"Email"},
{key:"role", label:"Role"},
{key:"empId", label:"EmpId"},
{key:"reportingto", label:"Reporting To"}
];
dataSource.responseSchema.fields[0] = "id";
for (var i = 0; i < columnSettings.length; i++) {
dataSource.responseSchema.fields[i + 1] = columnSettings[i].key;
}
/**
* Notice initialLoad equal To false (I suppose your dataTable IS NOT pre-populated)
*/
var dataTableSettings = {
paginator:paginator,
initialLoad:false
};
/**
* dataTable
*
* Notice IT IS STORED in the namespace YAHOO._3657287
*/
_3657287.dataTable = new DataTable("container", columnSettings, dataSource, dataTableSettings);
})();
Now when you want to filter your data, do as follows (Notice sendRequest method)
var i = 0;
YAHOO.util.Event.addListener("reload", "keyup", function(e) {
YAHOO._3657287.dataTable.getDataSource().sendRequest(null, {
success:function(request, response, payload) {
/**
* initializeTable method clear any data stored by The datatable
*/
this.initializeTable();
if(i === 0) {
this.getRecordSet().setRecords(jsonObject["root"], 0);
i++;
} else {
this.getRecordSet().setRecords(jsonObject["another"], 0);
i--;
}
this.render();
},
scope:YAHOO._3657287.dataTable,
argument:null
});
});
You can see here. It works fine!
But if the effect appears again (Notice i am just using relevant part - Nor special feature Nor something else) can occurs because
keyup Event
dataTable rendering
You can set up a variable as follows
var isProcessing = false;
YAHOO.util.Event.addListener("reload", "keyup", function(e) {
if(isProcessing) {
return;
}
isProcessing = true;
YAHOO._3657287.dataTable.getDataSource().sendRequest(null, {
success:function(request, response, payload) {
// as shown above
isProcessing = false;
}
});
}
See also here and here
The problem could be related to the line:
myDataTable.resizeHack = function()
{ this.getTbodyEl().parentNode.style.width = "100%"; }
Since you are resizing the width of the table, it is reasonable to assume that the table will need to be re-painted on the screen resulting in the flicker.

Categories

Resources