/***************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. ****************************************************************/ package org.apache.cayenne.modeler.util; import org.apache.cayenne.modeler.pref.TableColumnPreferences; import javax.swing.JTable; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import java.awt.Component; import java.awt.Cursor; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class TableHeaderListener extends MouseAdapter { private static final int EPSILON = 5; private static final Cursor EAST = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); private static final Cursor WEST = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR); private JTableHeader header; private SortButtonRenderer renderer; private JTable table; private TableColumnPreferences tableColumnPreferences; public TableHeaderListener(JTableHeader header, SortButtonRenderer renderer) { this.header = header; this.renderer = renderer; table = header.getTable(); } @Override public void mouseClicked(MouseEvent e) { if(e.getClickCount() > 1 && isResizeCursor()) { resize(getLeftColumn(e.getPoint())); } else if (!isResizeCursor()) { int col = header.columnAtPoint(e.getPoint()); int sortCol = table.convertColumnIndexToModel(col); if (renderer.isSortingEnabled() && ((CayenneTableModel) table.getModel()).isColumnSortable(sortCol)) { boolean isAscent = SortButtonRenderer.DOWN != renderer.getState(col); sortByDefinedColumn(col, sortCol, isAscent); tableColumnPreferences.setSortOrder(isAscent); tableColumnPreferences.setSortColumn(sortCol); } } } public void mouseReleased(MouseEvent e) { header.repaint(); } public void sortByDefinedColumn(int col, int sortCol, boolean order) { CayenneTableModel model = (CayenneTableModel) table.getModel(); if (renderer.isSortingEnabled() && model.isColumnSortable(sortCol)) { renderer.setSelectedColumn(col, order); header.repaint(); if (table.isEditing()) { table.getCellEditor().stopCellEditing(); } model.sortByColumn(sortCol, order); } } public void setPreferences(TableColumnPreferences tableColumnPreferences) { if (this.tableColumnPreferences == null) { this.tableColumnPreferences = tableColumnPreferences; } } private boolean isResizeCursor() { Cursor cursor = table.getTableHeader().getCursor(); return cursor.equals(EAST) || cursor.equals(WEST); } private int getLeftColumn(Point pt) { pt.x -= EPSILON; return table.getTableHeader().columnAtPoint(pt); } private void resize(int col) { TableColumnModel tcm = table.getColumnModel(); TableColumn tc = tcm.getColumn(col); TableCellRenderer tcr = tc.getHeaderRenderer(); if (tcr == null) tcr = table.getTableHeader().getDefaultRenderer(); Object obj = tc.getHeaderValue(); Component comp = tcr.getTableCellRendererComponent(table, obj, false, false, 0, 0); int maxWidth = comp.getPreferredSize().width; for(int i=0, ub = table.getRowCount(); i!=ub; ++i) { tcr = table.getCellRenderer(i, col); obj = table.getValueAt(i, col); comp = tcr.getTableCellRendererComponent(table, obj, false, false, i, col); int w = comp.getPreferredSize().width; if (w > maxWidth) maxWidth = w; } maxWidth += 10; tc.setPreferredWidth(maxWidth); tc.setWidth(maxWidth); } }