📄 basictableui.java
字号:
secondModel.addSelectionInterval(reverse ? secondMax : secondMin, reverse ? secondMax : secondMin); // if we're not wrapping the seconds, we have to find out where we // are within the secondModel and advance to the next cell (or // go back to the previous cell if reverse == true) else { int[] secondsSelected; if (eventIsTab && table.getRowSelectionAllowed() || !eventIsTab && table.getColumnSelectionAllowed()) secondsSelected = eventIsTab ? table.getSelectedRows() : table.getSelectedColumns(); else { // if row selection is not allowed, then the entire column gets // selected when you click on it, so consider ALL rows selected secondsSelected = new int[numSeconds]; for (int i = 0; i < numSeconds; i++) secondsSelected[i] = i; } // and now find the "next" index within the model int secondIndex = reverse ? secondsSelected.length - 1 : 0; if (!reverse) while (secondsSelected[secondIndex] <= secondLead) secondIndex++; else while (secondsSelected[secondIndex] >= secondLead) secondIndex--; // and select it - updating the lead selection index secondModel.addSelectionInterval(secondsSelected[secondIndex], secondsSelected[secondIndex]); } } // We didn't have to wrap the firsts, so just find the "next" first // and select it, we don't have to change "seconds" else { int[] firstsSelected; if (eventIsTab && table.getColumnSelectionAllowed() || !eventIsTab && table.getRowSelectionAllowed()) firstsSelected = eventIsTab ? table.getSelectedColumns() : table.getSelectedRows(); else { // if selection not allowed, consider ALL firsts to be selected firstsSelected = new int[numFirsts]; for (int i = 0; i < numFirsts; i++) firstsSelected[i] = i; } int firstIndex = reverse ? firstsSelected.length - 1 : 0; if (!reverse) while (firstsSelected[firstIndex] <= firstLead) firstIndex++; else while (firstsSelected[firstIndex] >= firstLead) firstIndex--; firstModel.addSelectionInterval(firstsSelected[firstIndex], firstsSelected[firstIndex]); secondModel.addSelectionInterval(secondLead, secondLead); } } /** * A helper method for the key bindings. Used because the actions * for TAB, SHIFT-TAB, ENTER, and SHIFT-ENTER are very similar. * * Selects the next (previous if SHIFT pressed) column (TAB) or row (ENTER) * in the table, changing the current selection. All cells in the table * are eligible, not just the ones that are currently selected. * @param firstModel the ListSelectionModel for columns (TAB) or rows * (ENTER) * @param firstMax the last index in firstModel * @param secondModel the ListSelectionModel for rows (TAB) or columns * (ENTER) * @param secondMax the last index in secondModel * @param reverse true if SHIFT was pressed for the event */ void advanceSingleSelection (ListSelectionModel firstModel, int firstMax, ListSelectionModel secondModel, int secondMax, boolean reverse) { // for TABs, "first" corresponds to columns and "seconds" to rows. // the opposite is true for ENTERs int firstLead = firstModel.getLeadSelectionIndex(); int secondLead = secondModel.getLeadSelectionIndex(); // if we are going backwards subtract 2 because we later add 1 // for a net change of -1 if (reverse && (firstLead == 0)) { // check if we have to wrap around if (secondLead == 0) secondLead += secondMax + 1; secondLead -= 2; } // do we have to wrap the "seconds"? if (reverse && (firstLead == 0) || !reverse && (firstLead == firstMax)) secondModel.setSelectionInterval((secondLead + 1)%(secondMax + 1), (secondLead + 1)%(secondMax + 1)); // if not, just reselect the current lead else secondModel.setSelectionInterval(secondLead, secondLead); // if we are going backwards, subtract 2 because we add 1 later // for net change of -1 if (reverse) { // check for wraparound if (firstLead == 0) firstLead += firstMax + 1; firstLead -= 2; } // select the next "first" firstModel.setSelectionInterval ((firstLead + 1)%(firstMax + 1), (firstLead + 1)%(firstMax + 1)); } } protected void installListeners() { if (focusListener == null) focusListener = createFocusListener(); table.addFocusListener(focusListener); if (keyListener == null) keyListener = createKeyListener(); table.addKeyListener(keyListener); if (mouseInputListener == null) mouseInputListener = createMouseInputListener(); table.addMouseListener(mouseInputListener); table.addMouseMotionListener(mouseInputListener); if (propertyChangeListener == null) propertyChangeListener = new PropertyChangeHandler(); table.addPropertyChangeListener(propertyChangeListener); } protected void uninstallDefaults() { // TODO: this method used to do the following which is not // quite right (at least it breaks apps that run fine with the // JDK): // // table.setFont(null); // table.setGridColor(null); // table.setForeground(null); // table.setBackground(null); // table.setSelectionForeground(null); // table.setSelectionBackground(null); // // This would leave the component in a corrupt state, which is // not acceptable. A possible solution would be to have component // level defaults installed, that get overridden by the UI defaults // and get restored in this method. I am not quite sure about this // though. / Roman Kennke } protected void uninstallKeyboardActions() { // TODO: Implement this properly. } protected void uninstallListeners() { table.removeFocusListener(focusListener); table.removeKeyListener(keyListener); table.removeMouseListener(mouseInputListener); table.removeMouseMotionListener(mouseInputListener); table.removePropertyChangeListener(propertyChangeListener); propertyChangeListener = null; } public void installUI(JComponent comp) { table = (JTable)comp; installDefaults(); installKeyboardActions(); installListeners(); } public void uninstallUI(JComponent c) { uninstallListeners(); uninstallKeyboardActions(); uninstallDefaults(); } /** * Paints a single cell in the table. * * @param g The graphics context to paint in * @param row The row number to paint * @param col The column number to paint * @param bounds The bounds of the cell to paint, assuming a coordinate * system beginning at <code>(0,0)</code> in the upper left corner of the * table * @param rend A cell renderer to paint with * @param data The data to provide to the cell renderer * @param rowLead The lead selection for the rows of the table. * @param colLead The lead selection for the columns of the table. */ void paintCell(Graphics g, int row, int col, Rectangle bounds, TableCellRenderer rend, TableModel data, int rowLead, int colLead) { boolean rowSelAllowed = table.getRowSelectionAllowed(); boolean colSelAllowed = table.getColumnSelectionAllowed(); boolean isSel = false; if (rowSelAllowed && colSelAllowed || !rowSelAllowed && !colSelAllowed) isSel = table.isCellSelected(row, col); else isSel = table.isRowSelected(row) && table.getRowSelectionAllowed() || table.isColumnSelected(col) && table.getColumnSelectionAllowed(); // Determine the focused cell. The focused cell is the cell at the // leadSelectionIndices of the row and column selection model. ListSelectionModel rowSel = table.getSelectionModel(); ListSelectionModel colSel = table.getColumnModel().getSelectionModel(); boolean hasFocus = table.hasFocus() && table.isEnabled() && rowSel.getLeadSelectionIndex() == row && colSel.getLeadSelectionIndex() == col; Component comp = rend.getTableCellRendererComponent(table, data.getValueAt(row, col), isSel, hasFocus, row, col); rendererPane.paintComponent(g, comp, table, bounds); // FIXME: this is manual painting of the Caret, why doesn't the // JTextField take care of this itself? if (comp instanceof JTextField) { Rectangle oldClip = g.getClipBounds(); g.translate(bounds.x, bounds.y); g.clipRect(0, 0, bounds.width, bounds.height); ((JTextField)comp).getCaret().paint(g); g.translate(-bounds.x, -bounds.y); g.setClip(oldClip); } } public void paint(Graphics gfx, JComponent ignored) { int ncols = table.getColumnCount(); int nrows = table.getRowCount(); if (nrows == 0 || ncols == 0) return; Rectangle clip = gfx.getClipBounds(); TableColumnModel cols = table.getColumnModel(); int height = table.getRowHeight(); int x0 = 0, y0 = 0; int x = x0; int y = y0; Dimension gap = table.getIntercellSpacing(); int ymax = clip.y + clip.height; int xmax = clip.x + clip.width; // paint the cell contents for (int c = 0; c < ncols && x < xmax; ++c) { y = y0; TableColumn col = cols.getColumn(c); int width = col.getWidth(); int halfGapWidth = gap.width / 2; int halfGapHeight = gap.height / 2; for (int r = 0; r < nrows && y < ymax; ++r) { Rectangle bounds = new Rectangle(x + halfGapWidth, y + halfGapHeight + 1, width - gap.width + 1, height - gap.height); if (bounds.intersects(clip)) { paintCell(gfx, r, c, bounds, table.getCellRenderer(r, c), table.getModel(), table.getSelectionModel().getLeadSelectionIndex(), table.getColumnModel().getSelectionModel().getLeadSelectionIndex()); } y += height; } x += width; } // tighten up the x and y max bounds ymax = y; xmax = x; Color grid = table.getGridColor(); // paint vertical grid lines if (grid != null && table.getShowVerticalLines()) { x = x0; Color save = gfx.getColor(); gfx.setColor(grid); boolean paintedLine = false; for (int c = 0; c < ncols && x < xmax; ++c) { x += cols.getColumn(c).getWidth(); gfx.drawLine(x, y0, x, ymax); paintedLine = true; } gfx.setColor(save); } // paint horizontal grid lines if (grid != null && table.getShowHorizontalLines()) { y = y0; Color save = gfx.getColor(); gfx.setColor(grid); boolean paintedLine = false; for (int r = 0; r < nrows && y < ymax; ++r) { y += height; gfx.drawLine(x0, y, xmax, y); paintedLine = true; } gfx.setColor(save); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -