package jdepend.client.ui.result.panel; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.event.MouseInputListener; import javax.swing.plaf.basic.BasicTableUI; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableModel; import jdepend.client.report.ui.RelationDetailDialog; import jdepend.client.ui.result.framework.SubResultTabPanel; import jdepend.framework.ui.component.JDependFrame; import jdepend.model.JDependUnit; import jdepend.model.MetricsMgr; import jdepend.model.result.AnalysisResult; import jdepend.model.util.JDependUnitByMetricsComparator; /** * 二维格 * * @author wangdg * */ public final class TwoDimensionCell extends SubResultTabPanel { private DefaultTableModel model; private JTable table; private AnalysisResult result; private List<JDependUnit> units; private JDependFrame frame; public TwoDimensionCell(JDependFrame frame) { this.frame = frame; } @Override protected void init(final AnalysisResult result) { this.result = result; units = new ArrayList<JDependUnit>(result.getComponents()); Collections.sort(units, new JDependUnitByMetricsComparator(MetricsMgr.Ca)); this.setLayout(new BorderLayout()); this.add(initTable()); this.showTable(); } private JComponent initTable() { model = new DefaultTableModel() { @Override public boolean isCellEditable(int row, int column) { return false; } }; table = new JTable(model) { @Override public TableCellRenderer getCellRenderer(int row, int column) { return new TDCRenderer(); } }; table.setUI(new DragDropRowTableUI()); table.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseMoved(MouseEvent e) { Point p = new Point(e.getX(), e.getY()); int col = table.columnAtPoint(p); int row = table.rowAtPoint(p); String left = (String) table.getValueAt(row, 0); String right = (String) table.getColumnModel().getColumn(col).getHeaderValue(); jdepend.model.Component leftComponent = result.getTheComponent(left); jdepend.model.Component rightComponent = result.getTheComponent(right); if (left != null && left.length() != 0 && right != null && right.length() != 0 && isRelation(leftComponent, rightComponent)) { table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } else if (left != null && left.length() != 0 && right != null && right.length() != 0 && isRelation(rightComponent, leftComponent)) { table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } else { table.setCursor(Cursor.getDefaultCursor()); } } }); table.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { JTable table = (JTable) e.getSource(); if (e.getClickCount() == 2) { String left = (String) table.getValueAt(table.rowAtPoint(e.getPoint()), 0); String right = (String) table.getColumnModel().getColumn(table.columnAtPoint(e.getPoint())) .getHeaderValue(); jdepend.model.Component leftComponent = result.getTheComponent(left); jdepend.model.Component rightComponent = result.getTheComponent(right); if (isRelation(leftComponent, rightComponent)) { RelationDetailDialog d = new RelationDetailDialog(frame, leftComponent, rightComponent); d.setModal(true); d.setVisible(true); } else if (isRelation(rightComponent, leftComponent)) { RelationDetailDialog d = new RelationDetailDialog(frame, rightComponent, leftComponent); d.setModal(true); d.setVisible(true); } } } }); model.addColumn(""); for (JDependUnit unit : units) { model.addColumn(unit.getName()); } return new JScrollPane(table); } private void showTable() { Object[] row; for (JDependUnit unit : units) { row = new Object[units.size() + 1]; row[0] = unit.getName(); model.addRow(row); } } private boolean isRelation(jdepend.model.Component left, jdepend.model.Component right) { return left.getEfferents().contains(right); } class TDCRenderer extends DefaultTableCellRenderer { public TDCRenderer() { super(); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, final int row, final int column) { String left = (String) table.getValueAt(row, 0); String right = (String) table.getColumnModel().getColumn(column).getHeaderValue(); jdepend.model.Component leftComponent = result.getTheComponent(left); jdepend.model.Component rightComponent = result.getTheComponent(right); if (left != null && left.length() != 0 && right != null && right.length() != 0 && isRelation(leftComponent, rightComponent)) { this.setBackground(Color.ORANGE); } else if (left != null && left.length() != 0 && right != null && right.length() != 0 && TwoDimensionCell.this.isRelation(rightComponent, leftComponent)) { this.setBackground(Color.CYAN); } else if (column == 0) { JTableHeader header = table.getTableHeader(); setOpaque(true); setBorder(BorderFactory.createEtchedBorder()); setHorizontalAlignment(CENTER); setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); setText(value == null ? "" : value.toString()); } else { return super.getTableCellRendererComponent(table, value, hasFocus, hasFocus, column, column); } return this; } } class DragDropRowTableUI extends BasicTableUI { private boolean draggingRow = false; private int startDragPoint; private int dyOffset; protected MouseInputListener createMouseInputListener() { return new DragDropRowMouseInputHandler(); } public void paint(Graphics g, JComponent c) { super.paint(g, c); if (draggingRow) { g.setColor(table.getParent().getBackground()); Rectangle cellRect = table.getCellRect(table.getSelectedRow(), 0, false); g.copyArea(cellRect.x, cellRect.y, table.getWidth(), table.getRowHeight(), cellRect.x, dyOffset); if (dyOffset < 0) { g.fillRect(cellRect.x, cellRect.y + (table.getRowHeight() + dyOffset), table.getWidth(), (dyOffset * -1)); } else { g.fillRect(cellRect.x, cellRect.y, table.getWidth(), dyOffset); } } } class DragDropRowMouseInputHandler extends MouseInputHandler { public void mousePressed(MouseEvent e) { super.mousePressed(e); Point p = new Point(e.getX(), e.getY()); int col = table.columnAtPoint(p); if (col == 0) { startDragPoint = (int) e.getPoint().getY(); } } public void mouseDragged(MouseEvent e) { int fromRow = table.getSelectedRow(); Point p = new Point(e.getX(), e.getY()); int col = table.columnAtPoint(p); if (fromRow >= 0 && col == 0) { draggingRow = true; int rowHeight = table.getRowHeight(); int middleOfSelectedRow = (rowHeight * fromRow) + (rowHeight / 2); int toRow = -1; int yMousePoint = (int) e.getPoint().getY(); if (yMousePoint < (middleOfSelectedRow - rowHeight)) { // Move row up toRow = fromRow - 1; } else if (yMousePoint > (middleOfSelectedRow + rowHeight)) { // Move row down toRow = fromRow + 1; } if (toRow >= 0 && toRow < table.getRowCount()) { TableModel model = table.getModel(); for (int i = 0; i < model.getColumnCount(); i++) { Object fromValue = model.getValueAt(fromRow, i); Object toValue = model.getValueAt(toRow, i); model.setValueAt(toValue, fromRow, i); model.setValueAt(fromValue, toRow, i); } table.setRowSelectionInterval(toRow, toRow); startDragPoint = yMousePoint; } dyOffset = (startDragPoint - yMousePoint) * -1; table.repaint(); } } public void mouseReleased(MouseEvent e) { super.mouseReleased(e); draggingRow = false; table.repaint(); } } } }