View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.gui;
21  
22  import java.beans.PropertyChangeEvent;
23  import java.beans.PropertyChangeListener;
24  
25  import javax.swing.JScrollPane;
26  import javax.swing.JTextArea;
27  import javax.swing.SwingUtilities;
28  import javax.swing.border.EmptyBorder;
29  import javax.swing.text.BadLocationException;
30  
31  import org.xnap.gui.util.GUIHelper;
32  import org.xnap.util.Preferences;
33  
34  /***
35   * This class provides a simple text console that can be used for logging. 
36   */
37  public class ConsolePane extends JScrollPane
38      implements PropertyChangeListener {
39  
40      //--- Constant(s) ---
41  
42      //--- Data field(s) ---
43  
44      private static Preferences prefs = Preferences.getInstance();
45  
46      private JTextArea jta;
47      private boolean crop;
48      private boolean appendPending = false;
49      private StringBuffer pendingText = new StringBuffer();
50  
51      //--- Constructor(s) ---
52  
53      public ConsolePane(boolean crop)
54      {
55  		this.crop = crop;
56  
57  		jta = new JTextArea();
58          jta.setLineWrap(true);
59          jta.setWrapStyleWord(true);
60          jta.setCaretColor(java.awt.Color.red);
61  		jta.setSelectedTextColor(java.awt.Color.red);
62          jta.setEditable(false); 
63  		jta.setBorder(new EmptyBorder(5, 5, 5, 5));
64  
65  		setVerticalScrollBarPolicy
66  			(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
67  		setHorizontalScrollBarPolicy
68  			(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
69  
70  		setViewportView(jta);
71  	
72  		updateProperties();
73  
74  		prefs.addPropertyChangeListener("consoleFont", this);
75  		prefs.addPropertyChangeListener("consoleBackgroundColor", this);
76  		prefs.addPropertyChangeListener("consoleForegroundColor", this);
77      }
78  
79      public ConsolePane()
80      {
81  		this(true);
82      }
83      
84      //--- Method(s) ---
85  
86      /***
87       * Appends <code>text</code> to the console. This method is thread
88       * safe and can be called from any thread.
89       */
90      public void appendLater(final String text)
91      {
92  		synchronized (pendingText) {
93  			pendingText.append(text);
94  			if (appendPending) {
95  				return;
96  			}
97  			appendPending = true;
98  		}
99  
100 		Runnable r = new Runnable()
101 			{
102 				public void run() 
103 				{
104 					String toAppend;
105 					synchronized (pendingText) {
106 						toAppend = pendingText.toString();
107 						pendingText.setLength(0);
108 						appendPending = false;
109 					}
110 					append(toAppend);
111 				}
112 			};
113 		SwingUtilities.invokeLater(r);
114     }
115 
116     /***
117      * Appends <code>text</code> to the console.
118      */
119     public void append(String text) 
120     {
121 		boolean autoScroll = GUIHelper.shouldScroll(getVerticalScrollBar());
122 
123 		jta.append(text);
124 
125 		if (crop) {
126 			//remove some lines at the top and leave maxConsoleLines
127 			int i = jta.getLineCount() - prefs.getMaxConsoleLines();
128 			if (i > 0) {
129 				try {
130 					int endoffset = jta.getLineEndOffset(i);
131 					jta.replaceRange(null, 0, endoffset);
132 
133 					// try to keep displaying the same text
134 					//  		    pos = (pos >= i) ? pos - i : 0;
135 					//  		    System.out.println("new pos: " + pos);
136 				}
137 				catch (BadLocationException e) {
138 				}
139 			}
140 		}
141 
142 		if (autoScroll) {
143 			GUIHelper.scrollToEnd(jta);
144 		}
145     }
146 
147     public void propertyChange(PropertyChangeEvent e)
148     {
149 		updateProperties();
150     }
151 
152     /***
153      * Sets <code>text</code> to the console. This method is thread
154      * safe and can be called from any thread.
155      */
156     public void setLater(final String text)
157     {
158 		synchronized (pendingText) {
159 			pendingText.setLength(0);
160 		}
161 
162 		Runnable r = new Runnable()
163 			{
164 				public void run() 
165 				{
166 					setText(text);
167 				}
168 			};
169 		SwingUtilities.invokeLater(r);
170     }
171 
172     /***
173      * Sets the text of the console to <code>newValue</code>.
174      */
175     public void setText(String newValue)
176     {
177 		jta.setText(newValue);
178     }
179 
180     /***
181      * Updates the font and colors.
182      */
183     public void updateProperties()
184     {
185 		jta.setFont(prefs.getFont("consoleFont"));
186 		jta.setBackground(prefs.getColor("consoleBackgroundColor"));
187 		jta.setForeground(prefs.getColor("consoleForegroundColor"));
188     }
189 
190 }