I have two ObservableList which one of them contains some song and other one has the directory that related to songs.
I want when remove a directory from its ObservableList, all of the songs those contain that directory be removed from their ObservableList.
but when I do that, just songs with odd id removed and ones with even id remained !!!
my ObservableLists are in a different class and "controller" is the object of the class that contains the ObservableLists.
here is my code :
private static ObservableList<SongModel> songModelObservableList = FXCollections.observableArrayList();
private static ObservableList<Directory_Model> directoryModelObservableList = FXCollections.observableArrayList();
and now my code that remove directory :
for (int j = 0 ; j < controller.getSongModelObservableList().size() ; j++)
if (controller.getSongModelObservableList().get(j).getPath().contains(controller.getDirectoryModelObservableList().get(i).getPath())){
controller.getSongModelObservableList().remove(controller.getSongModelObservableList().get(j));
}
controller.getDirectoryModelObservableList().remove(controller.getDirectoryModelObservableList().get(i));
here. in the first if, I check which songModel(my class for songs) has the directory's path to remove it from songObservableList.
have any idea to fix that? I want to remove all of directory's songs not ones with odd id.
If you remove the element at index j from the list, the item at position j after modification is the item that was previously at index j+1. Since you increment the index after every iteration of the loop, you skip an item, if you remove one in the iteration. Instead only increment the index, if no item is removed:
final String removePath = controller.getDirectoryModelObservableList().get(i).getPath();
for (int j = 0; j < controller.getSongModelObservableList().size();)
if (controller.getSongModelObservableList().get(j).getPath().contains(removePath)){
controller.getSongModelObservableList().remove(j);
} else {
j++;
}
}
controller.getDirectoryModelObservableList().remove(i);
It would be simpler though to simply use a Predicate with removeIf:
final String removePath = controller.getDirectoryModelObservableList().get(i).getPath();
controller.getSongModelObservableList().removeIf(element -> element.getPath().contains(removePath));
Related
Im new to Java and JavaFX and Im trying to check it there is a duplicate in a Tableview, and if that is the case I would like to replace it with a new set of data.
So in essence I'm trying to iterate through the data in my TableView and compare it to something. To be more exact I'd like to compre a value of the String on the first column to a new String. I've done some research and I've found that the most common kind of solution for Filtering Data is using a FilteredList but this doesn't return my original set of items.
my current Code looks like this:
#FXML private TableView<STable> TableV;
public void Replace(String s){
ObservableList<STable> getCurrentData;
for(int i = 0; i < getCurrentData.size(); i++){
// Here is where I get Stuck I've tried:
//TableV.getSelectionModel().getSelectedItem().getCajas();
//getCurrentData.get(i)
}
}
Note: The STable is a class that has all the setters and getters for each of the columns, I've also got the CellFactory set up.
Any guidance on how to do this would be great!
Basically you just have to iterate through your data items, and compare the value representing the content of column 1, to your new string. If both values are equal, you update the value in your dataModel:
(I replaced STable with YourData, because I find the name for a dataModel a little confusing)
for (YourData data : tableView.getItems()) {
if (data.getColumOne().equals(textToCompare)) {
data.setColumnOne("newText");
}
}
Or if you want to replace the row:
for (int idx = 0; idx < tableView.getItems().size(); idx++) {
YourData data = tableView.getItems().get(idx);
if (data.getColumnOne().equals(textToCompare)) {
tableView.getItems().set(idx, someOtherData);
return;
}
}
This pertains to .NET Web Performance Tests.
If I have an ASP.NET page with a GridView that has a column of ints, how do I write an extraction rule to get the largest int in the column?
I tried creating a custom extraction rule by inheriting from ExtractionRule and in the Extract method using e.Response.HtmlDocument.GetFilteredHtmlTags however, the HtmlTags returned don't seem to expose their innerHtml contents.
Perhaps you can write an extraction rule that gets the whole column, then process the numbers to get their maximum value. Alternatively, use a built-in extraction rule to get the whole column, then write a plugin to get the maximum value. In either case your code should expect a mixture of numbers and other text.
Ben Day has a great blog post containing two types that express similar concerns. TableColumnValueValidator and ExtractRandomValueFromTable.
http://www.benday.com/2013/08/19/validation-extraction-rules-for-visual-studio-2012-web-performance-tests/
In the Extract(object, ExtractionEventArgs), you need to parse the ExtractionEventArgs.Response.BodyString. Ben uses the HtmlAgilityPack library for this. http://www.nuget.org/packages/htmlagilitypack
Something like this is roughly the code you'd need. This is simliar logic to ExtractRandomValueFromTable.
This does not account for thead/tbody or cells that span multiple columns/rows.
HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(e.Response.BodyString);
HtmlNode table = doc.GetElementbyId(TableId); // TableId is a test property
HtmlNodeCollection columns = table.SelectNodes("//th");
int columnIndex = FindColumnIndexByName(columns, ColumnName); // ColumnName is a test property
HtmlNodeCollection rows = table.SelectNodes("//tr")
int maxValue = Int32.MinValue;
foreach(HtmlNode row in rows)
{
HtmlNodeCollection cells = row.SelectNodes("./td");
// Todo check for bounds of cells here
HtmlNode cell = cells[columnIndex];
int value = Int32.MinValue;
Int32.TryParse(cell.InnerText.Trim(), out value);
maxValue = Math.Max(value, maxValue);
}
e.WebTest.Context.Add(ContextParameterName, maxValue);
int FindColumnIndexByName(HtmlNodeCollection columns, string columnName)
{
for(int i=0; i<columns.Count; i++)
if (String.Equals(columns[i].InnerText, columnName, StringComparison.OrdinalIgnoreCase))
{
return i;
}
return -1;
}
Picture this: I have a JSON file which has a list of Node objects that contain a list of Link types. Something like:
node1:
links: node1,node2
node3,node1
node1,node6
node2:
links: node2,node1
node2,node9
node7,node2
I need to identify unique pairs of links - ie a (node_a,node_b) pair. Note that (node_b,node_a) represents the same thing.
The Link class has getter methods that return a pointer to either the source/destination Node. In the file, the information about the links is stored as a string that has the source node's name and the destination node name, like: (source,destination).
When I build my structure from file, I first create the Nodes and only then I create the Links. The Link constructor is as follows:
Link::Link(Node *fromNode, Node *toNode)
And my code to create the links:
QList<Link*> consumedLinks; // list where I was trying to place all the non-duplicate links
// for each node in the file
foreach(QVariant nodesMap, allNodesList){
QVariantMap node1 = nodesMap.toMap();
QList<QVariant> nodeDetails = node1["node"].toList();
QVariantMap allLinksMap = nodeDetails.at(9).toMap();
// extract all the links of the node to a list of QVariant
QList<QVariant> linksList = allLinksMap["links"].toList();
// for each Link in that list
foreach(QVariant linkMap, linksList){
QVariantMap details = linkMap.toMap();
Node *savedFromNode;
Node *savedToNode;
// get all the Items in the scene
QList<QGraphicsItem*> itemList = scene->items();
// cast each item to a Node
foreach(QGraphicsItem *item, itemList){
Node* tempNode = qgraphicsitem_cast<Node*>(item);
if(tempNode){
// check what the node name matches in the link list
if(tempNode->text()==details["fromNode"]){
savedFromNode = tempNode;
}
if(tempNode->text()==details["toNode"]){
savedToNode = tempNode;
}
}
}
// create the link
Link *linkToCheck = new Link(savedFromNode,savedToNode);
// add it to the links list (even if duplicate)
consumedLinks.append(linkToCheck);
}
}
// add all the links as graphics items in the scene
foreach(Link *linkToCheck, consumedLinks){
scene->addItem(linkToCheck);
}
So right now this doesn't check for duplicates in the consumedLinks list (obviously). Any ideas on how to achieve this?
NOTE: I know that the pseudo-JSON above isn't valid, it's just to give you an idea of the structure.
NOTE2: I rephrased and added detail and code to the question to make it clearer to understand what I need.
1. Normalize links i.e. replace (a, b) to (b, a) when b < a. Each link should be represented as (a, b), a < b.
2. Create a QSet< QPair<Node*, Node *> > variable and put all links into it. Each link object can be maked using qMakePair(node1, node2). Since QSet is an qnique container, all duplicates will be removed automatically.
Well, I didn't exactly do the same as #Riateche suggested, but something similar.
I basically created a QList<QPair<QString,QString> > so I could check for duplicates easily and then I created a list of Link based on the items in the QPair list. Something like:
QList<Node*> existingNodes;
QList<QPair<QString,QString> > linkPairList;
QList<QGraphicsItem*> itemList = scene->items();
foreach(QGraphicsItem *item, itemList){
Node* tempNode = qgraphicsitem_cast<Node*>(item);
if(tempNode){
existingNodes.append(tempNode);
}
}
foreach(QVariant nodesMap, allNodesList){
QVariantMap node1 = nodesMap.toMap();
QList<QVariant> nodeDetails = node1["node"].toList();
QVariantMap allLinksMap = nodeDetails.at(9).toMap();
QList<QVariant> linksList = allLinksMap["links"].toList();
foreach(QVariant linkMap, linksList){
QVariantMap details = linkMap.toMap();
QPair<QString,QString>linkPair(details["fromNode"].toString(),details["toNode"].toString());
QPair<QString,QString>reversedLinkPair(details["toNode"].toString(),details["fromNode"].toString());
if(!linkPairList.contains(linkPair)){
// !dupe
if(!linkPairList.contains(reversedLinkPair)){
// !reversed dupe
linkPairList.append(linkPair);
}
}
qDebug()<<"number of pairs: "<<linkPairList.size();
}
}
QPair<QString,QString> linkPairInList;
foreach(linkPairInList, linkPairList){
Node *savedFromNode;
Node *savedToNode;
foreach(Node* node, existingNodes){
if(node->text()==linkPairInList.first){
savedFromNode=node;
}
if(node->text()==linkPairInList.second){
savedToNode=node;
}
}
Link *newLink = new Link(savedFromNode,savedToNode, "input");
scene->addItem(newLink);
}
This is the correct answer because it solves what I needed to solve. Since I only got there because of #Riateche's comments, I +1'd his answer.
Have landed into a scenario.
I have a gridview with 22 static columns (few are BoundFields, few are TemplateFields).
We have a scenario in our project that we need to order the GridView according to the columns selected. The order of the columns selected is provided from the UI.
For ex: We have Doc1 to Doc23 as the columns.
Now, from the functionality provided in the UI, I am passing some 4 columns say Doc2,Doc4,Doc5,Doc7.
Now I want that only these 4 columns should be present in my grid as a final output.
Have tried some code, but it doesn't seem to work.
Below is my code:
public int GridColumnOrdering(string columnList)
{
string[] test = columnList.Split(';');
var docCatColumn = gridResultSet.Columns[0];
var docTypeColumn = gridResultSet.Columns[1];
int columnCount = 0;
int testCount = 0;
for (int i = 0; i < test.Count(); i++)
{
if (test[i] == "Doc2")
{
gridResultSet.Columns.Insert(i , docCatColumn);
columnCount++;
}
if (test[i] == "Doc3")
{
gridResultSet.Columns.Insert(i , docTypeColumn);
columnCount++;
}
}
gridResultSet.Columns[2].Visible = false;
gridResultSet.Columns[3].Visible = false;
}
columnList is a parameter passed which has values such as Doc2;Doc3.
My idea is that I get the static columns which resemble the column gotten from the UI, change its position to the very next position, and then hide that static column. In this way, we actually have 2 columns by the same name, but I am trying to hide the static one and display the dynamic one.
I know it sounds weird and hectic, but this is what came to my mind.
Now the problem is that if I try to change the visibility of the static column, the visibility of the dynamic one also changes.
Can experts help on this issue or point out to some easy method in this regards??
Regards
Anurag
Hi
I am creating online quiz in asp.net c#. For that i have one form that displays testlist in dropdownlist & start button. After clicking 2nd form appears, 2nd form shows one label for question, radiobuttonlist for answers ,next & checkbox for review. I am creating array of random question ids in start button click event of the 1stform. when i click next button in 2nd form then next random question appears, i want array of questions those are checked for review. I used code for arrays of values ( eg.10101) 1 for true & 0 for false as follows but i want array of that question ids those are checked:
int[] a = (int[])Session["values"];//this is array of random question ids created in 1st form
int g;
if (chkmark.Checked == true)
{
g = 1;
}
else
{
g = 0;
}
int[] chkarray = new int[Convert.ToInt32(Session["Counter"]) - 1];
int[] temp1 = (int[])Session["arrofchk"];
int k, no;
if (temp1 == null)
no = 0;
else
no = temp.Length;
for (k = 0; k < no; k++)
{
chkarray[k] = temp1[k];
}
chkarray[j] = g;
Personally, i would use a Dictionary<int, bool> for this.
In the key of the dictionary, you can store the random Question ID, in the value of the pair, you can store the checked item state. It might take you more work now to refactor it, but I believe it will save you a lot of time in the end when you want to do more actions on your quiz items.
Using a dictionary - or at least a well chosen collection, I think it will be easier to get the right data back.
For your example, it can work only if the positions of both arrays are the same.
Dictionary<int, bool> quizAnswers = new Dictionary<int, bool>(); // <questionID, checked>
// Fill dictionary with questions and answers
for(int i=0;i<a.length;i++)
{
if(temp1.length > i) // Make sure we don't get an IndexOutOfBoundsException
{
quizAnswers.Add(a[i], temp1[i] == 1);
}
}
// Get Answered question in array ( LINQ )
int[] checkedAnswers = (from KeyValuePair<int, bool> pair in quizAnswers
where pair.Value == true
select pair.Key).ToArray<int>();
The reason I am using a Dictionary here, is because I personally think it's neater than having two separate arrays.
I believe you should implement a Dictionary in your quiz, in stead of those arrays. What if the array indexes don't match, or you want to dynamically add a question to a fixed size array, etc..
It's something to take into consideration. Hope I could help you out.