I'm new to Java and I want to know how to fill a JTable with HashMap data. In the hash map, the key is an integer and the value is an array of objects. I want to put the data from the hash map into the table, but I don't know how to get the values.
The HashMap:
Map<Integer, Object[]> prodList = new HashMap<>();
prodList.put(1, new Object[]{"Prod_1", 8000.0, 550}); //name, price, amount
prodList.put(2, new Object[]{"Prod_2", 2300.0, 15});
prodList.put(3, new Object[]{"Prod_3", 2700.0, 15});
I have been trying with this:
public TableModel fillTable(Map<?,?> prodList)
{
DefaultTableModel tableModel = new DefaultTableModel(
new Object[] {"key", "value"}, 0
);
for(Map.Entry<?,?> data : prodList.entrySet())
{
tableModel.addRow(new Object[] {data.getKey(), data.values()});
}
return tableModel;
}
But it just returns the key and this: [L] java.lang.Object; # 1565e42a. I think I have to iterate over the array and put all the array values into a new column, but I don't know how to do it.
I think I have to iterate over the array and put all the array values into a new column,
Correct. You can do this by adding all the values to a Vector and then add the Vector to the model.
Iterator<Integer> iter = prodList.keySet().iterator();
while (iter.hasNext())
{
Vector<Object> row = new Vector<>(4);
Integer key = iter.next();
row.addElement(key);
// Cell represents a row after the inserted row
Object[] values = (Object[])prodList.get(key);
for (Object item: values)
{
row.addElement(item);
}
System.out.println(row);
tableModel.addRow( row );
}
The above code should will create a Vector with 4 items, the first will be the key and the last 3 will be the values in the Array that you added to the HashMap.
Note, I rarely iterate over a HashMap and I don't remember how to use the EntrySet, so I'm just using the old Iterator.
Figured out how to do it using the EntrySet:
for(Map.Entry<Integer,Object[]> data : prodList.entrySet())
{
Vector<Object> row = new Vector<>(4);
row.addElement(data.getKey());
Object[] values = data.getValue();
for (Object item: values)
{
row.addElement(item);
}
System.out.println(row);
tableModel.addRow( row );
}
Related
I want to use a data structure to store column names of a JTable with their respective indexes, so that I can select the corresponding data column. If I filter out a column name, then the name and the index gets removed, if I put it back, the index will be the same. If I want to swap two columns, the indexes change but the column names stay the same. It also has to be serializable. Can I do this with a HashMap<String,Integer>?
I managed to load it with values, I basically filtered the dataList with the selected columnNames. I'm not too familiar with maps. As far as a know, I can't "swap" key's in HashMap
private List<Object[]> data = new ArrayList<Object[]>();
private List<String> columnNames = new ArrayList<String>();
public CustomTableModel(List<Object[]> dataList, Map<Integer,String> columnNames) {
for (Map.Entry<Integer, String> set : columnNames.entrySet()) {
this.columnNames.add(set.getValue());
}
ArrayList<Integer> selectedColIndexes = new ArrayList<Integer>();
for (Map.Entry<Integer, String> set : columnNames.entrySet()) {
selectedColIndexes.add(set.getKey());
}
for(int n=0; n<dataList.size(); n++) {
Object[] selectedRow = new Object[columnNames.size()];
for(int j=0; j<selectedColIndexes.size(); j++) {
int index = selectedColIndexes.get(j);
selectedRow[j]=dataList.get(n)[index];
}
data.add(selectedRow);
}
}
Issue : There will 3 records in testcaseInputs . All the three records are iterated, but at end the "rows" map has only one record which is iterated in the last. I want rows map should contain all the three records.
Issue 2: The iteration takes record1, then record 2, record 3 .. again it takes record 1 or 3 for iteration. I don't know why.
public void addinputtosc() {
try {
Map<String, List<JsonNode>> testrecords = null;
Map<String, String> rows = new Hashmap<String, String>();
// this function takes the input sheet , sheet name and returns data in Map<String, List<JsonNode>> format.
testrecords = fetchScenariosData("C:\\testData.xlsx", "input", "inputParam");
Iterator<Map.Enry<String, List<JsonNode>>> entries = testRecords.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, List<JsonNode>> entry = entries.next();
String scenarioName = entry.getKey();
List<JsonNode> testcaseInputs = entry.getValue();
if (scenarioName.equalsIgnoreCase("TestCase1")) {
ListIterator<JsonNode> listIterator = testCaseInputs.listIterator();
while (listIterator.hasNext()) {
for (JsonNode tcinputs :testCaseInputs) {
String keyValue = tcinputs.toString();
String newKeyValue = keyValue.replaceAll("[{}]", "");
String[] keyValue1 = newKeyValue.split(",");
for (String j : keyValue1) {
String[] keyValueorg = j.split(":");
row.put(keyValueorg[0].substring(1, keyValueorg[0].length() - 1), keyValueorg[1].substring(1, keyValueorg[1].length() - 1));
}
}
}
}
}
} catch (exception e) {
e.printStackTrace();
}
}
Issue : There will 3 records in testcaseInputs . All the three records
are iterated, but at end the "rows" map has only one record which is
iterated in the last. I want rows map should contain all the three
records.
This is happening because of this line :
rows.put(keyValueorg[0].substring(1, keyValueorg[0].length() - 1), keyValueorg[1].substring(1, keyValueorg[1].length() - 1));
when you are procesing frist JsonNode suppose this as per your example
{"File Source Env.":"Unix","TC_ID":"tc1","File Path":"/tmp/test.dat","Date":"20190101"}
the HashMap rows will contain content as :
{Date=20190101, path=/tmp/test.dat, TC_ID=tc1, File Source Env.=Unix}
now when again this codeis executed for second JsonNode suppose this :
{"File Source Env.":"Unix-qa","TC_ID":"tc2","File Path":"/tmp/test1.dat","Date":"20190201"}
as per your code , keys which will be calculated for this new record (keyValueorg[0].substring(1, keyValueorg[0].length() - 1)) is same as the previous key values that are stored in hashmap i.e. Date, File Source Env, TC_ID, Path by the first record.
Since these key values are already present in hashmap there values get updated by new values which is property of PUT operation of HashMap(if key is there then it just override with new values else insert new key in map).
This process will continue and hence only last record values are seen in hashmap.
In order to keep all key-value pairs of all records in single hashmap you need to create different key for each record. Otherwise create a nested hashmap.
How to findcolumn in vector and change a specific column value to show something else on the JTable?
my code looks like this:
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
I would recommend to use Vector<Map<String, Object>> Structure to for your solution.
But if you do not want to use Map, then you can implement this solution.
Have an map which has Column Name and Column Index pair.
Map<String, Integer> columnNameIndexPair
Vector maintains insertion order, so in this case you can Insert objects in the vector. To retrieve data from vector, first find corresponding index from columnNameIndexPair, and get(index) element from vector.
Hashmap contains key and value(result of parsing an XML). Hashmap contains things in the way that key is a string and value is a vector.
A key may have single value in the vector or mutiple values in the vector.
This hashmap, has to be put into a jtable,such that if the key has single value, put it to text box. If it has multiple values insert a combobox in the table.
You may change the code.
hashmap.put(nodeList.item(j).getNodeName(), nodeValueList);
Set keys = PropertyIMPL.hashmap.keySet();
Iterator iteratorKeys = keys.iterator();
while (iteratorKeys.hasNext()) {
String key = (String) iteratorKeys.next();
if (nodeValueList.size() > 1) {
tablemodel.insertRow(0, new Object[]{key});
String[] ss = (String[]) nodeValueList.toArray(
new String[nodeValueList.size()]);
TableColumn col = table.getColumnModel().getColumn(1);
col.setCellEditor(new MyComboBoxEditor(ss));
} else {
tablemodel.insertRow(0, new Object[]{key, nodeValueList});
}
}
keys.clear();
Short answer is you need to override the getCellEditor(...) method of JTable.
I use apache-commons-beanutils DynaBean class in order to fetch rows from a database and to handle them outside of the mysql function.
is there a way to convert a DynaBean to a List without iterating through each row and manually creating the list ?
thanks!
so far I didn't get any answers so I wrote the function that iterates through the rows and creates an ArrayList of HashMap type (String, Object).
public ArrayList<HashMap<String,Object>> convertDynaBeanListToArrayList(List<DynaBean> theList) {
ArrayList<HashMap<String,Object>> result = new ArrayList<HashMap<String,Object>>();
DynaProperty[] dynaProperties = null;
for (Integer i=0;i<theList.size();i++) {
DynaBean row = theList.get(i);
HashMap<String,Object> resultRow=new HashMap<String,Object>();
// each raw got the same column names, no need to fetch this for every line
if (dynaProperties == null) {
dynaProperties = row.getDynaClass().getDynaProperties();
}
for (Integer j=0;j<dynaProperties.length;j++) {
String columnName=dynaProperties[j].getName();
resultRow.put(columnName, row.get(columnName));
}
result.add(resultRow);
}
return result;
}