KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > jclasslib > browser > BrowserHistory


1 /*
2     This library is free software; you can redistribute it and/or
3     modify it under the terms of the GNU General Public
4     License as published by the Free Software Foundation; either
5     version 2 of the license, or (at your option) any later version.
6 */

7
8 package org.gjt.jclasslib.browser;
9
10 import org.gjt.jclasslib.browser.detail.attributes.CodeAttributeDetailPane;
11
12 import javax.swing.*;
13 import javax.swing.tree.TreePath JavaDoc;
14 import java.util.LinkedList JavaDoc;
15 import java.util.ListIterator JavaDoc;
16
17
18 /**
19     Manages the navigation history of a single child window.
20  
21     @author <a HREF="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>
22     @version $Revision: 1.5 $ $Date: 2003/08/18 08:06:46 $
23 */

24 public class BrowserHistory {
25
26     private static int MAX_HISTORY_ENTRIES = 50;
27     
28     private BrowserServices services;
29
30     private LinkedList JavaDoc history = new LinkedList JavaDoc();
31     private int historyPointer = -1;
32
33     /**
34         Constructor.
35         @param services the associated browser services.
36      */

37     public BrowserHistory(BrowserServices services) {
38         this.services = services;
39     }
40
41     /**
42         Clear the navigation history.
43      */

44     public void clear() {
45         history.clear();
46         historyPointer = -1;
47     }
48     
49     /**
50         Move one step backward in the navigation history.
51      */

52     public void historyBackward() {
53         if (historyPointer == 0) {
54             return;
55         }
56         historyPointer--;
57         syncWithHistory();
58     }
59
60     /**
61         Move one step forward in the navigation history.
62      */

63     public void historyForward() {
64         if (historyPointer == history.size() - 1) {
65             return;
66         }
67         historyPointer++;
68         syncWithHistory();
69     }
70     
71     /**
72         Update the availability of the actions associated with the
73         navigation history.
74      */

75     public void updateActions() {
76
77         if (services.getActionBackward() == null || services.getActionForward() == null) {
78             return;
79         }
80         services.getActionBackward().setEnabled(historyPointer > 0);
81         services.getActionForward().setEnabled(historyPointer < history.size() - 1);
82     }
83
84     /**
85         Add a navigation step to the history.
86         @param newPath the selected tree path in <tt>BrowserTreePane</tt>
87      */

88     public void updateHistory(TreePath JavaDoc newPath) {
89         updateHistory(newPath, null);
90     }
91     
92     /**
93         Add a navigation step to the history.
94         @param newPath the selected tree path in <tt>BrowserTreePane</tt>
95         @param offset the target's offset in the code. <tt>Null</tt> if
96                       not applicable.
97      */

98     public void updateHistory(TreePath JavaDoc newPath, Integer JavaDoc offset) {
99         
100
101         BrowserHistoryEntry newEntry = new BrowserHistoryEntry(newPath, offset);
102         
103         if (!checkForOffset(newEntry) &&
104                 (historyPointer < 0 || !newEntry.equals(history.get(historyPointer)))) {
105                         
106             eliminateForwardEntries();
107             
108             if (historyPointer > MAX_HISTORY_ENTRIES) {
109                 history.removeFirst();
110                 historyPointer--;
111             }
112             
113             history.add(newEntry);
114             historyPointer++;
115             
116         }
117         updateActions();
118     }
119     
120     private boolean checkForOffset(BrowserHistoryEntry newEntry) {
121
122         if (historyPointer >= 0) {
123
124             BrowserHistoryEntry currentEntry = (BrowserHistoryEntry)history.get(historyPointer);
125             if (currentEntry.getTreePath().equals(newEntry.getTreePath())) {
126                 if (newEntry.getOffset() == null) {
127                     // Ignore history event, since it is more unspecific than the current one
128
return true;
129
130                 } else if (currentEntry.getOffset() == null) {
131                     // merge with current entry to achieve more specific history entry
132
eliminateForwardEntries();
133                     currentEntry.setOffset(newEntry.getOffset());
134                     // Do not add another history event
135
return true;
136                 }
137             }
138         }
139         return false;
140     }
141     
142     private void eliminateForwardEntries() {
143         
144         if (historyPointer < history.size() - 1) {
145             ListIterator JavaDoc it = history.listIterator(historyPointer + 1);
146             while (it.hasNext()) {
147                 it.next();
148                 it.remove();
149             }
150         }
151     }
152     
153     private void syncWithHistory() {
154         
155         BrowserHistoryEntry entry = (BrowserHistoryEntry)history.get(historyPointer);
156
157         JTree tree = services.getBrowserComponent().getTreePane().getTree();
158         
159         tree.setSelectionPath(entry.getTreePath());
160         tree.scrollPathToVisible(entry.getTreePath());
161         
162         Integer JavaDoc offset = entry.getOffset();
163         
164         if (offset != null) {
165             BrowserDetailPane detailPane = services.getBrowserComponent().getDetailPane();
166             
167             CodeAttributeDetailPane codeAttributeDetailPane =
168                 detailPane.getAttributeDetailPane().getCodeAttributeDetailPane();
169             
170             codeAttributeDetailPane.selectByteCodeDetailPane();
171
172             codeAttributeDetailPane.getCodeAttributeByteCodeDetailPane().
173                 scrollToOffset(offset.intValue());
174         }
175         
176         updateActions();
177     }
178     
179     private class BrowserHistoryEntry {
180         
181         private TreePath JavaDoc treePath;
182         private Integer JavaDoc offset;
183         
184         private BrowserHistoryEntry(TreePath JavaDoc treePath, Integer JavaDoc offset) {
185             this.treePath = treePath;
186             this.offset = offset;
187         }
188         
189         public TreePath JavaDoc getTreePath() {
190             return treePath;
191         }
192         
193         public Integer JavaDoc getOffset() {
194             return offset;
195         }
196
197         public void setOffset(Integer JavaDoc offset) {
198             this.offset = offset;
199         }
200         
201         public boolean equals(Object JavaDoc object) {
202             
203             if (object == null && !(object instanceof BrowserHistoryEntry)) {
204                 return false;
205             }
206             BrowserHistoryEntry other = (BrowserHistoryEntry)object;
207             
208             return isEqual(offset, other.getOffset()) &&
209                    isEqual(treePath, other.getTreePath());
210         }
211
212         public int hashCode() {
213             return treePath.hashCode() ^ offset.hashCode();
214         }
215
216         private boolean isEqual(Object JavaDoc one, Object JavaDoc two) {
217             
218             if (one == null) {
219                 if (two != null) {
220                     return false;
221                 }
222             } else {
223                 if (!one.equals(two)) {
224                     return false;
225                 }
226             }
227             return true;
228         }
229         
230         public String JavaDoc toString() {
231             return treePath.toString() + " / offset " + (offset == null ? "null" : offset.toString());
232         }
233     }
234 }
235
Popular Tags