001: /**
002: * L2FProd.com Common Components 7.3 License.
003: *
004: * Copyright 2005-2007 L2FProd.com
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package com.l2fprod.common.swing;
018:
019: import java.awt.Container;
020: import java.awt.Cursor;
021: import java.awt.Dimension;
022: import java.awt.Point;
023: import java.awt.Rectangle;
024: import java.awt.event.MouseEvent;
025:
026: import javax.swing.JScrollPane;
027: import javax.swing.JTable;
028: import javax.swing.JViewport;
029: import javax.swing.event.MouseInputAdapter;
030: import javax.swing.table.TableColumn;
031:
032: /**
033: * HeaderlessColumnResizer. <br>
034: *
035: * Allows table columns to be resized not only using the header but from any
036: * rows. Based on the BasicTableHeaderUI code.
037: */
038: public class HeaderlessColumnResizer extends MouseInputAdapter {
039:
040: private static Cursor resizeCursor = Cursor
041: .getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
042:
043: private int mouseXOffset;
044: private Cursor otherCursor = resizeCursor;
045:
046: private JTable table;
047:
048: public HeaderlessColumnResizer(JTable table) {
049: this .table = table;
050: table.addMouseListener(this );
051: table.addMouseMotionListener(this );
052: }
053:
054: private boolean canResize(TableColumn column) {
055: return (column != null)
056: && table.getTableHeader().getResizingAllowed()
057: && column.getResizable();
058: }
059:
060: private TableColumn getResizingColumn(Point p) {
061: return getResizingColumn(p, table.columnAtPoint(p));
062: }
063:
064: private TableColumn getResizingColumn(Point p, int column) {
065: if (column == -1) {
066: return null;
067: }
068: int row = table.rowAtPoint(p);
069: Rectangle r = table.getCellRect(row, column, true);
070: r.grow(-3, 0);
071: if (r.contains(p)) {
072: return null;
073: }
074: int midPoint = r.x + r.width / 2;
075: int columnIndex;
076: if (table.getTableHeader().getComponentOrientation()
077: .isLeftToRight()) {
078: columnIndex = (p.x < midPoint) ? column - 1 : column;
079: } else {
080: columnIndex = (p.x < midPoint) ? column : column - 1;
081: }
082: if (columnIndex == -1) {
083: return null;
084: }
085: return table.getTableHeader().getColumnModel().getColumn(
086: columnIndex);
087: }
088:
089: public void mousePressed(MouseEvent e) {
090: table.getTableHeader().setDraggedColumn(null);
091: table.getTableHeader().setResizingColumn(null);
092: table.getTableHeader().setDraggedDistance(0);
093:
094: Point p = e.getPoint();
095:
096: // First find which header cell was hit
097: int index = table.columnAtPoint(p);
098:
099: if (index != -1) {
100: // The last 3 pixels + 3 pixels of next column are for resizing
101: TableColumn resizingColumn = getResizingColumn(p, index);
102: if (canResize(resizingColumn)) {
103: table.getTableHeader()
104: .setResizingColumn(resizingColumn);
105: if (table.getTableHeader().getComponentOrientation()
106: .isLeftToRight()) {
107: mouseXOffset = p.x - resizingColumn.getWidth();
108: } else {
109: mouseXOffset = p.x + resizingColumn.getWidth();
110: }
111: }
112: }
113: }
114:
115: private void swapCursor() {
116: Cursor tmp = table.getCursor();
117: table.setCursor(otherCursor);
118: otherCursor = tmp;
119: }
120:
121: public void mouseMoved(MouseEvent e) {
122: if (canResize(getResizingColumn(e.getPoint())) != (table
123: .getCursor() == resizeCursor)) {
124: swapCursor();
125: }
126: }
127:
128: public void mouseDragged(MouseEvent e) {
129: int mouseX = e.getX();
130:
131: TableColumn resizingColumn = table.getTableHeader()
132: .getResizingColumn();
133:
134: boolean headerLeftToRight = table.getTableHeader()
135: .getComponentOrientation().isLeftToRight();
136:
137: if (resizingColumn != null) {
138: int oldWidth = resizingColumn.getWidth();
139: int newWidth;
140: if (headerLeftToRight) {
141: newWidth = mouseX - mouseXOffset;
142: } else {
143: newWidth = mouseXOffset - mouseX;
144: }
145: resizingColumn.setWidth(newWidth);
146:
147: Container container;
148: if ((table.getTableHeader().getParent() == null)
149: || ((container = table.getTableHeader().getParent()
150: .getParent()) == null)
151: || !(container instanceof JScrollPane)) {
152: return;
153: }
154:
155: if (!container.getComponentOrientation().isLeftToRight()
156: && !headerLeftToRight) {
157: if (table != null) {
158: JViewport viewport = ((JScrollPane) container)
159: .getViewport();
160: int viewportWidth = viewport.getWidth();
161: int diff = newWidth - oldWidth;
162: int newHeaderWidth = table.getWidth() + diff;
163:
164: /* Resize a table */
165: Dimension tableSize = table.getSize();
166: tableSize.width += diff;
167: table.setSize(tableSize);
168:
169: /*
170: * If this table is in AUTO_RESIZE_OFF mode and has a horizontal
171: * scrollbar, we need to update a view's position.
172: */
173: if ((newHeaderWidth >= viewportWidth)
174: && (table.getAutoResizeMode() == JTable.AUTO_RESIZE_OFF)) {
175: Point p = viewport.getViewPosition();
176: p.x = Math.max(0, Math.min(newHeaderWidth
177: - viewportWidth, p.x + diff));
178: viewport.setViewPosition(p);
179:
180: /* Update the original X offset value. */
181: mouseXOffset += diff;
182: }
183: }
184: }
185: }
186: }
187:
188: public void mouseReleased(MouseEvent e) {
189: //setDraggedDistance(0, viewIndexForColumn(header.getDraggedColumn()));
190:
191: table.getTableHeader().setResizingColumn(null);
192: table.getTableHeader().setDraggedColumn(null);
193: }
194:
195: public void mouseEntered(MouseEvent e) {
196: }
197:
198: public void mouseExited(MouseEvent e) {
199: }
200:
201: }
|