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