📄 ktable.java
字号:
if (redrawFixedCols)
drawCells(gc, gc.getClipping(), 0, getFixedColumnCount(),
m_TopRow, m_TopRow + m_RowsVisible);
if (redrawFixedCols || redrawFixedRows) {
drawCells(gc, gc.getClipping() , 0, getFixedColumnCount(),
0, getFixedRowCount());
drawBottomSpace(gc);
}
gc.dispose();
}
protected void drawCells(GC gc, Rectangle clipRect, int fromCol, int toCol, int fromRow, int toRow) {
Rectangle r;
// for the starting col and row, we have to check if they
// are subcells that are part of a span cell.
Point valid = getValidCell(fromCol, fromRow);
fromCol = valid.x;
if (valid.y<fromRow)
fromRow = valid.y;
int moveLeft = 1;
for (int i=Math.min(fromCol+m_ColumnsVisible, toCol);
i>fromCol; i-=moveLeft) {
valid = getValidCell(i, fromRow);
if (valid.y<fromRow)
fromRow = valid.y;
moveLeft = i-valid.x+1;
}
if (m_CellEditor != null) {
if (!isCellVisible(m_CellEditor.m_Col, m_CellEditor.m_Row)) {
Rectangle hide = new Rectangle(-101, -101, 100, 100);
m_CellEditor.setBounds(hide);
} else {
m_CellEditor.setBounds(getCellRect(m_CellEditor.m_Col,
m_CellEditor.m_Row));
}
}
int fromCol_X = getCellRectIgnoreSpan(fromCol, fromRow).x;
for (int row = fromRow; row < toRow; row++) {
// skipping non-visible:
r = getCellRectIgnoreSpan(fromCol, row, fromCol_X);
// if (r.y + r.height < clipRect.y && !haveToPaintRowBefore)
// continue;
if (r.y > clipRect.y + clipRect.height) {
break;
}
// the right cell border is cached to avoid the expensive col loop.
int right_border_x = r.x;
for (int col = fromCol; col < toCol; col++) {
r = getCellRect(col, row, right_border_x);
right_border_x+=getColumnWidth(col);
if (r.x > clipRect.x + clipRect.width)
break;
if (r.y > clipRect.y + clipRect.height)
return;
// check if it is an overlapped cell that must not be drawn:
Point belongsTo = m_Model.belongsToCell(col, row);
if (belongsTo!=null && (belongsTo.x!=col || belongsTo.y!=row))
continue;
// perform real work:
if (canDrawCell(r, clipRect))
drawCell(gc, col, row, r);
}
}
}
/**
* Looks into the model to determine if the given cell is overlapped by
* a cell that spans several columns/rows. In that case the index of the
* cell responsible for the content (in the left upper corner) is returned.
* Otherwise the given cell is returned.
*
* @param colToCheck The column index of the cell to check.
* @param rowToCheck The row index of the cell to check.
* (as seen by the KTable. Map if you use a sorted model!)
* @return returns the cell that overlaps the given cell, or the given
* cell if no cell overlaps it.
* @throws IllegalArgumentException If the model returns cells on <code>
* Model.belongsToCell()</code> that are on the right or below the given cell.
* @see KTableSortedModel#mapToTable(int);
*/
public Point getValidCell(int colToCheck, int rowToCheck) {
checkWidget();
// well, there is no supercell with negative indices, so don't check:
Point found = new Point(colToCheck, rowToCheck);
Point lastFound=null;
while (!found.equals(lastFound)) {
lastFound = found;
found = m_Model.belongsToCell(found.x, found.y);
if (found!=null && (found.x>lastFound.x || found.y>lastFound.y))
throw new IllegalArgumentException("When spanning over several cells, " +
"supercells that determine the content of the large cell must " +
"always be in the left upper corner!");
if (found==null)
return lastFound;
}
return found;
}
/**
* Call when a manual redraw on a cell should be performed.
* In case headers should be updated to reflect a focus change, this is performed.
* @param gc
* @param col
* @param row
*/
protected void drawCell(GC gc, int col, int row) {
drawCell(gc, col, row, getCellRect(col, row));
Rectangle oldClip = gc.getClipping();
gc.setClipping(getClientArea());
if ((getStyle() & SWTX.MARK_FOCUS_HEADERS)==SWTX.MARK_FOCUS_HEADERS) {
if (row>=m_TopRow) {
for (int i=0; i<m_Model.getFixedHeaderColumnCount(); i++)
drawCell(gc, i, row, getCellRect(i, row));
for (int i=0; i<m_Model.getFixedHeaderRowCount(); i++)
drawCell(gc, col, i, getCellRect(col, i));
}
}
gc.setClipping(oldClip);
}
protected void drawCell(GC gc, int col, int row, Rectangle rect) {
if ((row < 0) || (row >= m_Model.getRowCount())) {
return;
}
if (rect.width==0 || rect.height==0)
return;
// set up clipping so that the renderer is only
// allowed to paint in his area:
Rectangle oldClip = gc.getClipping();
Rectangle newClip = new Rectangle(rect.x, rect.y, rect.width+1, rect.height+1);
newClip.intersect(oldClip);
gc.setClipping(newClip);
m_Model.getCellRenderer(col, row).drawCell(
gc,
rect,
col,
row,
m_Model.getContentAt(col, row),
showAsSelected(col, row) || highlightSelectedRowCol(col, row),
isHeaderCell(col, row),
col == m_ClickColumnIndex && row == m_ClickRowIndex,
m_Model);
gc.setClipping(oldClip);
}
/**
* Interface method to update the content of a cell.<p>
* Don't forget to map the row index if a sorted model is used.
* @param col The column index
* @param row The row index.
* @see KTableSortedModel#mapRowIndexToTable(int)
*/
public void updateCell(int col, int row) {
checkWidget();
if ((row < 0) || (row >= m_Model.getRowCount()) ||
(col < 0) || (col >= m_Model.getColumnCount()))
return;
// be sure it is a valid cell if cells span
Point valid = getValidCell(col, row);
// update it:
GC gc = new GC(this);
drawCell(gc, valid.x, valid.y);
gc.dispose();
}
/**
* @param col The column index
* @param row The row index
* @return Returns true if the given cell is a fixed cell,
* that is a header cell. Returns false otherwise.
*/
public boolean isFixedCell(int col, int row) {
return col < getFixedColumnCount()
|| row < getFixedRowCount();
}
/**
* @param col The column index
* @param row The row index
* @return Returns true if the given cell is within the region specified by the model
* using the methods <code>getFixedHeaderColumnCount()</code> and <code>getFixedHeaderRowCount()</code>
*/
public boolean isHeaderCell(int col, int row) {
return col < m_Model.getFixedHeaderColumnCount()
|| row < m_Model.getFixedHeaderRowCount();
}
protected boolean showAsSelected(int col, int row) {
// A cell with an open editor should be drawn without focus
if (m_CellEditor != null) {
if (col == m_CellEditor.m_Col && row == m_CellEditor.m_Row)
return false;
}
return isCellSelected(col, row) && (isFocusControl() || isShowSelectionWithoutFocus());
}
protected void drawRow(GC gc, int row) {
drawCells(gc, getClientArea(), 0, getFixedColumnCount(), row,
row + 1);
drawCells(gc, getClientArea(), m_LeftColumn, m_Model.getColumnCount(),
row, row + 1);
}
protected void drawCol(GC gc, int col) {
if (col<getFixedColumnCount()) {
drawCells(gc, getClientArea(), col, col+1, 0, m_TopRow + m_RowsVisible);
} else {
drawCells(gc, getClientArea(), col, col + 1, 0, getFixedRowCount());
Rectangle oldClip = setContentAreaClipping(gc);
drawCells(gc, gc.getClipping(), col, col + 1, m_TopRow, m_TopRow + m_RowsVisible);
gc.setClipping(oldClip);
}
}
/**
* Sets the default cursor to the given cursor. This instance is saved
* internally and displayed whenever no linecursor or resizecursor is shown.
* <p>
* The difference to setCursor is that this cursor will be preserved over
* action cursor changes.
*
* @param cursor
* The cursor to use, or <code>null</code> if the OS default
* cursor should be used.
* @param size_below_hotspot The number of pixels that are needed to paint the
* cursor below and right of the cursor hotspot (that is the actual location the cursor
* is pointing to).<p>
* NOTE that this is just there to allow better positioning of tooltips.
* Currently SWT does not provide an API to get the size of the cursor. So
* these values are taken to calculate the position of the tooltip. The
* the tooltip is placed pt.x pixels left and pt.y pixels below the mouse location.<br>
* If you don't know the size of the cursor (for example you use a default one), set
* <code>null</code> or <code>new Point(-1, -1)</code>.
*/
public void setDefaultCursor(Cursor cursor, Point size_below_hotspot) {
checkWidget();
if (m_defaultCursor != null)
m_defaultCursor.dispose();
m_defaultCursor = cursor;
m_defaultCursorSize = size_below_hotspot;
setCursor(cursor);
}
public void setDefaultRowResizeCursor(Cursor cursor) {
checkWidget();
if ( m_defaultRowResizeCursor != null ) {
m_defaultRowResizeCursor.dispose();
}
m_defaultRowResizeCursor = cursor;
}
public void setDefaultColumnResizeCursor(Cursor cursor) {
checkWidget();
if ( m_defaultColumnResizeCursor != null ) {
m_defaultColumnResizeCursor.dispose();
}
m_defaultColumnResizeCursor = cursor;
}
//////////////////////////////////////////////////////////////////////////////
// REACTIONS ON USER ACTIONS
//////////////////////////////////////////////////////////////////////////////
private int getHeaderHeight() {
int height = 1;
for (int i=0; i<m_Model.getFixedHeaderRowCount(); i++)
height+=m_Model.getRowHeight(i);
return height;
}
/* gibt die Nummer einer Modellspalte zur�ck */
protected int getColumnForResize(int x, int y) {
if (m_Model == null || y <= 0 || y >= getHeaderHeight() ) {
return -1;
}
if ( x < getFixedWidth() + m_ResizeAreaSize / 2 ) {
for (int i = 0; i < getFixedColumnCount(); i++)
if (Math.abs(x - getColumnRight(i)) < m_ResizeAreaSize / 2) {
if (m_Model.isColumnResizable(i)) {
return i;
}
return -1;
}
}
int left = getColumnLeft(m_LeftColumn);
// -1
for (int i = m_LeftColumn; i < (m_LeftColumn + m_ColumnsVisible + 1) && i<m_Model.getColumnCount(); i++) {
if ( i >= m_Model.getColumnCount() ) {
return -1;
}
int right = left + getColumnWidth(i);
if ( Math.abs(x - right) < m_ResizeAreaSize / 2 ) {
if (m_Model.isColumnResizable(i)) {
return i;
}
return -1;
}
if ( (x >= left + m_ResizeAreaSize / 2) &&
(x <= right - m_ResizeAreaSize / 2) ) {
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -