// PathVisio, // a tool for data visualization and analysis using Biological Pathways // Copyright 2006-2011 BiGCaT Bioinformatics // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //Source: http://www.chka.de/swing/table/row-headers/ package org.pathvisio.desktop.util; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.event.MouseEvent; import java.io.Serializable; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.event.MouseInputAdapter; public class JTableRowHeaderResizer extends MouseInputAdapter implements Serializable, ContainerListener { private JScrollPane pane; private JViewport viewport; private JTable rowHeader; private Component corner; private JTable view; private boolean enabled; public JTableRowHeaderResizer(JScrollPane pane) { this.pane = pane; this.pane.addContainerListener(this); } public void setEnabled(boolean what) { if (enabled == what) return; enabled = what; if (enabled) addListeners(); else removeListeners(); } protected void addListeners() { if (corner != null) { corner.addMouseListener(this); corner.addMouseMotionListener(this); } } protected void removeListeners() { if (corner != null) { corner.removeMouseListener(this); corner.removeMouseMotionListener(this); } } protected void lookupComponents() { this.view = (JTable)pane.getViewport().getView(); this.viewport = pane.getRowHeader(); if (viewport == null) this.rowHeader = null; else this.rowHeader = (JTable)viewport.getView(); this.corner = pane.getCorner(JScrollPane.UPPER_LEFT_CORNER); } public void componentAdded(ContainerEvent e) { componentRemoved(e); } public void componentRemoved(ContainerEvent e) { if (enabled) removeListeners(); lookupComponents(); if (enabled) addListeners(); } private boolean active; private int startX, startWidth; private int minWidth, maxWidth; private Dimension size; private static final int PIXELS = 10; private static final Cursor RESIZE_CURSOR = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); private Cursor oldCursor; public void mouseExited(MouseEvent e) { if (oldCursor != null) { corner.setCursor(oldCursor); oldCursor = null; } } public void mouseEntered(MouseEvent e) { mouseMoved(e); } public void mouseMoved(MouseEvent e) { if (corner.getWidth() - e.getX() <= PIXELS) { if (oldCursor == null) { oldCursor = corner.getCursor(); corner.setCursor(RESIZE_CURSOR); } } else if (oldCursor != null) { corner.setCursor(oldCursor); oldCursor = null; } } public void mousePressed(MouseEvent e) { startX = e.getX(); startWidth = rowHeader.getWidth(); if (startWidth - startX > PIXELS) return; active = true; if (oldCursor == null) { oldCursor = corner.getCursor(); corner.setCursor(RESIZE_CURSOR); } minWidth = rowHeader.getMinimumSize().width; maxWidth = rowHeader.getMaximumSize().width; } public void mouseReleased(MouseEvent e) { active = false; } public void mouseDragged(MouseEvent e) { if (!active) return; size = viewport.getPreferredSize(); int newX = e.getX(); size.width = startWidth + e.getX() - startX; if (size.width < minWidth) size.width = minWidth; else if (size.width > maxWidth) size.width = maxWidth; // This isn't too clean, it assumes the width bubbles up to // viewport.getPreferredSize().width without changes. rowHeader.getColumnModel().getColumn(0).setPreferredWidth(size.width); view.sizeColumnsToFit(-1); pane.revalidate(); } }