当前位置: 代码迷 >> Web前端 >> Swing界面格局之代码手写一, 计算器layout实现
  详细解决方案

Swing界面格局之代码手写一, 计算器layout实现

热度:228   发布时间:2012-08-24 10:00:21.0
Swing界面布局之代码手写一, 计算器layout实现

很多人认为Swing的布局设计很难, 其实并不然
一方面是教科书的误导
另一方面是Swing的布局思想比较先进, 理解了, 你就会喜欢上它

这篇贴子, 先讲简单的, 也是许多人学习swing时最想做的事, 我希望像VS一样设计Layout
要在Swing里实现这个, 其实很简单, 只须要轻轻地告诉swing, 我的layout为null即可
可惜, 读了好多本swing的书, 都没有比较仔细的例子, 只有简单地说一下(一小段文字)

下面是用swing做的一个计算器demo, 只有layout, 没有功能实现




既然是手写代码, 当然是简洁喽, 不像IDE生成的一大堆不明所以的代码

Java代码 复制代码?收藏代码
  1. public?CalculatorView()?{ ??
  2. ????frame=new?JFrame("计算器"); ??
  3. ????frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);???????//退出窗口时关闭线程 ??
  4. ????frame.setBounds(200,?200,?300,?250);????????????????//初始位置和大小 ??
  5. ????frame.setResizable(false);??????????????????//不能放大 ??
  6. ????container=frame.getContentPane();???????????????//指定container ??
  7. ????container.setLayout(null);??????????????????//像VS一样的布局,简单实现 ??
  8. ????setLookAndFeel();???????????????????????//XP?style的layout ??
  9. ????addComponent();?????????????????????????//添加控件 ??
  10. ????frame.setVisible(true);?????????????????????//最后把窗口显示出来 ??
  11. }??
	public CalculatorView() {
		frame=new JFrame("计算器");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);		//退出窗口时关闭线程
		frame.setBounds(200, 200, 300, 250);				//初始位置和大小
		frame.setResizable(false);					//不能放大
		container=frame.getContentPane();				//指定container
		container.setLayout(null);					//像VS一样的布局,简单实现
		setLookAndFeel();						//XP style的layout
		addComponent();							//添加控件
		frame.setVisible(true);						//最后把窗口显示出来
	}



添加控件: 菜单, 结果文本框, 按钮

Java代码 复制代码?收藏代码
  1. void?addComponent(){ ??
  2. ????addMenu();??????????????????????//添加菜单栏 ??
  3. ????addResultText();????????????????????//添加结果显示文本框 ??
  4. ????addButtonGroup();???????????????????//添加按钮 ??
  5. ??
  6. ????container.setBackground(new?Color(236,233,216));????//调整面板颜色一致 ??
  7. ????JSeparator?sep1=new?JSeparator();???????????//菜单栏下面的分隔线 ??
  8. ????sep1.setBounds(0,?30,?300,?1); ??
  9. ????sep1.setForeground(Color.WHITE); ??
  10. ????container.add(sep1); ??
  11. }??
	void addComponent(){
		addMenu();						//添加菜单栏
		addResultText();					//添加结果显示文本框
		addButtonGroup();					//添加按钮

		container.setBackground(new Color(236,233,216));	//调整面板颜色一致
		JSeparator sep1=new JSeparator();			//菜单栏下面的分隔线
		sep1.setBounds(0, 30, 300, 1);
		sep1.setForeground(Color.WHITE);
		container.add(sep1);
	}



菜单和结果文本框比较简单, 不贴上来, 下面的按钮的

Java代码 复制代码?收藏代码
  1. void?addButtonGroup(){ ??
  2. ????JPanel?panBtn=new?JPanel(null);?????????//所有的按钮都加在这个panel里 ??
  3. ????panBtn.setBounds(0,?65,?300,?200); ??
  4. ????JButton?btnBS=new?JButton("Backspace");?????//backspace,CE,C三个按钮单独添加 ??
  5. ????btnBS.setBounds(60,?5,?80,?25); ??
  6. ????panBtn.add(btnBS);??????????????//new?BtnUI() ??
  7. ????btnBS.setUI(new?BtnUI());???????????//由于swing的文字渲染要求按钮 ??
  8. ????JButton?btnCE=new?JButton("CE");????????//要很多的横向空间,?所以只好 ??
  9. ????btnCE.setBounds(150,?5,?60,?25);????????//自己override文字渲染function ??
  10. ????panBtn.add(btnCE); ??
  11. ????JButton?btnC=new?JButton("C"); ??
  12. ????btnC.setBounds(220,?5,?60,?25); ??
  13. ????panBtn.add(btnC); ??
  14. ???? ??
  15. ????String[]?btnName={ ??
  16. ????????"MC",?"7",?"8",?"9",?"/",?"sqrt"??
  17. ????????,"MR",?"4",?"5",?"6",?"*",?"%"??
  18. ????????,"MS",?"1",?"2",?"3",?"-",?"1/x"??
  19. ????????,"M+",?"0",?"+/-",?".",?"+",?"="??
  20. ????}; ??
  21. ????JButton[]?btns=new?JButton[24]; ??
  22. ????int?i=0; ??
  23. ????int?oriX=15; ??
  24. ????int?oriY=35; ??
  25. ????int?btnW=40; ??
  26. ????int?btnH=25; ??
  27. ????for(JButton?btn?:?btns){ ??
  28. ????????btn=new?JButton(); ??
  29. ????????btns[i]=btn; ??
  30. ????????int?x=(i%6)*(btnW+5)+oriX; ??
  31. ????????int?y=(i/6)*(btnH+5)+oriY; ??
  32. ????????x=(i%6==0)?x-10:x;??????//add?sep?sapce?more ??
  33. ????????btn.setText(btnName[i++]); ??
  34. ????????btn.setUI(new?BtnUI()); ??
  35. ????????btn.setForeground(Color.blue); ??
  36. ????????btn.setBounds(x,?y,?btnW,?btnH); ??
  37. ????????panBtn.add(btn); ??
  38. ????} ??
  39. ????//set?some?button?color?to?red ??
  40. ????int?red[]={0,?6,?12,?18,?4,?10,?16,?22,?23}; ??
  41. ????for(int?n?:?red){ ??
  42. ????????btns[n].setForeground(Color.RED); ??
  43. ????} ??
  44. ????btnBS.setForeground(Color.RED); ??
  45. ????btnCE.setForeground(Color.RED); ??
  46. ????btnC.setForeground(Color.RED); ??
  47. ????container.add(panBtn);??????????????????//panel加进container容器里 ??
  48. }??
	void addButtonGroup(){
		JPanel panBtn=new JPanel(null);			//所有的按钮都加在这个panel里
		panBtn.setBounds(0, 65, 300, 200);
		JButton btnBS=new JButton("Backspace");		//backspace,CE,C三个按钮单独添加
		btnBS.setBounds(60, 5, 80, 25);
		panBtn.add(btnBS);				//new BtnUI()
		btnBS.setUI(new BtnUI());			//由于swing的文字渲染要求按钮
		JButton btnCE=new JButton("CE");		//要很多的横向空间, 所以只好
		btnCE.setBounds(150, 5, 60, 25);		//自己override文字渲染function
		panBtn.add(btnCE);
		JButton btnC=new JButton("C");
		btnC.setBounds(220, 5, 60, 25);
		panBtn.add(btnC);
		
		String[] btnName={
			"MC", "7", "8", "9", "/", "sqrt"
			,"MR", "4", "5", "6", "*", "%"
			,"MS", "1", "2", "3", "-", "1/x"
			,"M+", "0", "+/-", ".", "+", "="
		};
		JButton[] btns=new JButton[24];
		int i=0;
		int oriX=15;
		int oriY=35;
		int btnW=40;
		int btnH=25;
		for(JButton btn : btns){
			btn=new JButton();
			btns[i]=btn;
			int x=(i%6)*(btnW+5)+oriX;
			int y=(i/6)*(btnH+5)+oriY;
			x=(i%6==0)?x-10:x;		//add sep sapce more
			btn.setText(btnName[i++]);
			btn.setUI(new BtnUI());
			btn.setForeground(Color.blue);
			btn.setBounds(x, y, btnW, btnH);
			panBtn.add(btn);
		}
		//set some button color to red
		int red[]={0, 6, 12, 18, 4, 10, 16, 22, 23};
		for(int n : red){
			btns[n].setForeground(Color.RED);
		}
		btnBS.setForeground(Color.RED);
		btnCE.setForeground(Color.RED);
		btnC.setForeground(Color.RED);
		container.add(panBtn);					//panel加进container容器里
	}



BtnUI(),
由于swing的文字渲染要求按钮, 要很多的横向空间, 所以只好自己override文字渲染function

Java代码 复制代码?收藏代码
  1. class?BtnUI?extends?WindowsButtonUI?{ ??
  2. ??
  3. ????????@Override??
  4. ????????protected?void?paintText(Graphics?g,?AbstractButton?b,?Rectangle?textRect,?String?text)?{ ??
  5. ????????????textRect.width=40; ??
  6. ????????????text=b.getText(); ??
  7. //??????????FontMetrics?fm=SwingUtilities2.getFontMetrics(b,?g);????????//source?code?method ??
  8. ????????????FontMetrics?fm=Toolkit.getDefaultToolkit().getFontMetrics(b.getFont()); ??
  9. ????????????int?w=fm.stringWidth(text); ??
  10. ????????????int?x=(b.getWidth()-w)/2; ??
  11. ????????????int?y=17; ??
  12. ????????????g.setColor(b.getForeground()); ??
  13. //??????????SwingUtilities2.drawString(b,?g,?text,?x,?y);???????????????//source?code?method ??
  14. ????????????g.drawString(text,?x,?y); ??
  15. ????????} ??
  16. ????}??
class BtnUI extends WindowsButtonUI {

		@Override
		protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {
			textRect.width=40;
			text=b.getText();
//			FontMetrics fm=SwingUtilities2.getFontMetrics(b, g);		//source code method
			FontMetrics fm=Toolkit.getDefaultToolkit().getFontMetrics(b.getFont());
			int w=fm.stringWidth(text);
			int x=(b.getWidth()-w)/2;
			int y=17;
			g.setColor(b.getForeground());
//			SwingUtilities2.drawString(b, g, text, x, y);				//source code method
			g.drawString(text, x, y);
		}
	}



以上, 只有178行, 够简洁吧, 其实主要不是在乎行数的多少, 而是受不了IDE生成的一大堆代码
而且, 自己写, 结构能控制得更好