i got a task which iam not sure of how to solve.
I have to fill a JTable with rows i get from a .txt document. The problem is that there are multiple .txt documents which have more or less rows and columns for the JTable.
example:
inside the cars.txt:
id;hp;price;quantity
1;100;7000;5
4;120;20000;2
7;300;80000;3
inside the bikes.txt
id;price;quantity;color;year
3;80;20;red;2010
5;200;40;green;2011
12;150;10;blue;2007
So, when a .txt is chosen a JDialog will pop up with a JTable inside, where the data will be shown.
I thought that i could maybe create a "class Anything" where i have a instance variable String[][] which i can define the sizes by reading the .txt and after saving the data in one array i can count how many rows and how many columns it has,
with the cars.txt example it would be: String[4][3]
Is that a good way to work with or is there a better way to do it?
Thanks for the help :D
Your question is a bit vague on what you want to do specifically.
Do you want to simply fill the table with all data given? Or do you only want certain columns used? When you choose the text files are you aware of which column names they have (can you hardcode this or not).
A good start would be...
EDITED here's the solution.....
DefaultTableModel dtm = (DefaultTableModel)yourJTable.getModel();
// This divides your txt file to a string array divided by rows
string[] RowSplit = yourTxtFileThatYouRead.split("\n");
//this assumes that your txt file contains the column headers
dtm.setColumnHeaders(RowSplit[0].split(";"));
//Start the iteration at 1 to skip the column headers
for (int i = 1; i < RowSplit.length; ++i) {
dtm.addRow(RowSplit[i].split(//some delimeter //));
dtm.fireTableDataChanged();
The first part sets the column headers and enables for variation within your table column size.
The second part sequentially adds rows.
edited for formatting
edited for better answer
As shown in How to Use Tables: Creating a Table Model, you can extend AbstractTableModel to manage models of arbitrary dimensions. Let your model manage a List<List<String>>. Parse the first line of each file into a List<String> that is accessed by your implementations of getColumnCount() and getColumnName(). Parse subsequent lines into one List<String> per row; access the List of such rows in your implementation of getValueAt(). A related example that manages a Map<String, String> is shown here. Although more complex, you can use Class Literals as Runtime-Type Tokens for non-string data; return the token in your implementation of getColumnClass() to get the default render and editor for supported types. Finally, consider one of these file based JDBC drivers for flat files.
Related
I want to iterate a dataframe by partitions and for each partition iterate all of its rows and create a deleteList of them that will contain HBase's delete objects for each row.
I'm using Spark and HBase with Java and I've created a Row object with the following code:
df.foreachPartition((ForeachPartitionFunction<Row> iterator -> {
while (iterator.hasNext()) {
Row row = RowFactory.create(iterator.next());
deleteList.add(new Delete(Bytes.toBytes(String.valueOf(row))));
}
}
But it won't work because I cannot access row's value correctly. While df has one column named "hbase_key".
It's hard to tell from your post which class exactly is Row, but I suspect it is org.apache.spark.sql.Row ?
If that's the case, try the methods like getString(i) or similar, where i is the index of the column in the row you are trying to access.
Again, depending on how you are configuring your Hbase access, I suspect that in your case the 0 index would be the value of the row-key of the physical HBase table, and the subsequent indices will be the respective column values that are returned with your row. But again, that would depend on how exactly you arrived at this point in your code.
Your Row object should have methods to access other data types as well, such as getInt(i), etc.
I was using glpsol with a .mod file containing both the problem and the data for it.
However, I want to use its Java API to instantiate the problem within my application, without the need to write/read files and run them with glpsol.
In my problem, I have "sets" that are given afterwards in the data section, and also params in function of these sets, for example:
set ROBOTS;
param L{ROBOTS}, integer;
And then, at the data section:
data;
set ROBOTS := ag1 ag2 ag3;
What I want to know is what method can I use to add such params to the problem, as well as how to retrieve them.
In order to observe how this problem was being represented, I've tried reading the problem and the data from files and extracted the rows and cols of the problem through the methods glp_get_row_name and glp_get_col_name. I came to the conclusion that the rows are the objective and constraints, whilst the columns are the values of a var f that is declared as follows and used in some of the constraints as well as in the objective:
var f{ROBOTS,SUBTASKS}, binary;
I could not find in the documentation a way to extract these params from the problem. Also, I have no idea about where my other vars went, since only f appeared in the columns. But as the program was able to solve the instantiated problem and had the same result as the solution given by glpsol, I know that it has all of this data, I just want to know where it stores it.
I was reading the documentation from here: http://glpk-java.sourceforge.net/apidocs/org/gnu/glpk/GLPK.html
Sorry for the lack of correct terminology. Thanks in advance.
var f{ROBOTS,SUBTASKS}, binary;
ROBOTS and SUBTASKS only exist in the GMPL language model.
After the model is translated the problem is stored as a sparse matrix. You only have column numbers and row numbers for addressing.
I have a requirement where I have to parse an HTML page that contains multiple tables of scorecard. table structure remains same but based on data for different matches,different tables can contain different, though column names are same.
Now i need to search based on table columnname and data contained in it with an argument pair. e.g. if i have a column called playername and multiple tables contain many player names. if i search for a particular player name by passing 2 arguments- playername(column name) and Jason, it should fetch all rows where playername column has Jason as its data. i can pass another pair of arguments as a AND - matchesplayed(column name) and 15, it should fetch all rows from above result set where Jason played 15 matches.
Can you assist how I can achieve this. Logic I tried is-
get the data for all columns in different array lists.then create a map with the column names as keys and its values as different arraylists containing that column's data. Is my approach correct or i need to solve it using different approach.
Thanks for your help.
Let's make order. I use your example.
1) The first thing you have to do is searching for rows where playername == Jason. Using jsoup or another HTML parser you can easily have access to the td where Jason is contained in. From there, you can easily access to the parend trand to the table.
2) Using the table you can access first tr or th to individuate columnname to use as keys. Then using a positional logic (first with first, second with second) you can understand which columnname corresponds to which content (inside the td
3) How to collect data is up to you. Probably, a Map<String, String> can be a solution. Or, if data is static, you can create a Player pojo and use reflection api to fill it.
Giving us more details and snippets of code we can help you more.
You can use Jsoup to get the HTML Document and then write a method with the input player name values. This method should parse through <table> elements in the html document to get you what is needed. Parsing will be easy if you understand Jquery/css selectors.
Check this link for Jsoup Selectors.
http://jsoup.org/apidocs/org/jsoup/select/Selector.html
I have two or more .csv files which have the following data:
//CSV#1
Actor.id, Actor.DisplayName, Published, Target.id, Target.ObjectType
1, Test, 2014-04-03, 2, page
//CSV#2
Actor.id, Actor.DisplayName, Published, Object.id
2, Testing, 2014-04-04, 3
Desired Output file:
//CSV#Output
Actor.id, Actor.DisplayName, Published, Target.id, Target.ObjectType, Object.id
1, Test, 2014-04-03, 2, page,
2, Testing, 2014-04-04, , , 3
For the case some of you might wonder: the "." in the header is just an additional information in the .csv file and shouldn't be treated as a separator (the "." results from the conversion of a json-file to csv, respecting the level of the json-data).
My problem is that I did not find any solution so far which accepts different column counts.
Is there a fine way to achieve this? I did not have code so far, but I thought the following would work:
Read two or more files and add each row to a HashMap<Integer,String> //Integer = lineNumber, String = data, so that each file gets it's own HashMap
Iterate through all indices and add the data to a new HashMap.
Why I think this thought is not so good:
If the header and the row data from file 1 differs from file 2 (etc.) the order won't be kept right.
I think this might result if I do the suggested thing:
//CSV#Suggested
Actor.id, Actor.DisplayName, Published, Target.id, Target.ObjectType, Object.id
1, Test, 2014-04-03, 2, page //wrong, because one "," is missing
2, Testing, 2014-04-04, 3 // wrong, because the 3 does not belong to Target.id. Furthermore the empty values won't be considered.
Is there a handy way I can merge the data of two or more files without(!) knowing how many elements the header contains?
This isn't the only answer but hopefully it can point you in a good direction. Merging is hard, you're going to have to give it some rules and you need to decide what those rules are. Usually you can break it down to a handful of criteria and then go from there.
I wrote a "database" to deal with situations like this a while back:
https://github.com/danielbchapman/groups
It is basically just a Map<Integer, Map<Integer. Map<String, String>>> which isn't all that complicated. What I'd recommend is you read each row into a structure similar to:
(Set One) -> Map<Column, Data>
(Set Two) -> Map<Column, Data>
A Bidi map (as suggested in the comments) will make your lookups faster but carries some pitfalls if you have duplicate values.
Once you have these structures you lookup can be as simple as:
public List<Data> process(Data one, Data two) //pseudo code
{
List<Data> result = new List<>();
for(Row row : one)
{
Id id = row.getId();
Row additional = two.lookup(id);
if(additional != null)
merge(row, additional);
result.add(row);
}
}
public void merge(Row a, Row b)
{
//Your logic here.... either mutating or returning a copy.
}
Nowhere in this solution am I worried about the columns as this is just acting on the raw data-types. You can easily remap all the column names either by storing them each time you do a lookup or by recreating them at output.
The reason I linked my project is that I'm pretty sure I have a few methods in there (such as outputing column names etc...) that might save you considerable time/point you in the right direction.
I do a lot of TSV processing in my line of work and maps are my best friends.
I am not sure if I have understood properly, but I think if I use the POI Event model, and there is no data (just blank, not even a space) in a excel column, the data is not read at all.
The problem I have is say I have a model with 15 columns and I am reading the data to populate the model from a excel sheet.
I read the excel and store the data in a List and then add to the model
If one of the column has no data, POI reads nothing and hence the List I create has only 14 columns.
And then I cannot match the columns in the model and the List.
How do I solve this issue?
If you were using HSSF for a .xls file, you could have used MissingRecordAwareHSSFListener which would have sent you special records to indicate gaps. A good example for that is XLS2CSVmra. However, you say you're on XSSF for .xlsx, so it's a little different
The is an Apache POI example that covers missing records in a .xlsx file, you'll want to look at the XLSX2CSV example. Basically, you should have a variable that holds the last column number you saw. When the startElement fires for c (cell), check the reference column against the last one seen. If there's a gap, trigger empty cells to your logic at that point, then record the new column and process.
The logic to get the current column number would be something like:
// Get the cell reference
String r = attributes.getValue("r");
int firstDigit = -1;
for (int c = 0; c < r.length(); ++c) {
if (Character.isDigit(r.charAt(c))) {
firstDigit = c;
break;
}
}
thisColumn = nameToColumn(r.substring(0, firstDigit));
Don't forget to reset the column counter on a new row (endElement for row is often a good one to trigger that on)
Thanks #Gagravarr, for giving me the initial idea to solve the problem.
I did not follow, exactly what you suggested though. Instead what I did is, I compared the characters (ASCII values) from the column references, the current one and the last one.
I kept track of the last column reference and checked that the difference between two column reference should always be 1 i.e. B1 - A1 == 1.
Any deviation from this I considered as a skipping of a column.
The solution works perfectly, below is a snippet of what I did:
char currColChar = attributes.getValue("r").charAt(0);
// Check if we have missed a column due to no data
if ((currColChar - lastColumnChar) > 1) {
//logic for column skipped
}
lastColumnChar = currColChar;