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 package org.apache.log4j.lf5.viewer; 18 19 import java.awt.Adjustable; 20 21 import javax.swing.JComponent; 22 import javax.swing.JScrollPane; 23 import javax.swing.JTable; 24 import javax.swing.ListSelectionModel; 25 import javax.swing.SwingUtilities; 26 import javax.swing.table.TableModel; 27 28 /** 29 * Provides methods to accomplish common yet non-trivial tasks 30 * with Swing. Obvious implementations of these methods have been 31 * tried and failed. 32 * 33 * @author Richard Wan 34 */ 35 36 // Contributed by ThoughtWorks Inc. 37 38 public class LF5SwingUtils { 39 //-------------------------------------------------------------------------- 40 // Constants: 41 //-------------------------------------------------------------------------- 42 43 //-------------------------------------------------------------------------- 44 // Protected Variables: 45 //-------------------------------------------------------------------------- 46 47 //-------------------------------------------------------------------------- 48 // Private Variables: 49 //-------------------------------------------------------------------------- 50 51 //-------------------------------------------------------------------------- 52 // Constructors: 53 //-------------------------------------------------------------------------- 54 55 //-------------------------------------------------------------------------- 56 // Public Methods: 57 //-------------------------------------------------------------------------- 58 59 /** 60 * Selects a the specified row in the specified JTable and scrolls 61 * the specified JScrollpane to the newly selected row. More importantly, 62 * the call to repaint() delayed long enough to have the table 63 * properly paint the newly selected row which may be offscre 64 * @param table should belong to the specified JScrollPane 65 */ 66 public static void selectRow(int row, JTable table, JScrollPane pane) { 67 if (table == null || pane == null) { 68 return; 69 } 70 if (contains(row, table.getModel()) == false) { 71 return; 72 } 73 moveAdjustable(row * table.getRowHeight(), pane.getVerticalScrollBar()); 74 selectRow(row, table.getSelectionModel()); 75 // repaint must be done later because moveAdjustable 76 // posts requests to the swing thread which must execute before 77 // the repaint logic gets executed. 78 repaintLater(table); 79 } 80 81 /** 82 * Makes the specified Adjustable track if the view area expands and 83 * the specified Adjustable is located near the of the view. 84 */ 85 public static void makeScrollBarTrack(Adjustable scrollBar) { 86 if (scrollBar == null) { 87 return; 88 } 89 scrollBar.addAdjustmentListener(new TrackingAdjustmentListener()); 90 } 91 92 /** 93 * Makes the vertical scroll bar of the specified JScrollPane 94 * track if the view expands (e.g. if rows are added to an underlying 95 * table). 96 */ 97 public static void makeVerticalScrollBarTrack(JScrollPane pane) { 98 if (pane == null) { 99 return; 100 } 101 makeScrollBarTrack(pane.getVerticalScrollBar()); 102 } 103 104 //-------------------------------------------------------------------------- 105 // Protected Methods: 106 //-------------------------------------------------------------------------- 107 protected static boolean contains(int row, TableModel model) { 108 if (model == null) { 109 return false; 110 } 111 if (row < 0) { 112 return false; 113 } 114 if (row >= model.getRowCount()) { 115 return false; 116 } 117 return true; 118 } 119 120 protected static void selectRow(int row, ListSelectionModel model) { 121 if (model == null) { 122 return; 123 } 124 model.setSelectionInterval(row, row); 125 } 126 127 protected static void moveAdjustable(int location, Adjustable scrollBar) { 128 if (scrollBar == null) { 129 return; 130 } 131 scrollBar.setValue(location); 132 } 133 134 /** 135 * Work around for JTable/viewport bug. 136 * @link http://developer.java.sun.com/developer/bugParade/bugs/4205145.html 137 */ 138 protected static void repaintLater(final JComponent component) { 139 SwingUtilities.invokeLater(new Runnable() { 140 public void run() { 141 component.repaint(); 142 } 143 }); 144 } 145 //-------------------------------------------------------------------------- 146 // Private Methods: 147 //-------------------------------------------------------------------------- 148 149 //-------------------------------------------------------------------------- 150 // Nested Top-Level Classes or Interfaces 151 //-------------------------------------------------------------------------- 152 } 153