PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre3/org/gjt/sp/jedit/gui/StatusBar.java

#
Java | 583 lines | 418 code | 87 blank | 78 comment | 67 complexity | f2b3e994ba6cb62b4bfd44d2946fce42 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * StatusBar.java - The status bar displayed at the bottom of views
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2001 Slava Pestov
  7. * Portions copyright (C) 2001 mike dillon
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. */
  23. package org.gjt.sp.jedit.gui;
  24. //{{{ Imports
  25. import javax.swing.border.*;
  26. import javax.swing.text.Segment;
  27. import javax.swing.*;
  28. import java.awt.event.*;
  29. import java.awt.*;
  30. import org.gjt.sp.jedit.io.*;
  31. import org.gjt.sp.jedit.textarea.*;
  32. import org.gjt.sp.jedit.*;
  33. import org.gjt.sp.util.*;
  34. //}}}
  35. /**
  36. * The status bar, used for the following:
  37. * <ul>
  38. * <li>Displaying caret position information
  39. * <li>Displaying readNextChar() prompts
  40. * <li>Displaying the status of the overwrite, multi select flags
  41. * <li>I/O progress
  42. * <li>Memory status
  43. * <li>And so on
  44. * </ul>
  45. *
  46. * @version $Id: StatusBar.java 3936 2001-12-21 07:02:14Z spestov $
  47. * @author Slava Pestov
  48. * @since jEdit 3.2pre2
  49. */
  50. public class StatusBar extends JPanel implements WorkThreadProgressListener
  51. {
  52. //{{{ StatusBar constructor
  53. public StatusBar(View view)
  54. {
  55. super(new BorderLayout(3,3));
  56. setBorder(BorderFactory.createEmptyBorder(3,0,0,0));
  57. this.view = view;
  58. Border border = BorderFactory.createLoweredBevelBorder();
  59. MouseHandler mouseHandler = new MouseHandler();
  60. caretStatus = new VICaretStatus();
  61. caretStatus.setBorder(border);
  62. caretStatus.setToolTipText(jEdit.getProperty("view.status.caret-tooltip"));
  63. caretStatus.addMouseListener(mouseHandler);
  64. add(BorderLayout.WEST,caretStatus);
  65. messagePanel = new JPanel();
  66. messagePanel.setLayout(new BorderLayout(0,0));
  67. messagePanel.setBorder(border);
  68. messagePanel.setPreferredSize(caretStatus.getPreferredSize());
  69. add(BorderLayout.CENTER,messagePanel);
  70. message = new JLabel();
  71. message.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
  72. setMessageComponent(message);
  73. Box box = new Box(BoxLayout.X_AXIS);
  74. mode = new JLabel();
  75. mode.setBorder(border);
  76. mode.setToolTipText(jEdit.getProperty("view.status.mode-tooltip"));
  77. mode.addMouseListener(mouseHandler);
  78. box.add(mode);
  79. box.add(Box.createHorizontalStrut(3));
  80. encoding = new JLabel();
  81. encoding.setBorder(border);
  82. encoding.setToolTipText(jEdit.getProperty("view.status.encoding-tooltip"));
  83. encoding.addMouseListener(mouseHandler);
  84. box.add(encoding);
  85. box.add(Box.createHorizontalStrut(3));
  86. FontMetrics fm = getFontMetrics(UIManager.getFont("Label.font"));
  87. foldMode = new JLabel();
  88. foldMode.setHorizontalAlignment(SwingConstants.CENTER);
  89. foldMode.setBorder(border);
  90. foldMode.setToolTipText(jEdit.getProperty("view.status.fold-tooltip"));
  91. foldMode.addMouseListener(mouseHandler);
  92. Dimension dim = foldMode.getPreferredSize();
  93. dim.width += Math.max(fm.stringWidth("none"),
  94. Math.max(
  95. fm.stringWidth("indent"),
  96. fm.stringWidth("explicit")));
  97. foldMode.setPreferredSize(dim);
  98. box.add(foldMode);
  99. box.add(Box.createHorizontalStrut(3));
  100. multiSelect = new JLabel();
  101. multiSelect.setHorizontalAlignment(SwingConstants.CENTER);
  102. multiSelect.setBorder(border);
  103. multiSelect.setToolTipText(jEdit.getProperty("view.status.multi-tooltip"));
  104. multiSelect.addMouseListener(mouseHandler);
  105. dim = multiSelect.getPreferredSize();
  106. dim.width += Math.max(fm.stringWidth("single"),
  107. fm.stringWidth("multi"));
  108. multiSelect.setPreferredSize(dim);
  109. box.add(multiSelect);
  110. box.add(Box.createHorizontalStrut(3));
  111. overwrite = new JLabel();
  112. overwrite.setHorizontalAlignment(SwingConstants.CENTER);
  113. overwrite.setBorder(border);
  114. overwrite.setToolTipText(jEdit.getProperty("view.status.overwrite-tooltip"));
  115. overwrite.addMouseListener(mouseHandler);
  116. dim = overwrite.getPreferredSize();
  117. dim.width += Math.max(fm.stringWidth("ovr"),
  118. fm.stringWidth("ins"));
  119. overwrite.setPreferredSize(dim);
  120. box.add(overwrite);
  121. updateBufferStatus();
  122. updateMiscStatus();
  123. box.add(Box.createHorizontalStrut(3));
  124. memory = new MemoryStatus();
  125. memory.setBorder(border);
  126. memory.addMouseListener(mouseHandler);
  127. box.add(memory);
  128. // UI hack because BoxLayout does not give all components the
  129. // same height
  130. dim = memory.getPreferredSize();
  131. dim.width += fm.stringWidth("99Mb/999Mb");
  132. dim.height = multiSelect.getPreferredSize().height;
  133. memory.setPreferredSize(dim);
  134. // Leave some room for OS X grow box
  135. if(System.getProperty("os.name").indexOf("Mac") != -1)
  136. box.add(Box.createHorizontalStrut(18));
  137. add(BorderLayout.EAST,box);
  138. } //}}}
  139. //{{{ addNotify() method
  140. public void addNotify()
  141. {
  142. super.addNotify();
  143. VFSManager.getIOThreadPool().addProgressListener(this);
  144. } //}}}
  145. //{{{ removeNotify() method
  146. public void removeNotify()
  147. {
  148. super.removeNotify();
  149. VFSManager.getIOThreadPool().removeProgressListener(this);
  150. } //}}}
  151. //{{{ WorkThreadListener implementation
  152. //{{{ statusUpdate() method
  153. public void statusUpdate(final WorkThreadPool threadPool, int threadIndex)
  154. {
  155. SwingUtilities.invokeLater(new Runnable()
  156. {
  157. public void run()
  158. {
  159. int requestCount = threadPool.getRequestCount();
  160. if(requestCount == 0)
  161. {
  162. setMessageAndClear(jEdit.getProperty(
  163. "view.status.io.done"));
  164. }
  165. else if(requestCount == 1)
  166. {
  167. setMessage(jEdit.getProperty(
  168. "view.status.io-1"));
  169. }
  170. else
  171. {
  172. Object[] args = { new Integer(requestCount) };
  173. setMessage(jEdit.getProperty(
  174. "view.status.io",args));
  175. }
  176. }
  177. });
  178. } //}}}
  179. //{{{ progressUpdate() method
  180. public void progressUpdate(WorkThreadPool threadPool, int threadIndex)
  181. {
  182. } //}}}
  183. //}}}
  184. //{{{ setMessageAndClear() method
  185. /**
  186. * Show a message for a short period of time.
  187. * @param message The message
  188. * @since jEdit 3.2pre5
  189. */
  190. public void setMessageAndClear(String message)
  191. {
  192. setMessage(message);
  193. tempTimer = new Timer(0,new ActionListener()
  194. {
  195. public void actionPerformed(ActionEvent evt)
  196. {
  197. // so if view is closed in the meantime...
  198. if(isShowing())
  199. setMessage(null);
  200. }
  201. });
  202. tempTimer.setInitialDelay(10000);
  203. tempTimer.setRepeats(false);
  204. tempTimer.start();
  205. } //}}}
  206. //{{{ setMessage() method
  207. public void setMessage(String message)
  208. {
  209. if(tempTimer != null)
  210. {
  211. tempTimer.stop();
  212. tempTimer = null;
  213. }
  214. setMessageComponent(this.message);
  215. if(message == null)
  216. {
  217. InputHandler inputHandler = view.getInputHandler();
  218. if(inputHandler.isRepeatEnabled())
  219. {
  220. int repeatCount = inputHandler.getRepeatCount();
  221. this.message.setText(jEdit.getProperty("view.status.repeat",
  222. new Object[] { repeatCount == 1 ? "" : String.valueOf(repeatCount) }));
  223. }
  224. else if(view.getMacroRecorder() != null)
  225. this.message.setText(jEdit.getProperty("view.status.recording"));
  226. else
  227. this.message.setText(null);
  228. }
  229. else
  230. this.message.setText(message);
  231. } //}}}
  232. //{{{ setMessageComponent() method
  233. public void setMessageComponent(Component comp)
  234. {
  235. if (comp == null || messageComp == comp)
  236. {
  237. return;
  238. }
  239. messageComp = comp;
  240. messagePanel.add(BorderLayout.CENTER, messageComp);
  241. } //}}}
  242. //{{{ repaintCaretStatus() method
  243. public void repaintCaretStatus()
  244. {
  245. caretStatus.repaint();
  246. } //}}}
  247. //{{{ updateBufferStatus() method
  248. public void updateBufferStatus()
  249. {
  250. Buffer buffer = view.getBuffer();
  251. mode.setText(buffer.getMode().getName());
  252. encoding.setText(buffer.getStringProperty("encoding"));
  253. } //}}}
  254. //{{{ updateMiscStatus() method
  255. public void updateMiscStatus()
  256. {
  257. JEditTextArea textArea = view.getTextArea();
  258. multiSelect.setText(textArea.isMultipleSelectionEnabled()
  259. ? "multi" : "single");
  260. overwrite.setText(textArea.isOverwriteEnabled()
  261. ? "ovr" : "ins");
  262. foldMode.setText((String)textArea.getBuffer().getProperty("folding"));
  263. } //}}}
  264. //{{{ Private members
  265. private View view;
  266. private VICaretStatus caretStatus;
  267. private JPanel messagePanel;
  268. private Component messageComp;
  269. private JLabel message;
  270. private JLabel mode;
  271. private JLabel encoding;
  272. private JLabel foldMode;
  273. private JLabel multiSelect;
  274. private JLabel overwrite;
  275. private MemoryStatus memory;
  276. /* package-private for speed */ StringBuffer buf = new StringBuffer();
  277. private Timer tempTimer;
  278. //}}}
  279. static final String testStr = "9999,999-999 99%";
  280. //{{{ MouseHandler class
  281. class MouseHandler extends MouseAdapter
  282. {
  283. //{{{ mouseClicked() method
  284. public void mouseClicked(MouseEvent evt)
  285. {
  286. Object source = evt.getSource();
  287. if(source == caretStatus)
  288. {
  289. if(evt.getClickCount() == 2)
  290. view.getTextArea().showGoToLineDialog();
  291. }
  292. else if(source == mode || source == encoding)
  293. {
  294. if(evt.getClickCount() == 2)
  295. new BufferOptions(view,view.getBuffer());
  296. }
  297. else if(source == foldMode)
  298. {
  299. String text = foldMode.getText();
  300. if(text.equals("none"))
  301. text = "indent";
  302. else if(text.equals("indent"))
  303. text = "explicit";
  304. else if(text.equals("explicit"))
  305. text = "none";
  306. JEditTextArea textArea = view.getTextArea();
  307. Buffer buffer = view.getBuffer();
  308. buffer.setStringProperty("folding",text);
  309. buffer.propertiesChanged();
  310. int collapseFolds = buffer.getIntegerProperty(
  311. "collapseFolds",0);
  312. if(collapseFolds != 0)
  313. {
  314. textArea.getFoldVisibilityManager()
  315. .expandFolds(collapseFolds);
  316. }
  317. else
  318. {
  319. textArea.getFoldVisibilityManager()
  320. .expandAllFolds();
  321. }
  322. }
  323. else if(source == multiSelect)
  324. view.getTextArea().toggleMultipleSelectionEnabled();
  325. else if(source == overwrite)
  326. view.getTextArea().toggleOverwriteEnabled();
  327. else if(source == memory)
  328. {
  329. if(evt.getClickCount() == 2)
  330. jEdit.showMemoryDialog(view);
  331. }
  332. } //}}}
  333. } //}}}
  334. //{{{ VICaretStatus class
  335. class VICaretStatus extends JComponent
  336. {
  337. //{{{ VICaretStatus constructor
  338. public VICaretStatus()
  339. {
  340. VICaretStatus.this.setForeground(UIManager.getColor("Label.foreground"));
  341. VICaretStatus.this.setBackground(UIManager.getColor("Label.background"));
  342. VICaretStatus.this.setFont(UIManager.getFont("Label.font"));
  343. Dimension size = new Dimension(
  344. VICaretStatus.this.getFontMetrics(
  345. VICaretStatus.this.getFont())
  346. .stringWidth(testStr),0);
  347. VICaretStatus.this.setPreferredSize(size);
  348. } //}}}
  349. //{{{ paintComponent() method
  350. public void paintComponent(Graphics g)
  351. {
  352. Buffer buffer = view.getBuffer();
  353. if(!buffer.isLoaded())
  354. return;
  355. FontMetrics fm = g.getFontMetrics();
  356. JEditTextArea textArea = view.getTextArea();
  357. int currLine = textArea.getCaretLine();
  358. int dot = textArea.getCaretPosition()
  359. - textArea.getLineStartOffset(currLine);
  360. int virtualPosition = getVirtualPosition(dot,buffer,textArea);
  361. buf.setLength(0);
  362. buf.append(Integer.toString(currLine + 1));
  363. buf.append(',');
  364. buf.append(Integer.toString(dot + 1));
  365. if (virtualPosition != dot)
  366. {
  367. buf.append('-');
  368. buf.append(Integer.toString(virtualPosition + 1));
  369. }
  370. buf.append(' ');
  371. int firstLine = textArea.getFirstLine();
  372. int visible = textArea.getVisibleLines();
  373. int lineCount = textArea.getVirtualLineCount();
  374. if (visible >= lineCount)
  375. {
  376. buf.append("All");
  377. }
  378. else if (firstLine == 0)
  379. {
  380. buf.append("Top");
  381. }
  382. else if (firstLine + visible >= lineCount)
  383. {
  384. buf.append("Bot");
  385. }
  386. else
  387. {
  388. float percent = (float)firstLine / (float)lineCount
  389. * 100.0f;
  390. buf.append(Integer.toString((int)percent));
  391. buf.append('%');
  392. }
  393. g.drawString(buf.toString(),
  394. VICaretStatus.this.getBorder().getBorderInsets(this).left + 1,
  395. (VICaretStatus.this.getHeight() + fm.getAscent()) / 2 - 1);
  396. } //}}}
  397. //{{{ Private members
  398. private Segment seg = new Segment();
  399. //{{{ getVirtualPosition() method
  400. private int getVirtualPosition(int dot, Buffer buffer, JEditTextArea textArea)
  401. {
  402. int line = textArea.getCaretLine();
  403. textArea.getLineText(line, seg);
  404. int virtualPosition = 0;
  405. int tabSize = buffer.getTabSize();
  406. for (int i = 0; i < seg.count && i < dot; ++i)
  407. {
  408. char ch = seg.array[seg.offset + i];
  409. if (ch == '\t')
  410. {
  411. virtualPosition += tabSize
  412. - (virtualPosition % tabSize);
  413. }
  414. else
  415. {
  416. ++virtualPosition;
  417. }
  418. }
  419. return virtualPosition;
  420. } //}}}
  421. //}}}
  422. } //}}}
  423. //{{{ MemoryStatus class
  424. class MemoryStatus extends JComponent implements ActionListener
  425. {
  426. //{{{ MemoryStatus constructor
  427. public MemoryStatus()
  428. {
  429. MemoryStatus.this.setDoubleBuffered(true);
  430. MemoryStatus.this.setForeground(UIManager.getColor("Label.foreground"));
  431. MemoryStatus.this.setBackground(UIManager.getColor("Label.background"));
  432. MemoryStatus.this.setFont(UIManager.getFont("Label.font"));
  433. } //}}}
  434. //{{{ addNotify() method
  435. public void addNotify()
  436. {
  437. super.addNotify();
  438. timer = new Timer(2000,this);
  439. timer.start();
  440. ToolTipManager.sharedInstance().registerComponent(this);
  441. } //}}}
  442. //{{{ removeNotify() method
  443. public void removeNotify()
  444. {
  445. timer.stop();
  446. ToolTipManager.sharedInstance().unregisterComponent(this);
  447. } //}}}
  448. //{{{ getToolTipText() method
  449. public String getToolTipText()
  450. {
  451. Runtime runtime = Runtime.getRuntime();
  452. int freeMemory = (int)(runtime.freeMemory() / 1024);
  453. int totalMemory = (int)(runtime.totalMemory() / 1024);
  454. int usedMemory = (totalMemory - freeMemory);
  455. Integer[] args = { new Integer(usedMemory),
  456. new Integer(totalMemory) };
  457. return jEdit.getProperty("view.status.memory-tooltip",args);
  458. } //}}}
  459. //{{{ actionPerformed() method
  460. public void actionPerformed(ActionEvent evt)
  461. {
  462. MemoryStatus.this.repaint();
  463. } //}}}
  464. //{{{ paintComponent() method
  465. public void paintComponent(Graphics g)
  466. {
  467. Insets insets = MemoryStatus.this.getBorder().getBorderInsets(this);
  468. Runtime runtime = Runtime.getRuntime();
  469. int freeMemory = (int)(runtime.freeMemory() / 1024 / 1024);
  470. int totalMemory = (int)(runtime.totalMemory() / 1024 / 1024);
  471. int usedMemory = (totalMemory - freeMemory);
  472. int width = MemoryStatus.this.getWidth()
  473. - insets.left - insets.right;
  474. Color text = MemoryStatus.this.getForeground();
  475. Color status = UIManager.getColor("ProgressBar.foreground");
  476. if(status.equals(text))
  477. g.setXORMode(MemoryStatus.this.getBackground());
  478. else
  479. g.setColor(status);
  480. float fraction = ((float)usedMemory) / totalMemory;
  481. g.fillRect(insets.left,insets.top,
  482. (int)(width * fraction),
  483. MemoryStatus.this.getHeight()
  484. - insets.top - insets.bottom);
  485. g.setPaintMode();
  486. g.setColor(text);
  487. String str = "" + usedMemory + "Mb/"
  488. + totalMemory + "Mb";
  489. FontMetrics fm = g.getFontMetrics();
  490. g.drawString(str,
  491. insets.left + (width - fm.stringWidth(str)) / 2,
  492. insets.top + fm.getAscent());
  493. } //}}}
  494. private Timer timer;
  495. } //}}}
  496. }