📄 jtable.java
字号:
* when its value changes. * * @see #setSelectionForeground(Color) * @see #getSelectionForeground() */ protected Color selectionForeground; /** * The name carried in property change events when the * {@link #selectionForeground} property changes. */ private static final String SELECTION_FOREGROUND_CHANGED_PROPERTY = "selectionForeground"; /** * The showHorizontalLines property. */ protected boolean showHorizontalLines; /** * The showVerticalLines property. */ protected boolean showVerticalLines; /** * The tableHeader property. */ protected JTableHeader tableHeader; /** * The row of the cell being edited. */ int rowBeingEdited = -1; /** * The column of the cell being edited. */ int columnBeingEdited = -1; /** * The action listener for the editor's Timer. */ Timer editorTimer = new EditorUpdateTimer(); /** * Stores the old value of a cell before it was edited, in case * editing is cancelled */ Object oldCellValue; /** * The property handler for this table's columns. */ TableColumnPropertyChangeHandler tableColumnPropertyChangeHandler = new TableColumnPropertyChangeHandler(); /** * Creates a new <code>JTable</code> instance. */ public JTable () { this(null, null, null); } /** * Creates a new <code>JTable</code> instance. * * @param numRows an <code>int</code> value * @param numColumns an <code>int</code> value */ public JTable (int numRows, int numColumns) { this(new DefaultTableModel(numRows, numColumns)); } /** * Creates a new <code>JTable</code> instance. * * @param data an <code>Object[][]</code> value * @param columnNames an <code>Object[]</code> value */ public JTable(Object[][] data, Object[] columnNames) { this(new DefaultTableModel(data, columnNames)); } /** * Creates a new <code>JTable</code> instance. * * @param dm a <code>TableModel</code> value */ public JTable (TableModel dm) { this(dm, null, null); } /** * Creates a new <code>JTable</code> instance. * * @param dm a <code>TableModel</code> value * @param cm a <code>TableColumnModel</code> value */ public JTable (TableModel dm, TableColumnModel cm) { this(dm, cm, null); } /** * Creates a new <code>JTable</code> instance. * * @param dm a <code>TableModel</code> value * @param cm a <code>TableColumnModel</code> value * @param sm a <code>ListSelectionModel</code> value */ public JTable (TableModel dm, TableColumnModel cm, ListSelectionModel sm) { boolean autoCreate = false; if (cm != null) setColumnModel(cm); else { setColumnModel(createDefaultColumnModel()); autoCreate = true; } setSelectionModel(sm == null ? createDefaultSelectionModel() : sm); setModel(dm == null ? createDefaultDataModel() : dm); setAutoCreateColumnsFromModel(autoCreate); initializeLocalVars(); // The following four lines properly set the lead selection indices. // After this, the UI will handle the lead selection indices. // FIXME: this should probably not be necessary, if the UI is installed // before the TableModel is set then the UI will handle things on its // own, but certain variables need to be set before the UI can be installed // so we must get the correct order for all the method calls in this // constructor. selectionModel.setAnchorSelectionIndex(0); selectionModel.setLeadSelectionIndex(0); columnModel.getSelectionModel().setAnchorSelectionIndex(0); columnModel.getSelectionModel().setLeadSelectionIndex(0); updateUI(); } protected void initializeLocalVars() { setTableHeader(createDefaultTableHeader()); if (autoCreateColumnsFromModel) createDefaultColumnsFromModel(); this.columnModel.addColumnModelListener(this); this.defaultRenderersByColumnClass = new Hashtable(); createDefaultRenderers(); this.defaultEditorsByColumnClass = new Hashtable(); createDefaultEditors(); this.autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS; this.rowHeight = 16; this.rowMargin = 1; this.rowSelectionAllowed = true; // this.accessibleContext = new AccessibleJTable(); this.cellEditor = null; // COMPAT: Both Sun and IBM have drag enabled this.dragEnabled = true; this.preferredViewportSize = new Dimension(450,400); this.showHorizontalLines = true; this.showVerticalLines = true; this.editingColumn = -1; this.editingRow = -1; setIntercellSpacing(new Dimension(1,1)); } /** * Creates a new <code>JTable</code> instance. * * @param data a <code>Vector</code> value * @param columnNames a <code>Vector</code> value */ public JTable(Vector data, Vector columnNames) { this(new DefaultTableModel(data, columnNames)); } /** * The timer that updates the editor component. */ private class EditorUpdateTimer extends Timer implements ActionListener { /** * Creates a new EditorUpdateTimer object with a default delay of 0.5 seconds. */ public EditorUpdateTimer() { super(500, null); addActionListener(this); } /** * Lets the caret blink and repaints the table. */ public void actionPerformed(ActionEvent ev) { Caret c = ((JTextField)JTable.this.editorComp).getCaret(); if (c != null) c.setVisible(!c.isVisible()); JTable.this.repaint(); } /** * Updates the blink delay according to the current caret. */ public void update() { stop(); Caret c = ((JTextField)JTable.this.editorComp).getCaret(); if (c != null) { setDelay(c.getBlinkRate()); if (((JTextField)JTable.this.editorComp).isEditable()) start(); else c.setVisible(false); } } } public void addColumn(TableColumn column) { if (column.getHeaderValue() == null) { String name = dataModel.getColumnName(column.getModelIndex()); column.setHeaderValue(name); } columnModel.addColumn(column); column.addPropertyChangeListener(tableColumnPropertyChangeHandler); } protected void createDefaultEditors() { //FIXME: Create the editor object. } protected void createDefaultRenderers() { setDefaultRenderer(Boolean.class, new BooleanCellRenderer()); setDefaultRenderer(Number.class, new NumberCellRenderer()); setDefaultRenderer(Double.class, new DoubleCellRenderer()); setDefaultRenderer(Double.class, new FloatCellRenderer()); setDefaultRenderer(Date.class, new DateCellRenderer()); setDefaultRenderer(Icon.class, new IconCellRenderer()); } /** * @deprecated 1.0.2, replaced by <code>new JScrollPane(JTable)</code> */ public static JScrollPane createScrollPaneForTable(JTable table) { return new JScrollPane(table); } protected TableColumnModel createDefaultColumnModel() { return new DefaultTableColumnModel(); } protected TableModel createDefaultDataModel() { return new DefaultTableModel(); } protected ListSelectionModel createDefaultSelectionModel() { return new DefaultListSelectionModel(); } protected JTableHeader createDefaultTableHeader() { return new JTableHeader(columnModel); } // listener support public void columnAdded (TableColumnModelEvent event) { revalidate(); repaint(); } public void columnMarginChanged (ChangeEvent event) { revalidate(); repaint(); } public void columnMoved (TableColumnModelEvent event) { revalidate(); repaint(); } public void columnRemoved (TableColumnModelEvent event) { revalidate(); repaint(); } public void columnSelectionChanged (ListSelectionEvent event) { repaint(); } public void editingCanceled (ChangeEvent event) { if (rowBeingEdited > -1 && columnBeingEdited > -1) { if (getValueAt(rowBeingEdited, columnBeingEdited) instanceof JTextField) { remove ((Component)getValueAt(rowBeingEdited, columnBeingEdited)); setValueAt(oldCellValue, rowBeingEdited, columnBeingEdited); } rowBeingEdited = -1; columnBeingEdited = -1; } editorTimer.stop(); editorComp = null; cellEditor = null; requestFocusInWindow(false); repaint(); } public void editingStopped (ChangeEvent event) { if (rowBeingEdited > -1 && columnBeingEdited > -1) { if (getValueAt(rowBeingEdited, columnBeingEdited) instanceof JTextField) { remove((Component)getValueAt(rowBeingEdited, columnBeingEdited)); setValueAt(((JTextField)editorComp).getText(), rowBeingEdited, columnBeingEdited); } rowBeingEdited = -1; columnBeingEdited = -1; } editorTimer.stop(); editorComp = null; cellEditor = null; requestFocusInWindow(false); repaint(); } public void tableChanged (TableModelEvent event) { // update the column model from the table model if the structure has // changed and the flag autoCreateColumnsFromModel is set if ((event.getFirstRow() ==TableModelEvent.HEADER_ROW) && autoCreateColumnsFromModel) createDefaultColumnsFromModel(); // If the structure changes, we need to revalidate, since that might // affect the size parameters of the JTable. Otherwise we only need // to perform a repaint to update the view. if (event.getType() == TableModelEvent.INSERT) revalidate(); else if (event.getType() == TableModelEvent.DELETE) { if (dataModel.getRowCount() == 0) clearSelection(); revalidate(); } repaint(); } public void valueChanged (ListSelectionEvent event) { repaint(); } /** * Returns index of the column that contains specified point * or -1 if this table doesn't contain this point. * * @param point point to identify the column * @return index of the column that contains specified point or * -1 if this table doesn't contain this point. */ public int columnAtPoint(Point point) { if (point != null) { int x0 = getLocation().x; int ncols = getColumnCount(); Dimension gap = getIntercellSpacing(); TableColumnModel cols = getColumnModel(); int x = point.x; for (int i = 0; i < ncols; ++i) { int width = cols.getColumn(i).getWidth() + (gap == null ? 0 : gap.width); if (0 <= x && x < width) return i; x -= width; } } return -1; } /** * Returns index of the row that contains specified point or * -1 if this table doesn't contain this point. * * @param point point to identify the row * @return index of the row that contains specified point or * -1 if this table doesn't contain this point. */ public int rowAtPoint(Point point) { if (point != null) { int y0 = getLocation().y; int nrows = getRowCount(); int height = getRowHeight(); int y = point.y; for (int i = 0; i < nrows; ++i) { if (0 <= y && y < height) return i; y -= height; } } return -1; } /** * Calculate the visible rectangle for a particular row and column. The * row and column are specified in visual terms; the column may not match * the {@link #dataModel} column. * * @param row the visible row to get the cell rectangle of * * @param column the visible column to get the cell rectangle of, which may * differ from the {@link #dataModel} column * * @param includeSpacing whether or not to include the cell margins in the * resulting cell. If <code>false</code>, the result will only contain the * inner area of the target cell, not including its margins. * * @return a rectangle enclosing the specified cell */ public Rectangle getCellRect(int row, int column, boolean includeSpacing) { int height = getRowHeight(row); int width = columnModel.getColumn(column).getWidth(); int x_gap = columnModel.getColumnMargin(); int y_gap = rowMargin; column = Math.max(0, Math.min(column, getColumnCount() - 1)); row = Math.max(0, Math.min(row, getRowCount() - 1)); int x = 0; int y = (height + y_gap) * row; for (int i = 0; i < column; ++i) x += columnModel.getColumn(i).getWidth();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -