Posted on 2010-09-13 10:32
TWaver 閱讀(2358)
評論(0) 編輯 收藏
做ERP或財務軟件的朋友知道,中國式的憑證錄入界面需要一些特殊的顯示效果:錄入金額的單元格要顯示一些數字分割線。估計這個風格來自老式的手工記賬本,因為我還隱約的記得當年從生產隊倉庫里面偷來的賬本就是這個樣子滴。為了繼續與“Swing很丑”的偏見做斗爭,持續弘揚Java的創新精神以及“除了老婆一切都可共享”的Share宗旨,這里特意用Swing寫了一個小例子,實現“中國式”的憑證錄入界面。

這里面主要用到了Swing Table的Renderer和Editor這兩個機制,也是Swing比較有代表性的技術,大家都不陌生。對于熟悉這個機制的童鞋來說,本文實在沒什么新意。這里也就不啰嗦廢話了,直奔主題,點到為止,然后上代碼。
用下面代碼設置table一個列的renderer和editor:
1
table.getColumnModel().getColumn(2).setCellRenderer(new MoneyRenderer());
2
table.getColumnModel().getColumn(2).setCellEditor(new MoneyEditor());
在renderer中,首先paint縱向的豎線,然后在paint正常的單元格內容。
1
@Override
2
public void paintChildren(Graphics g)
{
3
Graphics2D g2d = (Graphics2D) g;
4
painter.paint(this, g2d, null);
5
super.paintComponent(g);
6
}
其中,painter是一個封裝好的用來畫豎線的類。里面說道:
1
public class LinePainter
{
2
3
private Stroke normalStroke = new BasicStroke(1);
4
private Stroke thickStroke = new BasicStroke(1);
5
private Color normalColor = Color.lightGray;
6
private Color tickColor = Color.cyan.darker();
7
private Color decimalColor = Color.red;
8
9
public void paint(JComponent component, Graphics2D g, Color lineColor)
{
10
g.setColor(Color.gray);
11
g.setFont(component.getFont());
12
Rectangle2D bounds = g.getFontMetrics().getStringBounds("0", g);
13
int unitWidth = (int) bounds.getWidth();
14
15
int x = component.getWidth();
16
int rightGap = 0;
17
if (component.getInsets() != null)
{
18
rightGap = component.getInsets().right;
19
}
20
if (component.getBorder() != null)
{
21
rightGap = rightGap + component.getBorder().getBorderInsets(component).right;
22
}
23
if (component instanceof JTextComponent)
{
24
JTextComponent textComponent = (JTextComponent) component;
25
Insets insets = textComponent.getMargin();
26
rightGap = rightGap + insets.right;
27
rightGap = rightGap + 2;
28
}
29
30
x = x - rightGap;
31
32
int index = 0;
33
while (x > unitWidth * 2)
{
34
x = x - unitWidth;
35
if (index == 1)
{
36
g.setStroke(thickStroke);
37
g.setColor(decimalColor);
38
} else
{
39
if ((index - 1) % 3 == 0)
{
40
g.setColor(tickColor);
41
} else
{
42
g.setColor(normalColor);
43
}
44
g.setStroke(normalStroke);
45
}
46
g.drawLine(x, 0, x, component.getHeight());
47
index++;
48
}
49
if (lineColor != null)
{
50
g.setColor(lineColor);
51
g.setStroke(this.normalStroke);
52
g.drawLine(0, component.getHeight() - 1, component.getWidth(), component.getHeight() - 1);
53
}
54
}
55
}
很簡單,就一個paint函數,畫縱向的彩條線而已。注意間距、字體等的考慮。
為了在編輯期間也能顯示縱向線條,所以要定制editor,且重寫TextField的paint,先畫線條,再super正常的內容paint:
1
@Override
2
public void paint(Graphics g)
{
3
Graphics2D g2d = (Graphics2D) g;
4
painter.paint(this, g2d, Color.red);
5
super.paint(g);
6
}
這樣,整個程序就結束了。稍作修改,加上輸入格式檢查、匯率轉換等東西,相信可以很容易的用在你家的ERP或者財務軟件上。
給幾個家庭作業:
1、這張憑證記錄了什么業務活動的發生?
2、為什么“庫存商品”一欄的金額在“借方”,而“銀行現金”一欄的金額在“貸方”?
3、為什么“進項稅額”的金額是17元?
如果能隨口回答這幾個問題,說明你不僅僅是個優秀的程序員,還是個優秀的財務;至少做個出納沒問題!等咱寫不動程序了,去工廠應聘一下出納吧,沒準能成!