6128N/A * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * BasicTableUI implementation 0N/A * @author Philip Milne 0N/A * @author Shannon Hickey (drag and drop) 0N/A// Instance Variables 0N/A // The JTable that is delegating the painting to this UI. 0N/A // Listeners that are attached to the JTable 0N/A * Local cache of Table's client property "Table.isFileList" 0N/A// Helper class for keyboard actions 0N/A "selectNextRowExtendSelection";
0N/A "selectNextRowChangeLead";
0N/A "selectPreviousRowExtendSelection";
0N/A "selectPreviousRowChangeLead";
0N/A "selectNextColumnExtendSelection";
0N/A "selectNextColumnChangeLead";
0N/A "selectPreviousColumnCell";
0N/A "selectPreviousColumnExtendSelection";
0N/A "selectPreviousColumnChangeLead";
0N/A "scrollLeftChangeSelection";
0N/A "scrollLeftExtendSelection";
0N/A "scrollRightChangeSelection";
0N/A "scrollRightExtendSelection";
0N/A "scrollUpChangeSelection";
0N/A "scrollUpExtendSelection";
0N/A "scrollDownChangeSelection";
0N/A "scrollDownExtendSelection";
0N/A "selectFirstColumn";
0N/A "selectFirstColumnExtendSelection";
0N/A "selectLastColumnExtendSelection";
0N/A "selectFirstRowExtendSelection";
0N/A "selectLastRowExtendSelection";
0N/A // add the lead item to the selection without changing lead or anchor 0N/A // toggle the selected state of the lead item and move the anchor to it 0N/A // extend the selection to the lead item 0N/A // move the anchor to the lead and ensure only that item is selected 0N/A // give focus to the JTableHeader, if one exists 0N/A // horizontally, forwards always means right, 0N/A // regardless of component orientation 0N/A // Actions spcifying true for "inSelection" are 0N/A // fairly sensitive to bad parameter values. They require 0N/A // that one of dx and dy be 0 and the other be -1 or 1. 0N/A // Bogus parameter values could cause an infinite loop. 0N/A // To prevent any problems we massage the params here 0N/A // and complain if we get something we can't deal with. 0N/A // look at the sign of dx and dy only 0N/A // make sure one is zero, but not both 0N/A return (
num <
0) ? -
1 : ((
num ==
0) ?
0 :
1);
0N/A * Called to move within the selected range of the given JTable. 0N/A * This method uses the table's notion of selection, which is 0N/A * important to allow the user to navigate between items visually 0N/A * selected on screen. This notion may or may not be the same as 0N/A * what could be determined by directly querying the selection models. 0N/A * It depends on certain table properties (such as whether or not 0N/A * row or column selection is allowed). When performing modifications, 0N/A * it is recommended that caution be taken in order to preserve 0N/A * the intent of this method, especially when deciding whether to 0N/A * query the selection models or interact with JTable directly. 0N/A // Note: The Actions constructor ensures that only one of 0N/A // dx and dy is 0, and the other is either -1 or 1 0N/A // find out how many items the table is showing as selected 0N/A // and the range of items to navigate through 0N/A // both column and row selection 0N/A // row selection only 0N/A // column selection only 0N/A // no selection allowed 0N/A // A bogus assignment to stop javac from complaining 0N/A // about unitialized values. In this case, these 0N/A // won't even be used. 0N/A // For some cases, there is no point in trying to stay within the 0N/A // selected area. Instead, move outside the selection, wrapping at 0N/A // the table boundaries. The cases are: 0N/A // - nothing selected 0N/A // - one item selected, and the lead is already selected 0N/A // the mins are calculated like this in case the max is -1 0N/A // the algorithm below isn't prepared to deal with -1 lead/anchor 0N/A // so massage appropriately here first 0N/A // In cases where the lead is not within the search range, 0N/A // we need to bring it within one cell for the the search 0N/A // to work properly. Check these here. 0N/A // find the next position, possibly looping until it is selected 0N/A * Find the next lead row and column based on the given 0N/A // scroll by at least one cell 0N/A // scroll by at least one cell 0N/A // Unfortunately, this strategy introduces bugs because 0N/A // of the asynchronous nature of requestFocus() call below. 0N/A // Introducing a delay with invokeLater() makes this work 0N/A // in the typical case though race conditions then allow 0N/A // focus to disappear altogether. The right solution appears 0N/A // to be to fix requestFocus() so that it queues a request 0N/A // for the focus regardless of who owns the focus at the 0N/A // time the call to requestFocus() is made. The optimisation 0N/A // to ignore the call to requestFocus() when the component 0N/A // already has focus may ligitimately be made as the 0N/A // request focus event is dequeued, not before. 0N/A // boolean wasEditingWithFocus = table.isEditing() && 0N/A // table.getEditorComponent().isFocusOwner(); 0N/A // casting should be safe since the action is only enabled 0N/A // for DefaultListSelectionModel 0N/A // casting should be safe since the action is only enabled 0N/A // for DefaultListSelectionModel 0N/A // bail - don't try to move selection on an empty table 0N/A // this is the only way we have to set both the lead 0N/A // and the anchor without changing the selection 0N/A if (wasEditingWithFocus) { 0N/A table.editCellAt(leadRow, leadColumn); 0N/A final Component editorComp = table.getEditorComponent(); 0N/A if (editorComp != null) { 0N/A SwingUtilities.invokeLater(new Runnable() { 0N/A editorComp.requestFocus(); 0N/A //Set the header's selected column to match the table. 0N/A //Then give the header the focus. 0N/A // discontinuous selection actions are only enabled for 0N/A // DefaultListSelectionModel 0N/A // discontinuous selection actions are only enabled for 0N/A // DefaultListSelectionModel 0N/A // This action is typically bound to SPACE. 0N/A // If the table is already in an editing mode, SPACE should 0N/A // simply enter a space character into the table, and not 0N/A // select a cell. Likewise, if the lead cell is already selected 0N/A // then hitting SPACE should just enter a space character 0N/A // into the cell and begin editing. In both of these cases 0N/A // this action will be disabled. 0N/A// The Table's Key listener 0N/A * This class should be treated as a "protected" inner class. 3972N/A * Instantiate it only within subclasses of {@code BasicTableUI}. 0N/A * <p>As of Java 2 platform v1.3 this class is no longer used. 0N/A * Instead <code>JTable</code> 0N/A * overrides <code>processKeyBinding</code> to dispatch the event to 0N/A * the current <code>TableCellEditor</code>. 0N/A // NOTE: This class exists only for backward compatability. All 0N/A // its functionality has been moved into Handler. If you need to add 0N/A // new functionality add it to the Handler, but make sure this 0N/A // class calls into the Handler. 0N/A// The Table's focus listener 0N/A * This class should be treated as a "protected" inner class. 3972N/A * Instantiate it only within subclasses of {@code BasicTableUI}. 0N/A // NOTE: This class exists only for backward compatability. All 0N/A // its functionality has been moved into Handler. If you need to add 0N/A // new functionality add it to the Handler, but make sure this 0N/A // class calls into the Handler. 0N/A// The Table's mouse and mouse motion listeners 0N/A * This class should be treated as a "protected" inner class. 0N/A * Instantiate it only within subclasses of BasicTableUI. 0N/A // NOTE: This class exists only for backward compatability. All 0N/A // its functionality has been moved into Handler. If you need to add 0N/A // new functionality add it to the Handler, but make sure this 0N/A // class calls into the Handler. 0N/A // We register all actions using ANCESTOR_OF_FOCUSED_COMPONENT 0N/A // which means that we might perform the appropriate action 0N/A // in the table and then forward it to the editor if the editor 0N/A // had focus. Make sure this doesn't happen by checking our 0N/A // The AWT seems to generate an unconsumed \r event when 0N/A // ENTER (\n) is pressed. 0N/A // Forwarding events this way seems to put the component 0N/A // in a state where it believes it has focus. In reality 0N/A // the table retains focus - though it is difficult for 0N/A // a user to tell, since the caret is visible and flashing. 0N/A // Calling table.requestFocus() here, to get the focus back to 0N/A // the table, seems to have no effect. 0N/A // MouseInputListener 0N/A // Component receiving mouse events during editing. 0N/A // May not be editorComponent. 0N/A // Check for isEditing() in case another event has 0N/A // caused the editor to be removed. See bug #4306499. 0N/A // The row and column where the press occurred and the 0N/A // press event itself 0N/A // Whether or not the mouse press (which is being considered as part 0N/A // of a drag sequence) also caused the selection change to be fully 0N/A // Set to true when a drag gesture has been fully recognized and DnD 0N/A // begins. Use this to ignore further mouse events which could be 0N/A // delivered if DnD is cancelled (via ESCAPE for example) 0N/A // Whether or not we should start the editing timer on release 0N/A // To cache the return value of pointOutsidePrefSize since we use 0N/A // it multiple times. 0N/A // Used to delay the start of editing. 0N/A // if this is a single selection table 0N/A // do nothing for control - will be handled on release 0N/A // or when drag starts 0N/A // clicking on something that's already selected 0N/A // and need to make it the lead now 0N/A // could be a drag initiating event - don't grab focus 0N/A // When drag can't happen, mouse drags might change the selection in the table 0N/A // so we want the isAdjusting flag to be set 0N/A // If shift is down in multi-select, we should just return. 0N/A // For single select or non-shift-click, clear the selection 0N/A // The autoscroller can generate drag events outside the 0N/A // This may appear completely odd, but must be done for backward 0N/A // compatibility reasons. Developers have been known to rely on 0N/A // a call to shouldSelectCell after editing has begun. 0N/A // Check isFileList: 0N/A // Until we support drag-selection, dragging should not change 0N/A // the selection (act like single-select). 0N/A // The autoscroller can generate drag events outside the 0N/A // PropertyChangeListener 0N/A * Returns true if the given point is outside the preferredSize of the 0N/A * item at the given row of the table. (Column must be 0). 0N/A * Returns false if the "Table.isFileList" client property is not set. 0N/A// Factory methods for the Listeners 0N/A * Creates the key listener for handling keyboard navigation in the JTable. 0N/A * Creates the focus listener for handling keyboard navigation in the JTable. 0N/A * Creates the mouse listener for the JTable. 0N/A * Initialize JTable properties, e.g. font, foreground, and background. 0N/A * The font, foreground, and background properties are only set if their 0N/A * current value is either null or a UIResource, other properties are set 0N/A * if the current value is null. 0N/A "Table.foreground",
"Table.font");
0N/A // JTable's original row height is 16. To correctly display the 0N/A // contents on Linux we should have set it to 18, Windows 19 and 0N/A // Solaris 20. As these values vary so much it's too hard to 0N/A // be backward compatable and try to update the row height, we're 0N/A // therefor NOT going to adjust the row height based on font. If the 0N/A // developer changes the font, it's there responsability to update 0N/A // install the scrollpane border 0N/A // default TransferHandler doesn't support drop 0N/A // so we don't want drop handling 0N/A * Attaches listeners to the JTable. 0N/A * Register all keyboard actions on the JTable. 0N/A "Table.ancestorInputMap");
0N/A "Table.ancestorInputMap.RightToLeft")) ==
null)) {
0N/A // IMPORTANT: There is a very close coupling between the parameters 0N/A // passed to the Actions constructor. Only certain parameter 0N/A // combinations are supported. For example, the following Action would 0N/A // not work as expected: 0N/A // new Actions(Actions.NEXT_ROW_CELL, 1, 4, false, true) 0N/A // Actions which move within the selection only (having a true 0N/A // inSelection parameter) require that one of dx or dy be 0N/A // zero and the other be -1 or 1. The point of this warning is 0N/A // that you should be very careful about making sure a particular 0N/A // combination of parameters is supported before changing or 0N/A // adding anything here. 0N/A 1,
0,
true,
false));
0N/A -
1,
0,
true,
false));
0N/A 0,
1,
true,
false));
0N/A 0, -
1,
true,
false));
0N/A false,
false,
true,
false));
0N/A false,
true,
true,
false));
0N/A false,
false,
false,
true));
0N/A false,
true,
false,
true));
0N/A true,
false,
true,
false));
0N/A true,
true,
true,
false));
0N/A true,
false,
false,
true));
0N/A true,
true,
false,
true));
0N/A true,
false,
true,
true));
0N/A true,
true,
true,
true));
0N/A 1,
0,
false,
true));
0N/A -
1,
0,
false,
true));
0N/A 0, -
1,
false,
true));
0N/A false,
false,
false,
false));
0N/A false,
true,
false,
false));
0N/A true,
false,
false,
false));
0N/A true,
true,
false,
false));
0N/A * Returns the baseline. 0N/A * @throws NullPointerException {@inheritDoc} 0N/A * @throws IllegalArgumentException {@inheritDoc} 0N/A * @see javax.swing.JComponent#getBaseline(int, int) 0N/A * Returns an enum indicating how the baseline of the component 0N/A * changes as the size changes. 0N/A * @throws NullPointerException {@inheritDoc} 0N/A * @see javax.swing.JComponent#getBaseline(int, int) 0N/A // Width is always positive. The call to abs() is a workaround for 0N/A // a bug in the 1.1.6 JIT on Windows. 0N/A * Return the minimum size of the table. The minimum height is the 0N/A * row height times the number of rows. 0N/A * The minimum width is the sum of the minimum widths of each column. 0N/A * Return the preferred size of the table. The preferred height is the 0N/A * row height times the number of rows. 0N/A * The preferred width is the sum of the preferred widths of each column. 0N/A * Return the maximum size of the table. The maximum height is the 0N/A * row heighttimes the number of rows. 0N/A * The maximum width is the sum of the maximum widths of each column. 0N/A// Paint methods and support 0N/A /** Paint a representation of the <code>table</code> instance 0N/A * that was set in installUI(). 0N/A // account for the fact that the graphics has already been translated 0N/A // into the table's bounds 0N/A // this check prevents us from painting the entire table 0N/A // when the clip doesn't intersect our bounds at all 0N/A // This should never happen (as long as our bounds intersect the clip, 0N/A // which is why we bail above if that is the case). 0N/A // If the table does not have enough rows to fill the view we'll get -1. 0N/A // (We could also get -1 if our bounds don't intersect the clip, 0N/A // which is why we bail above if that is the case). 0N/A // Replace this with the index of the last row. 0N/A // This should never happen. 0N/A // If the table does not have enough columns to fill the view we'll get -1. 0N/A // Replace this with the index of the last column. 0N/A * Paints the grid lines within <I>aRect</I>, using the grid 0N/A * color set with <I>setGridColor</I>. Paints vertical lines 0N/A * if <code>getShowVerticalLines()</code> returns true and paints 0N/A * horizontal lines if <code>getShowHorizontalLines()</code> 0N/A // Paint the dragged column if we are dragging. 0N/A // Remove any renderers that may be left in the rendererPane. 0N/A // Paint a gray well in place of the moving column. 0N/A // Move to the where the cell has been dragged. 0N/A // Fill the background. 0N/A // Paint the vertical grid lines if necessary. 0N/A // Render the cell value 0N/A // Paint the (lower) horizontal grid line if necessary. 0N/A * Create a Transferable to use as the source for a data transfer. 0N/A * @param c The component holding the data to be transfered. This 0N/A * argument is provided to enable sharing of TransferHandlers by 0N/A * multiple components. 0N/A * @return The representation of the data to be transfered. 0N/A // we want a newline at the end of each line and not a tab 0N/A // remove the last newline 0N/A}
// End of Class BasicTableUI