點我執行範例程式

我實做的 statusbar 主要是利用 JToolBar 來做的。主要就是把 border 去掉,floatable 關閉,再畫上陰影及右下方的三角形。其中最難的就是 JToolBar 的子元件會跟上方陰影重疊,為了把它們二者分離,花了我半天時間去實驗,最後才發現只要修改 getInsets 函數就好了。

一開始修改 getHeight,getWidth,paintChildren,利用 Graphics 的 translate 來位移子元件。但是在 JButton 上卻不行,只要滑鼠移到上方,觸發 rollover,在重畫子元件時,卻沒有經由 JToolBar 的 paintChildren,所以 translate 函數就沒有了,一樣會重疊。後來發現 getMargin 可以用來設定子元件跟 JToolBar 的間距,但是在某些 lookandfeel 下卻無效。後來才找到 getInsets,才是最終的王道,確確實實設定好 JToolBar 的間距。

public Insets getInsets() { Insets m = super.getInsets(); m.left += 5; m.top += 6; return m; } protected void paintComponent(Graphics g) { int x, y; super.paintComponent(g); x = getWidth(); y = 0; g.setColor(new Color(156, 154, 140)); g.drawLine(0, y, x, y); y++; g.setColor(new Color(196, 194, 183)); g.drawLine(0, y, x, y); y++; g.setColor(new Color(218, 215, 201)); g.drawLine(0, y, x, y); y++; g.setColor(new Color(233, 231, 217)); g.drawLine(0, y, x, y); x = getWidth(); y = getHeight(); g.setColor(new Color(255, 255, 255)); g.drawLine(x-12, y, x, y-12); g.drawLine(x-7, y, x, y-7); g.drawLine(x-2, y, x, y-2); g.setColor(new Color(172, 168, 153)); g.drawLine(x-11, y, x, y-11); g.drawLine(x-10, y, x, y-10); g.drawLine(x-9, y, x, y-9); g.drawLine(x-6, y, x, y-6); g.drawLine(x-5, y, x, y-5); g.drawLine(x-4, y, x, y-4); g.drawLine(x-1, y, x, y-1); g.drawLine(x, y, x, y); }

再來就是 JToolBar.Separator 的問題,只有在 Nimbus 下才顯得正常,在其它 lookandfeel 都很奇怪,不是間距太大,就是縮小間距後中間分隔線又不見等等問題。最後不得已只好自己來搞個 StatusBarSeparator,最重要的是自己搞一個 SeparatorUI,讓分隔線畫線統一,還有要注意的是 MaximumSize 及 PreferredSize 要設對,不然會造成間距太大。

public class StatusBarSeparator extends JToolBar.Separator { public StatusBarSeparator() { super(); super.setOrientation(JSeparator.VERTICAL); ui = new StatusBarBasicSeparatorUI(); // 重新設定 separator 元件寬度 Dimension d=super.getMaximumSize(); d.width = 22; setMaximumSize(d); // nimbus 需要再設定 preferredSize d=super.getPreferredSize(); d.width = 22; setPreferredSize(d); } public void setUI(SeparatorUI ui) { super.setUI(this.ui); } public SeparatorUI getUI() { return (SeparatorUI)ui; } /** * StatusBar separator UI */ public class StatusBarBasicSeparatorUI extends BasicSeparatorUI { public void paint( Graphics g, JComponent c ) { // 計算方位 Dimension d = c.getSize(); int left = (d.width-1) / 2; // 畫線 g.setColor( c.getForeground() ); g.drawLine( left, 0, left, d.height ); g.setColor( c.getBackground() ); g.drawLine( left+1, 0, left+1, d.height ); } } }

台南小新 發表在 痞客邦 PIXNET 留言(0) 人氣()