Re-implement sorting algorithm of table and modified FpdFrameworkModules.java to using new interfaces.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1340 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jlin16 2006-08-21 22:03:24 +00:00
parent b5471b38bc
commit d78abb5a95
2 changed files with 181 additions and 267 deletions

View File

@ -1,3 +1,17 @@
/** @file
The file is used to create, update FrameworkModules of Fpd file
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.frameworkwizard.platform.ui;
import java.awt.BorderLayout;
@ -35,6 +49,8 @@ public class FpdFrameworkModules extends IInternalFrame {
* Initialize Globals
*/
private static final long serialVersionUID = 1L;
public static final int forceDbgColForFpdModTable = 7;
static JFrame frame;
@ -68,7 +84,7 @@ public class FpdFrameworkModules extends IInternalFrame {
private NonEditableTableModel modelAllModules = null;
private NonEditableTableModel modelFpdModules = null;
private FpdModulesTableModel modelFpdModules = null;
private FpdModuleSA settingDlg = null;
@ -321,7 +337,7 @@ public class FpdFrameworkModules extends IInternalFrame {
}
TableSorter sorter = (TableSorter) jTableAllModules.getModel();
selectedRow = sorter.modelIndex(selectedRow);
selectedRow = sorter.getModelRowIndex(selectedRow);
String path = modelAllModules.getValueAt(selectedRow, pathColForAllModTable) + "";
ModuleIdentification mi = miList.get(selectedRow);
Vector<String> vArchs = null;
@ -419,7 +435,7 @@ public class FpdFrameworkModules extends IInternalFrame {
}
JOptionPane.showMessageDialog(frame, s);
TableSorter sorterFpdModules = (TableSorter)jTableFpdModules.getModel();
int viewIndex = sorterFpdModules.getModelToView()[modelFpdModules.getRowCount() - 1];
int viewIndex = sorterFpdModules.getViewIndexArray()[modelFpdModules.getRowCount() - 1];
jTableFpdModules.changeSelection(viewIndex, 0, false, false);
}
});
@ -467,7 +483,7 @@ public class FpdFrameworkModules extends IInternalFrame {
*/
private JTable getJTableFpdModules() {
if (jTableFpdModules == null) {
modelFpdModules = new NonEditableTableModel();
modelFpdModules = new FpdModulesTableModel();
TableSorter sorter = new TableSorter(modelFpdModules);
jTableFpdModules = new JTable(sorter);
sorter.setTableHeader(jTableFpdModules.getTableHeader());
@ -479,7 +495,7 @@ public class FpdFrameworkModules extends IInternalFrame {
modelFpdModules.addColumn("<html>Module<br>Type</html>");
modelFpdModules.addColumn("<html>Module<br>Version</html>");
modelFpdModules.addColumn("<html>Package<br>Version</html>");
modelFpdModules.addColumn("<html>Force<br>Debug</html>");
javax.swing.table.TableColumn column = null;
column = jTableFpdModules.getColumnModel().getColumn(modNameColForFpdModTable);
@ -535,7 +551,7 @@ public class FpdFrameworkModules extends IInternalFrame {
}
TableSorter sorter = (TableSorter) jTableFpdModules.getModel();
selectedRow = sorter.modelIndex(selectedRow);
selectedRow = sorter.getModelRowIndex(selectedRow);
try {
if (ffc.adjustPcd(selectedRow)) {
docConsole.setSaved(false);
@ -584,7 +600,7 @@ public class FpdFrameworkModules extends IInternalFrame {
docConsole.setSaved(false);
TableSorter sorter = (TableSorter) jTableFpdModules.getModel();
selectedRow = sorter.modelIndex(selectedRow);
selectedRow = sorter.getModelRowIndex(selectedRow);
String[] sa = new String[5];
ffc.getFrameworkModuleInfo(selectedRow, sa);
@ -667,7 +683,7 @@ public class FpdFrameworkModules extends IInternalFrame {
for (int i = 0; i < saa.length; ++i) {
ModuleIdentification mi = WorkspaceProfile.getModuleId(saa[i][ffcModGuid] + " " + saa[i][ffcModVer] + " "
+ saa[i][ffcPkgGuid] + " " + saa[i][ffcPkgVer]);
String[] row = { "", "", "", "", "", "", "" };
Object[] row = { "", "", "", "", "", "", "", "" };
if (mi != null) {
row[modNameColForFpdModTable] = mi.getName();
row[modVerColForFpdModTable] = mi.getVersion();
@ -692,11 +708,12 @@ public class FpdFrameworkModules extends IInternalFrame {
}
al.add(saa[i][ffcModArch]);
}
row[forceDbgColForFpdModTable] = ffc.getModuleSAForceDebug(i);
modelFpdModules.addRow(row);
}
TableSorter sorter = (TableSorter)jTableFpdModules.getModel();
sorter.setSortingStatus(modNameColForFpdModTable, TableSorter.ASCENDING);
sorter.setSortState(modNameColForFpdModTable, TableSorter.ASCENDING);
}
showAllModules();
@ -736,7 +753,7 @@ public class FpdFrameworkModules extends IInternalFrame {
}
TableSorter sorter = (TableSorter)jTableAllModules.getModel();
sorter.setSortingStatus(modNameColForAllModTable, TableSorter.ASCENDING);
sorter.setSortState(modNameColForAllModTable, TableSorter.ASCENDING);
}
/**
@ -764,3 +781,25 @@ class NonEditableTableModel extends DefaultTableModel {
return false;
}
}
class FpdModulesTableModel extends DefaultTableModel {
/**
*
*/
private static final long serialVersionUID = 1L;
public Class<?> getColumnClass (int c) {
if (getValueAt(0, c) != null){
return getValueAt(0, c).getClass();
}
return String.class;
}
public boolean isCellEditable (int row, int col) {
if (col == FpdFrameworkModules.forceDbgColForFpdModTable) {
return true;
}
return false;
}
}

View File

@ -1,11 +1,22 @@
/** @file
The file is used to sort FrameworkModules of Fpd file
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.frameworkwizard.platform.ui;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;
@ -17,55 +28,45 @@ public class TableSorter extends AbstractTableModel {
*/
private static final long serialVersionUID = 1L;
protected TableModel tableModel;
protected DefaultTableModel tableModel;
private TableRow[] rowInView;
private int[] viewPos;
public static final int DESCENDING = -1;
public static final int NOT_SORTED = 0;
public static final int ASCENDING = 1;
private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
private Row[] viewToModel;
private int[] modelToView;
public static final String DESCENDING = "down";
public static final String NOT_SORTED = "none";
public static final String ASCENDING = "up";
private JTableHeader tableHeader;
private MouseListener mouseListener;
private TableModelListener tableModelListener;
private MouseListener mouseListener = new MouseHandler();
private TableModelListener tableModelListener = new TableModelHandler();
private List<Directive> sortingColumns = new ArrayList<Directive>();
private HashMap<Integer, String> sortingOrders = new HashMap<Integer, String>();
public TableSorter() {
this.mouseListener = new MouseHandler();
this.tableModelListener = new TableModelHandler();
}
public TableSorter(TableModel tableModel) {
this();
public TableSorter(DefaultTableModel tableModel) {
setTableModel(tableModel);
}
private void clearSortingState() {
viewToModel = null;
modelToView = null;
private void resetSortState() {
rowInView = null;
viewPos = null;
}
public TableModel getTableModel() {
public DefaultTableModel getTableModel() {
return tableModel;
}
public void setTableModel(TableModel tableModel) {
if (this.tableModel != null) {
this.tableModel.removeTableModelListener(tableModelListener);
public void setTableModel(DefaultTableModel dtm) {
if (tableModel != null) {
tableModel.removeTableModelListener(tableModelListener);
}
this.tableModel = tableModel;
if (this.tableModel != null) {
this.tableModel.addTableModelListener(tableModelListener);
tableModel = dtm;
if (tableModel != null) {
tableModel.addTableModelListener(tableModelListener);
}
clearSortingState();
resetSortState();
fireTableStructureChanged();
}
@ -73,153 +74,132 @@ public class TableSorter extends AbstractTableModel {
return tableHeader;
}
public void setTableHeader(JTableHeader tableHeader) {
if (this.tableHeader != null) {
this.tableHeader.removeMouseListener(mouseListener);
TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
if (defaultRenderer instanceof SortableHeaderRenderer) {
this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
}
}
this.tableHeader = tableHeader;
if (this.tableHeader != null) {
this.tableHeader.addMouseListener(mouseListener);
this.tableHeader.setDefaultRenderer(
new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
}
}
public boolean isSorting() {
return sortingColumns.size() != 0;
}
private Directive getDirective(int column) {
for (int i = 0; i < sortingColumns.size(); i++) {
Directive directive = (Directive)sortingColumns.get(i);
if (directive.column == column) {
return directive;
}
}
return EMPTY_DIRECTIVE;
}
public int getSortingStatus(int column) {
return getDirective(column).direction;
}
private void sortingStatusChanged() {
clearSortingState();
fireTableDataChanged();
public void setTableHeader(JTableHeader th) {
if (tableHeader != null) {
tableHeader.repaint();
tableHeader.removeMouseListener(mouseListener);
}
tableHeader = th;
if (tableHeader != null) {
tableHeader.addMouseListener(mouseListener);
}
}
public void setSortingStatus(int column, int status) {
Directive directive = getDirective(column);
if (directive != EMPTY_DIRECTIVE) {
sortingColumns.remove(directive);
private String getSortState(int column) {
Integer i = new Integer(column);
if (sortingOrders.get(i) != null) {
return sortingOrders.get(i);
}
if (status != NOT_SORTED) {
sortingColumns.add(new Directive(column, status));
}
sortingStatusChanged();
return NOT_SORTED;
}
protected Icon getHeaderRendererIcon(int column, int size) {
Directive directive = getDirective(column);
if (directive == EMPTY_DIRECTIVE) {
return null;
}
return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));
private void sortStateChanged() {
resetSortState();
fireTableDataChanged();
}
private void cancelSorting() {
sortingColumns.clear();
sortingStatusChanged();
public void setSortState(int column, String status) {
Integer i = new Integer(column);
sortingOrders.put(i, status);
sortStateChanged();
}
private Row[] getViewToModel() {
if (viewToModel == null) {
int tableModelRowCount = tableModel.getRowCount();
viewToModel = new Row[tableModelRowCount];
for (int row = 0; row < tableModelRowCount; row++) {
viewToModel[row] = new Row(row);
private TableRow[] getSortedViewRows() {
if (rowInView == null) {
int rowCount = tableModel.getRowCount();
rowInView = new TableRow[rowCount];
int i = 0;
while ( i < rowCount ) {
rowInView[i] = new TableRow(i);
++i;
}
if (isSorting()) {
Arrays.sort(viewToModel);
if (sortingOrders.size() != 0) {
Arrays.sort(rowInView);
}
}
return viewToModel;
return rowInView;
}
public int modelIndex(int viewIndex) {
return getViewToModel()[viewIndex].modelIndex;
public int getModelRowIndex(int viewIndex) {
TableRow[] rArray = getSortedViewRows();
return rArray[viewIndex].modelIndex;
}
public int[] getModelToView() {
if (modelToView == null) {
int n = getViewToModel().length;
modelToView = new int[n];
public int[] getViewIndexArray() {
if (viewPos == null) {
int n = getSortedViewRows().length;
viewPos = new int[n];
for (int i = 0; i < n; i++) {
modelToView[modelIndex(i)] = i;
viewPos[getModelRowIndex(i)] = i;
}
}
return modelToView;
return viewPos;
}
// TableModel interface methods
public int getRowCount() {
return (tableModel == null) ? 0 : tableModel.getRowCount();
if (tableModel == null) {
return 0;
}
return tableModel.getRowCount();
}
public String getColumnName(int col) {
return tableModel.getColumnName(col);
}
public int getColumnCount() {
return (tableModel == null) ? 0 : tableModel.getColumnCount();
if (tableModel == null) {
return 0;
}
return tableModel.getColumnCount();
}
public String getColumnName(int column) {
return tableModel.getColumnName(column);
public Class<?> getColumnClass(int col) {
return tableModel.getColumnClass(col);
}
public Class<?> getColumnClass(int column) {
return tableModel.getColumnClass(column);
public boolean isCellEditable(int row, int col) {
int modelIndex = getModelRowIndex(row);
return tableModel.isCellEditable(modelIndex, col);
}
public boolean isCellEditable(int row, int column) {
return tableModel.isCellEditable(modelIndex(row), column);
public Object getValueAt(int row, int col) {
int modelIndex = getModelRowIndex(row);
return tableModel.getValueAt(modelIndex, col);
}
public Object getValueAt(int row, int column) {
return tableModel.getValueAt(modelIndex(row), column);
}
public void setValueAt(Object aValue, int row, int column) {
tableModel.setValueAt(aValue, modelIndex(row), column);
public void setValueAt(Object val, int row, int col) {
int modelIndex = getModelRowIndex(row);
tableModel.setValueAt(val, modelIndex, col);
}
// Helper classes
private class Row implements Comparable {
private class TableRow implements Comparable {
private int modelIndex;
public Row(int index) {
public TableRow(int index) {
this.modelIndex = index;
}
public int compareTo(Object o) {
int row1 = modelIndex;
int row2 = ((Row) o).modelIndex;
int row2 = ((TableRow) o).modelIndex;
Iterator<Integer> mapIter = sortingOrders.keySet().iterator();
for (Iterator it = sortingColumns.iterator(); it.hasNext();) {
Directive directive = (Directive) it.next();
int column = directive.column;
while (mapIter.hasNext()) {
Integer column = mapIter.next();
Object o1 = tableModel.getValueAt(row1, column);
Object o2 = tableModel.getValueAt(row2, column);
int comparison = 0;
// Define null less than everything, except null.
if (o1 == null && o2 == null) {
comparison = 0;
} else if (o1 == null) {
@ -230,7 +210,10 @@ public class TableSorter extends AbstractTableModel {
comparison = o1.toString().compareTo(o2.toString());;
}
if (comparison != 0) {
return directive.direction == DESCENDING ? -comparison : comparison;
if (getSortState(column.intValue()).equals(DESCENDING)) {
return -comparison;
}
return comparison;
}
}
return 0;
@ -239,54 +222,29 @@ public class TableSorter extends AbstractTableModel {
private class TableModelHandler implements TableModelListener {
public void tableChanged(TableModelEvent e) {
// If we're not sorting by anything, just pass the event along.
if (!isSorting()) {
clearSortingState();
if (sortingOrders.size() != 0) {
resetSortState();
fireTableChanged(e);
return;
}
// If the table structure has changed, cancel the sorting; the
// sorting columns may have been either moved or deleted from
// the model.
if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
cancelSorting();
fireTableChanged(e);
return;
}
// We can map a cell event through to the view without widening
// when the following conditions apply:
//
// a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and,
// b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
// c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and,
// d) a reverse lookup will not trigger a sort (modelToView != null)
//
// Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
//
// The last check, for (modelToView != null) is to see if modelToView
// is already allocated. If we don't do this check; sorting can become
// a performance bottleneck for applications where cells
// change rapidly in different parts of the table. If cells
// change alternately in the sorting column and then outside of
// it this class can end up re-sorting on alternate cell updates -
// which can be a performance problem for large tables. The last
// clause avoids this problem.
int column = e.getColumn();
if (e.getFirstRow() == e.getLastRow()
&& column != TableModelEvent.ALL_COLUMNS
&& getSortingStatus(column) == NOT_SORTED
&& modelToView != null) {
int viewIndex = getModelToView()[e.getFirstRow()];
&& getSortState(column).equals(NOT_SORTED)
&& viewPos != null) {
int viewIndex = getViewIndexArray()[e.getFirstRow()];
fireTableChanged(new TableModelEvent(TableSorter.this,
viewIndex, viewIndex,
column, e.getType()));
return;
}
// Something has happened to the data that may have invalidated the row order.
clearSortingState();
resetSortState();
fireTableDataChanged();
return;
}
@ -298,105 +256,22 @@ public class TableSorter extends AbstractTableModel {
TableColumnModel columnModel = h.getColumnModel();
int viewColumn = columnModel.getColumnIndexAtX(e.getX());
int column = columnModel.getColumn(viewColumn).getModelIndex();
if (column != -1) {
int status = getSortingStatus(column);
if (!e.isControlDown()) {
cancelSorting();
if (column == 0) {
String status = getSortState(column);
if (status.equals(ASCENDING)) {
status = DESCENDING;
}
// Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or
// {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed.
status = status + (e.isShiftDown() ? -1 : 1);
status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1}
setSortingStatus(column, status);
else if (status.equals(DESCENDING)) {
status = NOT_SORTED;
}
else if (status.equals(NOT_SORTED)) {
status = ASCENDING;
}
setSortState(column, status);
}
}
}
private static class Arrow implements Icon {
private boolean descending;
private int size;
private int priority;
public Arrow(boolean descending, int size, int priority) {
this.descending = descending;
this.size = size;
this.priority = priority;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
Color color = c == null ? Color.GRAY : c.getBackground();
// In a compound sort, make each succesive triangle 20%
// smaller than the previous one.
int dx = (int)(size/2*Math.pow(0.8, priority));
int dy = descending ? dx : -dx;
// Align icon (roughly) with font baseline.
y = y + 5*size/6 + (descending ? -dy : 0);
int shift = descending ? 1 : -1;
g.translate(x, y);
// Right diagonal.
g.setColor(color.darker());
g.drawLine(dx / 2, dy, 0, 0);
g.drawLine(dx / 2, dy + shift, 0, shift);
// Left diagonal.
g.setColor(color.brighter());
g.drawLine(dx / 2, dy, dx, 0);
g.drawLine(dx / 2, dy + shift, dx, shift);
// Horizontal line.
if (descending) {
g.setColor(color.darker().darker());
} else {
g.setColor(color.brighter().brighter());
}
g.drawLine(dx, 0, 0, 0);
g.setColor(color);
g.translate(-x, -y);
}
public int getIconWidth() {
return size;
}
public int getIconHeight() {
return size;
}
}
private class SortableHeaderRenderer implements TableCellRenderer {
private TableCellRenderer tableCellRenderer;
public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {
this.tableCellRenderer = tableCellRenderer;
}
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component c = tableCellRenderer.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
if (c instanceof JLabel) {
JLabel l = (JLabel) c;
l.setHorizontalTextPosition(JLabel.LEFT);
int modelColumn = table.convertColumnIndexToModel(column);
l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize()));
}
return c;
}
}
private static class Directive {
private int column;
private int direction;
public Directive(int column, int direction) {
this.column = column;
this.direction = direction;
}
}
}