View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.log4j.chainsaw;
    19
    20  import java.awt.event.InputEvent;
    21  import java.awt.event.MouseEvent;
    22  import java.awt.event.MouseListener;
    23
    24  import javax.swing.JTable;
    25  import javax.swing.table.JTableHeader;
    26  import javax.swing.table.TableColumnModel;
    27
    28  import org.apache.log4j.chainsaw.helper.SwingHelper;
    29
    30
    31  /**
    32   * A Sortable JTable implementation that allows a user to click on a
    33   * specific Column and have the row information sorted by that column.
    34   *
    35   * @author Claude Duguay
    36   * @author Scott Deboy &lt;sdeboy@apache.org&gt;
    37   *
    38   */
    39  public class JSortTable extends JTable implements MouseListener {
    40    protected int sortedColumnIndex = -1;
    41    protected boolean sortedColumnAscending = true;
    42    private String sortedColumn;
    43    private int lastSelectedColumn = -1;
    44
    45    public JSortTable(SortTableModel model) {
    46      super(model);
    47      initSortHeader();
    48    }
    49
    50    public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
    51      //selection of the msg field causes rendering to flash...skip over it
    52      int colToSelect = columnIndex;
    53      //CHAINSAW columns are 1-based indexes
    54      if (columnIndex + 1 == ChainsawColumns.INDEX_MESSAGE_COL_NAME) {
    55          colToSelect = lastSelectedColumn < columnIndex ? columnIndex + 1 : columnIndex - 1;
    56          super.changeSelection(rowIndex, colToSelect, toggle, extend);
    57      } else {
    58          super.changeSelection(rowIndex, columnIndex, toggle, extend);
    59      }
    60      lastSelectedColumn = colToSelect;
    61    }
    62
    63    protected void initSortHeader() {
    64      JTableHeader header = getTableHeader();
    65      header.setDefaultRenderer(new SortHeaderRenderer());
    66      header.addMouseListener(this);
    67    }
    68
    69    public int getSortedColumnIndex() {
    70      return sortedColumnIndex;
    71    }
    72
    73    public void updateSortedColumn() {
    74    	if (sortedColumn != null) {
    75    		try {
    76  	  		sortedColumnIndex = columnModel.getColumnIndex(sortedColumn);
    77              getTableHeader().resizeAndRepaint();
    78    		} catch (IllegalArgumentException ie) {//nothing...column is not in the model
    79    			setSortedColumnIndex(-1);
    80  	  	}
    81  	  }
    82    }
    83
    84    public void setSortedColumnIndex(int index) {
    85      sortedColumnIndex = index;
    86      if (sortedColumnIndex > -1) {
    87          SortTableModel model = (SortTableModel) getModel();
    88          model.sortColumn(sortedColumnIndex, sortedColumnAscending);
    89      }
    90      getTableHeader().resizeAndRepaint();
    91    }
    92
    93    //Allow synchronous updates if already on the EDT
    94    private void scrollTo(final int row, final int col) {
    95      SwingHelper.invokeOnEDT(new Runnable() {
    96        public void run() {
    97          final int currentRow = getSelectedRow();
    98          if ((row > -1) && (row < getRowCount())) {
    99            try {
    100             //get the requested row off of the bottom and top of the screen by making the 5 rows around the requested row visible
    101             //if new past current row, scroll to display the 20th row past new selected row
    102             scrollRectToVisible(getCellRect(row, col, true));
    103             if (row > currentRow) {
    104                 scrollRectToVisible(getCellRect(row + 5, col, true));
    105             }
    106             if (row < currentRow) {
    107                 scrollRectToVisible(getCellRect(row - 5, col, true));
    108             }
    109             scrollRectToVisible(getCellRect(row, col, true));
    110             setRowSelectionInterval(row, row);
    111           } catch (IllegalArgumentException iae) {
    112             //ignore..out of bounds
    113           }
    114         }
    115       }
    116     });
    117   }
    118
    119   public void scrollToRow(int row) {
    120     scrollTo(row, columnAtPoint(getVisibleRect().getLocation()));
    121   }
    122
    123   public boolean isSortedColumnAscending() {
    124     return sortedColumnAscending;
    125   }
    126
    127   public void mouseClicked(MouseEvent event) {
    128
    129   	if(event.getClickCount()<2 || event.isPopupTrigger()){
    130   		return;
    131   	}else if(event.getClickCount()>1 && ((event.getModifiers() & InputEvent.BUTTON2_MASK)>0)){
    132   		return;
    133   	}
    134
    135     TableColumnModel colModel = getColumnModel();
    136     int index = colModel.getColumnIndexAtX(event.getX());
    137     int modelIndex = colModel.getColumn(index).getModelIndex();
    138     SortTableModel model = (SortTableModel) getModel();
    139
    140     if (model.isSortable(modelIndex)) {
    141       // toggle ascension, if already sorted
    142       if (sortedColumnIndex == index) {
    143         sortedColumnAscending = !sortedColumnAscending;
    144       }
    145
    146       sortedColumnIndex = index;
    147       sortedColumn = colModel.getColumn(index).getHeaderValue().toString();
    148       model.sortColumn(modelIndex, sortedColumnAscending);
    149       getTableHeader().resizeAndRepaint();
    150     }
    151   }
    152
    153   public void mousePressed(MouseEvent event) {
    154   }
    155
    156   public void mouseReleased(MouseEvent event) {
    157   }
    158
    159   public void mouseEntered(MouseEvent event) {
    160   }
    161
    162   public void mouseExited(MouseEvent event) {
    163   }
    164 }