Revision: 3633
Author: [email protected]
Date: Tue Jun 22 15:19:40 2010
Log: Added a new tab to the profile viewer to view all of the most frequent
values on column profiles being viewed. The csv and html exports do not yet
export this information.
http://code.google.com/p/power-architect/source/detail?r=3633
Added:
/trunk/src/main/java/ca/sqlpower/architect/swingui/table/MultiFreqValueCountTableModel.java
Modified:
/trunk/src/main/java/ca/sqlpower/architect/swingui/ProfileResultsViewer.java
/trunk/src/main/resources/ca/sqlpower/architect/swingui/messages.properties
=======================================
--- /dev/null
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/table/MultiFreqValueCountTableModel.java
Tue Jun 22 15:19:40 2010
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2010, SQL Power Group Inc.
+ *
+ * This file is part of SQL Power Architect.
+ *
+ * SQL Power Architect is free software; you can redistribute it and/or
modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SQL Power Architect is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package ca.sqlpower.architect.swingui.table;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableCellRenderer;
+
+import ca.sqlpower.architect.profile.ColumnProfileResult;
+import ca.sqlpower.architect.profile.ColumnValueCount;
+import ca.sqlpower.architect.profile.TableProfileResult;
+import ca.sqlpower.swingui.table.PercentTableCellRenderer;
+
+/**
+ * This class is similar to the {...@link FreqValueCountTableModel} except it
+ * displays the information for multiple columns at the same time.
+ */
+public class MultiFreqValueCountTableModel extends AbstractTableModel {
+
+ /**
+ * In the future we may want this to be a different type of listener
when the
+ * {...@link ProfileTableModel} is not the container for the existing set
of
+ * profiles being viewed.
+ */
+ private final TableModelListener profileListListener = new
TableModelListener() {
+ public void tableChanged(TableModelEvent e) {
+ refresh();
+ }
+ };
+
+ /**
+ * Apparently the ProfileTableModel is the object that tracks what
profiles
+ * are currently being viewed by the profile viewer. This seems like
an odd
+ * place to store this information and the ProfileResultsViewer that
+ * actually gets this information first may be more logical. More
+ * investigation into the current state of how the profile UI is
needed to
+ * fully understand and update this set of classes however.
+ */
+ private final ProfileTableModel tm;
+
+ /**
+ * This is the list of currently selected table profile results to
display
+ * in this table model.
+ */
+ private final List<TableProfileResult> tprList = new
ArrayList<TableProfileResult>();
+
+ /**
+ * @param tm
+ * The table model that is used as a collection of all of
the
+ * profiles currently being used.
+ */
+ public MultiFreqValueCountTableModel(ProfileTableModel tm) {
+ this.tm = tm;
+ tm.addTableModelListener(profileListListener);
+ refresh();
+ }
+
+ public void refresh() {
+ tprList.clear();
+ tprList.addAll(tm.getTableResultsToScan());
+ fireTableDataChanged();
+ }
+
+ public int getColumnCount() {
+ return 5;
+ }
+
+ public int getRowCount() {
+ int rowCount = 0;
+ for (TableProfileResult tpr : tprList) {
+ for (ColumnProfileResult cpr : tpr.getColumnProfileResults()) {
+ rowCount += cpr.getValueCount().size();
+ }
+ }
+ return rowCount;
+ }
+
+ @Override
+ public String getColumnName(int column) {
+ switch (column) {
+ case 0:
+ return "Table";
+ case 1:
+ return "Column";
+ case 2:
+ return "Value";
+ case 3:
+ return "Count";
+ case 4:
+ return "%";
+ default:
+ throw new IllegalArgumentException("Column " + column + "
does not exist.");
+ }
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ int rowCount = 0;
+ for (TableProfileResult tpr : tprList) {
+ for (ColumnProfileResult cpr : tpr.getColumnProfileResults()) {
+ if (rowCount + cpr.getValueCount().size() > rowIndex) {
+ ColumnValueCount cvc =
cpr.getValueCount().get(rowIndex - rowCount);
+ switch (columnIndex) {
+ case 0:
+ return tpr.getProfiledObject();
+ case 1:
+ return cpr.getProfiledObject();
+ case 2:
+ return cvc.getValue();
+ case 3:
+ return cvc.getCount();
+ case 4:
+ return cvc.getPercent();
+ default:
+ throw new IllegalArgumentException("Column at
index " + columnIndex + " does not exist.");
+ }
+ }
+ rowCount += cpr.getValueCount().size();
+ }
+ }
+ throw new IllegalStateException("No value for row " + rowIndex);
+ }
+
+ /**
+ * Returns a {...@link TableCellRenderer} that defines how cells of a
column
+ * should be rendered. The renderer returned may not be the same
renderer
+ * each time it is requested.
+ *
+ * @param colIndex
+ * The index of the column whose cell renderer will be
returned.
+ * Must be less than the column count and non-negative.
+ */
+ public TableCellRenderer getCellRenderer(int colIndex) {
+ switch (colIndex) {
+ case 0:
+ case 1:
+ return new SQLObjectTableCellRenderer();
+ case 2:
+ case 3:
+ return new ValueTableCellRenderer();
+ case 4:
+ return new PercentTableCellRenderer();
+ default:
+ throw new IllegalArgumentException("No cell renderer for
column " + colIndex);
+ }
+ }
+}
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/swingui/ProfileResultsViewer.java
Mon Dec 21 08:27:43 2009
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/ProfileResultsViewer.java
Tue Jun 22 15:19:40 2010
@@ -53,6 +53,7 @@
import ca.sqlpower.architect.profile.event.ProfileChangeListener;
import ca.sqlpower.architect.profile.output.ProfileColumn;
import ca.sqlpower.architect.swingui.action.SaveProfileAction;
+import ca.sqlpower.architect.swingui.table.MultiFreqValueCountTableModel;
import ca.sqlpower.architect.swingui.table.ProfileJTable;
import ca.sqlpower.architect.swingui.table.ProfileTableModel;
import ca.sqlpower.sqlobject.SQLColumn;
@@ -60,6 +61,7 @@
import ca.sqlpower.swingui.table.TableModelColumnAutofit;
import ca.sqlpower.swingui.table.TableModelSearchDecorator;
import ca.sqlpower.swingui.table.TableModelSortDecorator;
+import ca.sqlpower.swingui.table.TableTextConverter;
import ca.sqlpower.swingui.table.TableUtils;
/**
@@ -239,6 +241,42 @@
tableViewPane.add(searchPanel,BorderLayout.NORTH);
tabPane.addTab(Messages.getString("ProfileResultsViewer.tableViewTab"),
tableViewPane ); //$NON-NLS-1$
+ final MultiFreqValueCountTableModel columnTableModel = new
MultiFreqValueCountTableModel(tm);
+
+ //Setup a search and sort decorator on the table
+ TableModelSearchDecorator columnSearchDecorator =
+ new TableModelSearchDecorator(columnTableModel);
+ final TableModelSortDecorator columnTableModelSortDecorator =
+ new TableModelSortDecorator(columnSearchDecorator);
+ final JTable columnTable = new
JTable(columnTableModelSortDecorator);
+ columnSearchDecorator.setTableTextConverter(new
TableTextConverter() {
+ public int modelIndex(int viewIndex) {
+ return columnTableModelSortDecorator.modelIndex(viewIndex);
+ }
+
+ public String getTextForCell(int row, int col) {
+ // note: this will only work because we know all the
renderers are jlabels
+ JLabel renderer = (JLabel)
columnTable.getCellRenderer(row, col).
+ getTableCellRendererComponent(columnTable,
columnTable.getModel().getValueAt(row,
+
columnTable.getColumnModel().getColumn(col).getModelIndex()),
+ false, false, row, col);
+ return renderer.getText();
+ }
+ });
+
columnTableModelSortDecorator.setTableHeader(columnTable.getTableHeader());
+
+ for (int i = 0; i < columnTableModel.getColumnCount(); i++) {
+
columnTable.getColumnModel().getColumn(i).setCellRenderer(columnTableModel.getCellRenderer(i));
+ }
+ JPanel columnViewerPanel = new JPanel(new BorderLayout());
+ columnViewerPanel.add(new JScrollPane(columnTable),
BorderLayout.CENTER);
+ JPanel columnSearchPanel = new JPanel(new
FlowLayout(FlowLayout.RIGHT));
+ columnSearchPanel.add(new
JLabel(Messages.getString("ProfileResultsViewer.search"))); //$NON-NLS-1$
+ JTextField columnSearchField = new
JTextField(columnSearchDecorator.getDoc(),"",25); //$NON-NLS-1$
+ columnSearchPanel.add(columnSearchField);
+ columnViewerPanel.add(columnSearchPanel, BorderLayout.NORTH);
+
tabPane.addTab(Messages.getString("ProfileResultsViewer.columnViewTab"),
+ columnViewerPanel);
profilePanelMouseListener.setProfilePanel(p);
=======================================
---
/trunk/src/main/resources/ca/sqlpower/architect/swingui/messages.properties
Sun Jun 20 10:57:59 2010
+++
/trunk/src/main/resources/ca/sqlpower/architect/swingui/messages.properties
Tue Jun 22 15:19:40 2010
@@ -287,6 +287,7 @@
ProfileManagerView.viewAllActionName=View All
ProfileManagerView.viewSelectedActionName=View Selected
ProfileResultsViewer.closeButton=Close
+ProfileResultsViewer.columnViewTab=Column View
ProfileResultsViewer.frameTitle=Table Profiles
ProfileResultsViewer.graphViewTab=Graph View
ProfileResultsViewer.search=Search: