package edu.brown.gui.stats;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import edu.brown.catalog.CatalogKey;
import edu.brown.gui.AbstractInfoPanel;
import edu.brown.gui.AbstractViewer;
import edu.brown.statistics.TableStatistics;
/**
*
* @author pavlo
*
*/
public class TableStatsPanel extends AbstractInfoPanel<TableStatistics> {
private static final long serialVersionUID = 1L;
private JLabel tableLabel;
private JLabel partitionLabel;
private Map<TableStatistics.Members, JComponent> field_map;
protected class MapFieldEditor<T> extends JPanel {
private static final long serialVersionUID = 1L;
protected SortedMap<T, Long> map;
protected List<T> elements = new ArrayList<T>();
protected JTable table;
public MapFieldEditor() {
super();
this.init();
}
public void setMap(SortedMap<T, Long> map) {
this.map = map;
this.elements.addAll(this.map.keySet());
this.table.revalidate();
}
private void init() {
this.setLayout(new BorderLayout());
this.table = new JTable(new AbstractTableModel() {
private static final long serialVersionUID = 1L;
protected final String columns[] = { "ID", "VALUE" };
public String getColumnName(int col) {
return (this.columns[col]);
}
public int getColumnCount() {
return (this.columns.length);
}
public int getRowCount() {
return (elements.size());
}
public Object getValueAt(int row, int col) {
T element = elements.get(row);
Long value = map.get(element);
return (col == 0 ? element : value).toString();
}
public void setValueAt(Object aValue, int row, int column) {
T element = elements.get(row);
Long value = Long.valueOf(aValue.toString());
map.put(element, value);
}
public boolean isCellEditable(int row, int col) {
return (col != 0);
}
public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
});
this.table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
this.table.setFillsViewportHeight(true);
this.table.setDragEnabled(false);
this.table.setColumnSelectionAllowed(false);
this.table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
this.add(new JScrollPane(this.table), BorderLayout.CENTER);
}
} // END CLASS
public TableStatsPanel() {
super();
}
public TableStatsPanel(TableStatistics stats) {
this();
this.update(stats);
}
@Override
protected void init() throws Exception {
this.field_map = new HashMap<TableStatistics.Members, JComponent>();
this.setLayout(new GridBagLayout());
JLabel label = null;
GridBagConstraints c = AbstractViewer.getConstraints();
c.gridx = 0;
c.gridy = 0;
label = new JLabel("Table:");
label.setFont(AbstractViewer.key_font);
this.add(label, c);
c.gridx = 1;
this.tableLabel = new JLabel();
this.tableLabel.setFont(AbstractViewer.value_font);
this.add(this.tableLabel, c);
c.gridx = 0;
c.gridy++;
label = new JLabel("Num of Partitions:");
label.setFont(AbstractViewer.key_font);
this.add(label, c);
c.gridx = 1;
this.partitionLabel = new JLabel();
this.partitionLabel.setFont(AbstractViewer.value_font);
this.add(this.partitionLabel, c);
AbstractViewer.addSeperator(this, c);
//
// Editable Fields
//
String last_category = null;
Class<TableStatistics> statsClass = TableStatistics.class;
for (TableStatistics.Members element : TableStatistics.Members.values()) {
// FIXME if (element == TableStatistics.Members.PARTITION_COUNT) continue;
String name = element.toString().replace('_', ' ');
Field field = statsClass.getDeclaredField(element.toString().toLowerCase());
JComponent component = null;
String pieces[] = name.split(" ");
String category = (pieces.length == 3 && pieces[0].equals("TUPLE") ? pieces[1] : pieces[0]);
if (last_category != null && !last_category.equals(category)) {
AbstractViewer.addSpacer(this, c);
}
//System.out.println(name + " --> " + category);
c.gridx = 0;
c.gridy++;
label = new JLabel(name + ":");
label.setFont(AbstractViewer.key_font);
this.add(label, c);
c.gridx = 1;
// Integer fields
Class<?> elementClass = field.getType();
if (elementClass.equals(Long.class)) {
component = new JTextField(10);
// Boolean checkboxes
} else if (elementClass.equals(Boolean.class)) {
component = new JCheckBox();
// Other
} else {
// HACK
/* FIXME
switch (element) {
case TUPLE_COUNT_PARTITIONS:
component = new MapFieldEditor<Integer>();
break;
case TUPLE_SIZE_PARTITIONS:
component = new MapFieldEditor<Integer>();
break;
case QUERY_TYPE_COUNT:
component = new MapFieldEditor<QueryType>();
break;
default:
LOG.fatal("Unexpected element '" + element + "'");
System.exit(1);
} // SWITCH
*/
}
this.add(component, c);
this.field_map.put(element, component);
last_category = category;
} // FOR
}
@SuppressWarnings("unchecked")
public void update(TableStatistics stats) {
this.element = stats;
this.tableLabel.setText(CatalogKey.getNameFromKey(stats.getCatalogKey()));
// FIXME this.partitionLabel.setText(stats.partition_count.toString());
Class<TableStatistics> statsClass = TableStatistics.class;
for (TableStatistics.Members element : this.field_map.keySet()) {
JComponent component = this.field_map.get(element);
Field field = null;
try {
field = statsClass.getDeclaredField(element.toString().toLowerCase());
if (component instanceof JTextField) {
((JTextField)component).setText(field.get(stats).toString());
} else if (component instanceof JCheckBox) {
((JCheckBox)component).setSelected((Boolean)field.get(stats));
} else {
// HACK
/* FIXME
switch (element) {
case TUPLE_COUNT_PARTITIONS:
((MapFieldEditor)component).setMap(stats.tuple_count_partitions);
break;
case TUPLE_SIZE_PARTITIONS:
((MapFieldEditor)component).setMap(stats.tuple_size_partitions);
break;
case QUERY_TYPE_COUNT:
((MapFieldEditor)component).setMap(stats.query_type_count);
break;
default:
LOG.fatal("Unexpected element '" + element + "'");
System.exit(1);
} // SWITCH
*/
Dimension size = ((MapFieldEditor)component).getSize();
((MapFieldEditor)component).setMinimumSize(new Dimension(size.width, size.height+50));
}
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
}
public void save() {
Class<TableStatistics> statsClass = TableStatistics.class;
for (TableStatistics.Members element : this.field_map.keySet()) {
JComponent component = this.field_map.get(element);
Field field = null;
try {
field = statsClass.getDeclaredField(element.toString().toLowerCase());
if (component instanceof JTextField) {
String value = ((JTextField)component).getText();
field.set(this.element, Long.valueOf(value));
} else if (component instanceof JCheckBox) {
Boolean value = ((JCheckBox)component).isSelected();
field.set(this.element, value);
}
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
}
}