cpoy from http://yanhua.blog.techweb.com.cn/archives/2006/200691815392.shtml#cmt
在前面的文章中我们提到过Eclipse可以显示一个动态显示内存使用情况的状态条,而且还有一个按钮可以手工进行垃圾回收,昨天我看到OSWorkflow的设计器也有这么一个功能,那到底是怎么实现的呢?其实一点都不难,我们只要写一个特殊的JPanel就可以了!
class MemoryPanel extends JPanel { //状态条的颜色 private Color edgeColor = new Color(82, 115, 214); private Color centerColor = new Color(180, 200, 230);
public void paint(Graphics g) { super.paint(g); //得到当前组件(JPanel)的大小 Dimension dimension = getSize(); //得到各边框的宽度 Insets insets = getInsets(); int left = insets.left; int top = insets.top; //得到内存使用状态信息 Runtime runtime = Runtime.getRuntime(); long freeMemory = runtime.freeMemory(); long totalMemory = runtime.totalMemory(); //组件(JPanel)除去左、右边框后的宽度 int insideWidth = dimension.width - (insets.left + insets.right); //内存使用量的显示宽度 int usedAmount = insideWidth - (int) (((long) insideWidth * freeMemory) / totalMemory); int insideHeight = dimension.height - (insets.bottom + insets.top); Graphics2D g2 = (Graphics2D) g; //设置渐变效果的画笔 g2.setPaint(new GradientPaint(left, top, edgeColor, left, insideHeight / 2, centerColor, true)); g.fillRect(left, top, usedAmount, insideHeight); g.setColor(getBackground()); g.fillRect(left + usedAmount, top, insideWidth - usedAmount, insideHeight); g.setFont(getFont()); g.setColor(Color.black); //显示状态的文字 String memory = (Long.toString((totalMemory - freeMemory) / 1048576L) + "M of " + Long.toString(totalMemory / 1048576L) + 'M'); //确定文字的显示位置 FontMetrics fontmetrics = g.getFontMetrics(); int stringWidth = fontmetrics.charsWidth(memory.toCharArray(), 0, memory.length()); int stringHeight = fontmetrics.getHeight() - fontmetrics.getDescent(); //显示文字 g.drawString(memory, left + (insideWidth - stringWidth) / 2, top + (insideHeight + stringHeight) / 2); } }
有了这个JPanel,我们可以把它加到一个Frame或另一个Panel上去了。
然后再启动一个计时器以便能让上面的JPanel实时更新。
Timer timer = new Timer(2000, new ActionListener() { public void actionPerformed(ActionEvent actionevent) { memoryPanel.repaint(); } }); timer.start();
至于那个可以人工进行垃圾回收的小垃圾桶就更好做了,做一个带图标的JButton,在它的事件处理中进行垃圾回收并再调用一下上面那个JPanel的repaint()方法就可以了。
gcButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) { System.gc(); memoryPanel.repaint(); } });