content: /*****************************************************************
   *   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
   *
   *    https://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);
      }
  
  }
  