Hi,
The data for my JTable contains a Map of objects that looks something
like this:
Public Class MyData {
...
public String getName();
public String getSymbol();
public float getLast();
public float getHigh();
public float getLow();
...
...
public float getSomeFieldN();
}
basically class contains about 20 data members. I use a config file to
allow users to select what columns the want to display. typically they
will choose only 8 columns or so. I have two questions:
1) This object contains data that will represent a ROW in a table. the
Key for each row in my Map will be Symbol. How can i use these object
in a table model WITHOUT having to depend on the table column position.
right now all the methods of table model require either an row or
column index to do it's thing. Is there a way to do this using keys
instead?
You have to map the key to some row index. For instance, when you set
the Map as data for the table model, you obtain all the keys of the Map
(the symbols) and assing them a row index.
2) I need to also allow users to move columns around. How can i ensure
that when this is done, the column that maps to my data remain sync?
Your table model should take care of this.
Below is an example of using such a table model. It has a fixed set of
columns. You'll have to change it to make the columns configurable.
import java.awt.BorderLayout;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
public class MappedDataTable {
private static void add(MyData myData, Map data) {
data.put(myData.getSymbol(), myData);
}
public static void main(String[] args) {
MyTableModel tableModel = new MyTableModel();
JTable table = new JTable();
table.setModel(tableModel);
JScrollPane scroll = new JScrollPane();
scroll.getViewport().add(table);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
contentPane.add(scroll, BorderLayout.CENTER);
JFrame app = new JFrame();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setContentPane(contentPane);
app.setSize(300, 200);
app.setLocationRelativeTo(null); //center on screen
app.setVisible(true);
Map data = new HashMap();
add(new MyData("H", "Hydrogen", 1.0f, 1.00794f), data);
add(new MyData("He", "Helium", 2.0f, 4.002602f), data);
add(new MyData("Li", "Lithium", 3.0f, 6.941f), data);
tableModel.setData(data);
}
}
class MyData {
private float high;
private float last;
private String name;
private String symbol;
public MyData(String symbol) {
this.symbol = symbol;
}
public MyData(String symbol, String name, float last, float high) {
this(symbol);
this.name = name;
this.last = last;
this.high = high;
}
public float getHigh() {
return this.high;
}
public float getLast() {
return this.last;
}
public String getName() {
return this.name;
}
public String getSymbol() {
return this.symbol;
}
public void setHigh(float high) {
this.high = high;
}
public void setLast(float last) {
this.last = last;
}
public void setName(String name) {
this.name = name;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
}
class MyTableModel extends AbstractTableModel {
public final static int COLUMN_HIGH = 3;
public final static int COLUMN_LAST = 2;
public final static int COLUMN_NAME = 1;
public final static int COLUMN_SYMBOL = 0;
public final static int NUMBER_OF_COLUMNS = 4;
private Map data;
private String[] symbolRows = new String[0];
public Class getColumnClass(int columnIndex) {
switch (columnIndex) {
case COLUMN_NAME:
return String.class;
case COLUMN_SYMBOL:
return String.class;
case COLUMN_LAST:
return Float.class;
case COLUMN_HIGH:
return Float.class;
default:
System.err.print("No implementation for getColumnClass("
+ columnIndex + ")");
return Object.class;
}
}
public int getColumnCount() {
return NUMBER_OF_COLUMNS;
}
public String getColumnName(int columnIndex) {
switch (columnIndex) {
case COLUMN_NAME:
return "Name";
case COLUMN_SYMBOL:
return "Symbol";
case COLUMN_LAST:
return "Last";
case COLUMN_HIGH:
return "High";
default:
System.err.print("No implementation for getColumnName("
+ columnIndex + ")");
return "Column " + columnIndex;
}
}
public Map getData() {
return data;
}
public int getRowCount() {
return symbolRows == null ? 0 : symbolRows.length;
}
public Object getValueAt(int rowIndex, int columnIndex) {
MyData row = (MyData) data.get(symbolRows[rowIndex]);
switch (columnIndex) {
case COLUMN_NAME:
return row.getName();
case COLUMN_SYMBOL:
return row.getSymbol();
case COLUMN_LAST:
return new Float(row.getLast());
case COLUMN_HIGH:
return new Float(row.getHigh());
default:
System.err.print("No implementation for getValueAt("
+ rowIndex + "," + columnIndex + ")");
return null;
}
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
switch (columnIndex) {
case COLUMN_NAME:
return true;
case COLUMN_SYMBOL:
return false; // we don't want the Symbol column to be editable
case COLUMN_LAST:
return true;
case COLUMN_HIGH:
return true;
default:
System.err.print("No implementation for isCellEditable("
+ rowIndex + "," + columnIndex + ")");
return false;
}
}
public void setData(Map data) {
this.data = data;
if (data == null) {
symbolRows = new String[0];
} else {
Set keys = data.keySet();
symbolRows = new String[keys.size()];
int j = 0;
for (Iterator i = keys.iterator(); i.hasNext()
{
Object symbolKey = i.next();
assert symbolKey.equals(((MyData)
data.get(symbolKey)).getSymbol());
symbolRows[j] = (String) symbolKey;
j++;
}
}
fireTableDataChanged();
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
String value = aValue.toString();
MyData row = (MyData) data.get(symbolRows[rowIndex]);
switch (columnIndex) {
case COLUMN_NAME:
row.setName(value);
break;
case COLUMN_SYMBOL:
// not editable;
return;
case COLUMN_LAST:
try {
row.setLast(Float.parseFloat(value.trim()));
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
break;
case COLUMN_HIGH:
try {
row.setHigh(Float.parseFloat(value.trim()));
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
break;
default:
System.err.print("No implementation for setValueAt("
+ aValue + "," + rowIndex + "," + columnIndex + ")");
return;
}
fireTableCellUpdated(rowIndex, columnIndex);
}
}
--
Regards,
Roland de Ruiter
___ ___
/__/ w_/ /__/
/ \ /_/ / \