Best JavaFx container for manipulating long strings char by char - javafx

I'm working with DNA data, in it's simplest form a name/id with sequence info:
public class FastaSequence {
private String name;
private String sequence;
{
The sequence is basically ATGGCTATCAC... for a few thousand chars long. I also have several hundred of these things to compare at any one time.
I need to be able to manipulate the chars in columns and cells, e.g. select the 125th char of each aligned sequence, in a GUI like JavaFX, so I was thinking to use TableView and convert the sequence to a list of chars and feed it to the table model as such. That way each char would get it's own column and I could like color all the T containing cells in red etc.
I have tried this with Python's TableView and I get a working prototype, but it's very slow to respond (loading a list, refreshing), even with a list of only a hundred sequences loaded. So my question is two-fold:
1) Will the JavaFX implementation be (a lot) faster than Python, even when loading a 100k or more cells?
2) Am I barking up the wrong tree and is there a better way to view/manipulate the data as I described it above? Should I be using another model?
UPDATE
I have been doing more research on this and found that the TableView in JavaFX is apparently not designed for huge numbers of columns: https://www.youtube.com/watch?v=udc2iRZBF0M at 1:51.
So I went back to testing a JTable in Swing. Without further fluff it gives me a responsive (i.e. easy to scroll) table upto about a 1000 lines of a 1000 chars. However, making the TableModel a little more complex and using custom cell renderers to center chars in the cell and remove cell borders and such destroys the responsiveness. Because of the many things I've tried I'm not posting all the code here. If/when I come closer to a solution I'll update with my minimal (working?) code. Maybe I need to go back a simpler control like a custom class based on a grid based layout, without the overhead of the JTable and it's model?

You can try something like this to make an array of all the characters in a string:
String sequence = "ATGGCTATCAC";
char[] chars = sequence.toCharArray();
And then you can use System.out.println(chars[125]); to print out the 125th char in that sequence.
I've never used tables in JavaFX before, but I think you can do something like this:
TableColumn column = new TableColumn("Letter");
table.getColumns().add(column);
root.getChildren.add(table);
ObservableList<Character> data = FXCollections.observableArrayList();
for (int i = 0; i < chars.length; i++) {
data.add(chars[i]);
}
table.setItems(data);

Related

Consequences of using dynamic in a struct

I would like to use struct to make sure that everything inside is copied by value, but I would like it to be flexible enough to carry different types. What kind of bad things, especially in terms of performance, may happen when using dynamic field in a struct?
public struct Group
{
public double A;
public double B;
public dynamic Data;
}
This struct is expected to contain information about a single element on the chart and will be used in a collection that on average will contain ~1000 and up to 100K elements.
IList<Group> bars = new List<Group>(1000)
Field Data in this struct is expected to contain various types
double
OHLC bar represented as 4 doubles
up or down arrow represented as 1 double and 1 bool
Is there a way to avoid using dynamic here and still represent data of different types in unified format? If not possible, what is the downside of using dynamic as a field type?
Couple of bad things that I can think of are casting, boxing, and use of cached delegates for different types. Is there anything worse?

Converting a "name" to a real, then convert it back to a string

I've ran into some issues with my current gamemaker project. I've setup a simple "merge" functionality in my game, and I'm trying to increase it's QoL
So what's happening when I'm merging, is this;
var sabatons = instance_place(x, y, object_index);
if (instance_exists(sabatons)) {
instance_create_layer(sabatons.lastknownPosX, sabatons.lastknownPosY, "Instances", "");
if (level >= 3) {
scr_spawn_experience();
}
audio_play_sound(snd_sabatons_merge,10,false);
instance_destroy();
instance_destroy(sabatons);
}
So what the code above does, is to check if object_index matches with what I'm trying to merge it with, and if it does, it runs instance_create_layer - which is where my question comes in.
My objects are easily named with a digit at the end, to keep track of their "level"
so basically, obj_sabatons_1 means it's the first item in a chain, obj_sabatons_2 is the second etc. Now what I need help with is to convert whatever the object is that I'm trying to merge with, to a string (object_index) but increase it with 1, so I then can put that result in my instance_create_layer so the game will create the next level of item, if I successfully merge my first two items :)
Thanks!!
Is there a reason that the level should be part of the name? If not, then you could convert the level into a variable of the object obj_sabatons, so you can keep all the code related to obj_sabatons in one place (And then remove all those copied objects with digits at the end)
Making multiple copies of the same object can be disadvantageous in numerous ways, For example, if you want to expand the limit, then you'd have to create a new object for each level, making a code change also means changing that code in every other object level (unless you're making use of parents/child objects), it would also make the progress of merging objects into new objects easier

QT: QTableView read cell content

I'm writing a small program with QT creator (QT 5.2.1) under Windows 7 (32 bit) and I'm having problems reading the informations stored in a TableView. My application has 3 elements, a TableView to store text data, a TextBrowser to show info and a buttom.
I modified the TableView properties: when the user selects with the mouse a cell, the full row is selected and multiple row selection is not allowed.
The user select a row and when the buttom is pressed, I would like to read the content of a specific TableView cell and show it in a TextBrowser. In particular, I would like to know the row index of the selected row and read the content of the cell with that row index and a specific column index (example 2).
The pseudo-code is this:
void my_program::on_pushButton_clicked()
{
ui->textBrowser->append("button pressed");
QItemSelectionModel *select = ui->tableView->selectionModel();
int index_row = select->selectedRows();
int index_column = 2;
char cell_data[30] = ??[index_row][index_column]
ui->textBrowser->append(cell_data);
}
The main problem is that select->selectedRows() returns a QModelIndex that is a collection of indexs and I do not know how to convert it to int (since multiple selection are not allowed, it should have only one element).
I would be glad if someone can suggest me a way to proceed.
Thanks
Francesco
edit:
Hi Bogdan, thanks a lot!! I succeed to read the cell content by using
ui->textBrowser->append(ui->tableView->model()->data(ui->tableView->model()->index(2,5)).toString());
this give me the content of the cell in position 2,5.
not sure if this is the best way or not but it works !!.
Can you be a bit more precise about how to iterate the QModeIndexList ? thanks :)
selectedRows() returns QModelIndexList, thus you need to iterate over it and call QModelIndex::data() to get stored data.

QTableView problems with row

Hello guys i new to QT and i am doing Qtableview to add information in 3 columns to infinite row like
|--1--|--2--|--3--|
|--1--|--2--|--3--|
|--1--|--2--|--3--|
this is how i want to insert/append row but this is how i am getting after insert/append row functions.
|--1--|--2--|--3--|
|-----|-----|-----||--1--|--2--|--3--|
|-----|-----|-----||-----|-----|-----||--1--|--2--|--3--|
i am getting empty gaps and increased column count
i am using QStandardItemmodel for model this is code that creates the model item
void tableview::add_tableview() //this is used to add data to tableview
{
//to get data from line edit in add window
QStandardItem *item_1 = new QStandardItem(QString(enter1_edit->text()));
QStandardItem *item_2 = new QStandardItem(QString(enter2_edit->text()));
QStandardItem *item_3 = new QStandardItem(QString(enter3_edit->text()));
list << item_1 << item_2 << item_3;
model->appendRow(list);
//to set the model
main_tableview->setModel(model);
}
The values in the rows are added using qlineedit enter1_edit,enter2_edit & enter3_edit(its in other function/method)
main_tableview is the object of qtableview
Thanks for helping me!
Ding Ding Ding, I have it.
I tried to reproduce your problem without success unil I tried something...suboptimal :).
Is your list by any chance a global entity? If yes (and I assume it is) you keep adding items to it.
First time you call add_tableview() all is good, list is empty, gets three QStandardItem pointers added and is used to append a row with those three items. So far so god.
You call add_tableview() again, now you create another three QStandardItems and APPEND them to the list (which still contains the three from the last call). Invoking appendRow() actually tries to insert six items, from which the first three allready exist in the model. And as you know you mustn't add the same item pointer to a model twice. Thankfully Qt doesn't crash but inserts three empty columns for the item pointers allready in it.
Solution: At the end of your add_tableview() method call list.clear() or use a local variable for the list. The overhead should be minimal.
Best regards
D

AdvancedDataGrid (grouping) quick jump to row

I have a problem with the AdvancedDataGrid widget. When the dataProvider is an ArrayCollection (of arrays), the nth array (within the collection) is also the nth row within the grid, and I can jump and display the i-th row by scripting
adg.selectedIndex = i;
adg.scrollToIndex(i);
now, when I add a Grouping, the dataProvider ends up being a GroupingCollection2, and now the index in the dataprovider's source does not correspond to the index in the adg anymore (which is understandable, because it's being grouped).
How can I select and display a row in grouped data efficiently? Currently, I have to traverse the adg and compare each found item with its data attributes in order to find the correct index of the row within the adg, and jump to it like above. This process is very slow. Any thoughts?
edited later:
We already used a caching object as Shaun suggests, but it still didn't compensate for the search times. In order to fully construct a sorting of a list of things (which this problem equates to, as the list is completely reordered by the grouping), you always have to know the entire set. In the end we didn't solve that problem. The project is over now. I will accept Shaun's answer if no one knows a better way in three days.
Depending on what values your comparing against you can store the objects in a dictionary with the lookup using the property/properties that would be searched for, this way you have a constant time look-up for the object (no need to look at every single item). Say for example your using a property called id on an object then you can create an AS object like
var idLookup:Object = {};
for(myObject in objects)
idLookup[myObject.id] = myObject;
//Say you want multiple properties
//idLookup[myObject.id]={};
//idLookup[myObject.id][myObject.otherProp] = myObject;
now say the user types in an id you go into the idLookup object at that id property and retrieve the object:
var myObject:Object = idLookup[userInput.text];
myAdg.expandItem(myObject, true);
now when you want to get an object by id you can just do
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/controls/AdvancedDataGrid.html#expandItem()
I haven't done any thorough testing of this directly, but use a similar concept for doing quick look-ups for advanced filtering. Let me know if this helps at all or is going in the wrong direction. Also if you could clarify a bit more in terms of what types/number of values you need to lookup and if there's the possibility for multiple matches etc. I may be able to provide a better answer.
Good luck,
Shaun

Resources