/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.bearsoft.gui.grid.header.cell; import com.bearsoft.gui.grid.header.GridColumnsNode; import com.bearsoft.gui.grid.header.MultiLevelHeader; import java.awt.Component; import java.awt.Dimension; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; /** * * @author Gala */ public class CellMover extends MouseAdapter { protected HeaderCell cell; protected Point pressedPt; protected int targetIndex = -1; protected int selfIndex = -1; public CellMover(HeaderCell aCell) { super(); cell = aCell; } @Override public void mousePressed(MouseEvent e) { Dimension d = cell.getSize(); Point pt = e.getPoint(); if (pt.x >= MultiLevelHeader.PICK_MARGIN_SIZE && pt.x < d.width - MultiLevelHeader.PICK_MARGIN_SIZE - 1) { pressedPt = pt; cell.getHeader().setMovingColGroup(cell.getColGroup()); } else { pressedPt = null; } } @Override public void mouseDragged(MouseEvent e) { if (cell.getColGroup() == cell.getHeader().getMovingColGroup()) { Point nullPt = cell.getLocation(); Point cellPt = e.getPoint(); Component comp = cell.getHeader().getComponentAt(cellPt.x + nullPt.x, cellPt.y + nullPt.y); if (comp instanceof HeaderCell) { HeaderCell targetCell = (HeaderCell) comp; if (targetCell != cell && targetCell.getColGroup().getParent() == cell.getColGroup().getParent()) { selfIndex = getIndexInParent(cell.getColGroup()); targetIndex = getIndexInParent(targetCell.getColGroup()); Point targetCellNullPt = targetCell.getLocation(); Point targetCellPt = new Point(cellPt.x + nullPt.x - targetCellNullPt.x, cellPt.y + nullPt.y - targetCellNullPt.y); targetCell.setLeftRolledover(false); targetCell.setRightRolledover(false); boolean leftHighlight; if (targetCellPt.x > targetCell.getSize().width / 2) { targetIndex++; leftHighlight = false; } else { leftHighlight = true; } // ajust target index and highlighting side to avoid losting of bad drops if (!leftHighlight && targetIndex == selfIndex) { targetIndex--; leftHighlight = true; } else if (leftHighlight && (targetIndex - selfIndex) == 1) { targetIndex++; leftHighlight = false; } // end of ajusting block if (targetCell.getColGroup().isMovable()) { if (targetIndex < selfIndex || (targetIndex - selfIndex) > 1) { if (leftHighlight) { targetCell.setLeftRolledover(true); } else { targetCell.setRightRolledover(true); } } } } } } } @Override public void mouseReleased(MouseEvent e) { MultiLevelHeader header = cell.getHeader(); if (selfIndex != -1 && targetIndex != -1) { GridColumnsNode targetColGroup = neightbourColGroup(targetIndex); if (targetColGroup == null || targetColGroup.isMovable()) { TableColumnModel columnModel = header.getColumnModel(); GridColumnsNode movingColGroup = getNeightbourByIndex(selfIndex); List<GridColumnsNode> leaves = new ArrayList<>(); MultiLevelHeader.achieveLeaves(movingColGroup, leaves); TableColumn movingTableColumn = leaves.get(0).getTableColumn(); int movingTableColumnIndex = getTableColumnIndex(columnModel, movingTableColumn); List<TableColumn> movingColumns = new ArrayList<>(); for (int i = 0; i < leaves.size(); i++) { movingColumns.add(leaves.get(i).getTableColumn()); } int targetTableColumnIndex = calcTargetColumnIndex(columnModel); // Actual work. It will produce events, but we have to disable them //header.getColumnModelListener().setEventsEnabled(false); //try { for (int i = 0; i < movingColumns.size(); i++) { if (movingTableColumnIndex > targetTableColumnIndex) { columnModel.moveColumn(movingTableColumnIndex + i, targetTableColumnIndex + i); } else if (movingTableColumnIndex < targetTableColumnIndex) { columnModel.moveColumn(movingTableColumnIndex, targetTableColumnIndex - 1); } } // } finally { // header.getColumnModelListener().setEventsEnabled(true); // } if (selfIndex < targetIndex) { moveColGroup(selfIndex, targetIndex - 1); } else { moveColGroup(selfIndex, targetIndex); } cell.getHeader().regenerate(); cell.getHeader().checkStructure(); } } // clear all status information occured while dragging header.setMovingColGroup(null); pressedPt = null; targetIndex = -1; selfIndex = -1; cell.getHeader().validate(); MultiLevelHeader.simulateMouseEntered(cell, e); } private int calcTargetColumnIndex(TableColumnModel columnModel) { List<GridColumnsNode> leaves = new ArrayList<>(); GridColumnsNode targetColGroup = getNeightbourByIndex(targetIndex); if (targetColGroup == null) { targetColGroup = getNeightbourByIndex(targetIndex - 1); assert targetColGroup != null; MultiLevelHeader.achieveLeaves(targetColGroup, leaves); TableColumn targetTableColumn = leaves.get(leaves.size() - 1).getTableColumn(); int targetTableColumnIndex = getTableColumnIndex(columnModel, targetTableColumn); return targetTableColumnIndex + 1; } else { MultiLevelHeader.achieveLeaves(targetColGroup, leaves); TableColumn targetTableColumn = leaves.get(0).getTableColumn(); int targetTableColumnIndex = getTableColumnIndex(columnModel, targetTableColumn); return targetTableColumnIndex; } } private int getIndexInParent(GridColumnsNode aColGroup) { if (aColGroup.getParent() == null) { return cell.getHeader().getRoots().indexOf(aColGroup); } else { return aColGroup.getParent().getChildren().indexOf(aColGroup); } } private GridColumnsNode getNeightbourByIndex(int aIndex) { GridColumnsNode parent = cell.getColGroup().getParent(); if (parent != null) { if (aIndex >= 0 && aIndex < parent.getChildren().size()) { return parent.getChildren().get(aIndex); } else { return null; } } else { if (aIndex >= 0 && aIndex < cell.getHeader().getRoots().size()) { return cell.getHeader().getRoots().get(aIndex); } else { return null; } } } private int getTableColumnIndex(TableColumnModel aColumnModel, TableColumn aTableColumn) { for (int i = 0; i < aColumnModel.getColumnCount(); i++) { if (aColumnModel.getColumn(i) == aTableColumn) { return i; } } return -1; } private GridColumnsNode neightbourColGroup(int targetIndex) { List<GridColumnsNode> neightbours = null; if (cell.getColGroup().getParent() != null) { neightbours = cell.getColGroup().getParent().getChildren(); } else { neightbours = cell.getHeader().getRoots(); } return targetIndex >= 0 && targetIndex < neightbours.size() ? neightbours.get(targetIndex) : null; } private void moveColGroup(int aSelfIndex, int aTargetIndex) { List<GridColumnsNode> neightbours = null; if (cell.getColGroup().getParent() != null) { neightbours = cell.getColGroup().getParent().getChildren(); } else { neightbours = cell.getHeader().getRoots(); } GridColumnsNode moving = neightbours.remove(aSelfIndex); neightbours.add(aTargetIndex, moving); } }