今天学到了Swing,粗略看了一下几个控件,就来试试手。
推荐使用Eclipse+WindowBuilder(可以像C#和C++MFC那样拖拖拖),贼方便。
WindowBuilder官方下载地址 其中还有个小教程视频。
WindowBuilder安装可参考
老师要求做一个简易计算器,思路就是使用两个栈,一个存数字,一个存运算符号,界面就拖拖拖就行,添加控件函数处理即可。
首先是新建一个JavaProject文件,右键->new->other->WindowBuilder->Swing Designer->JFrame(也可以选其他的) 如图:
选好后起好名字,在显示代码的界面下方有个Design,点击即可进入可视化编程(拖拖拖)
点进去是这个样子:
这里要先添加一个Layout(布局)控件
这里我选了Absolute Layout
之后就可以拖其他控件了,这里我做计算器,就拖了JButton和JTextField控件。选中控件,可在左边的Properties中调整控件属性
Variable是控件对应变量名,text是显示在控件上面的文本,还可以调一下字体、背景颜色什么的。
计算器界面弄完我的是这样的:
完了之后,添加控件响应函数,选中控件,右键->Add Event handle,然后选择控件函数Eclipse就会帮你添加相应的代码,我这里选的是鼠标点击事件函数,mouseClicked。接下来把响应函数写好,一个简易计算器就可完成。
以下是我的代码(省略部分重复操作的代码)
package swingPackages;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class JSQ extends JFrame {
private JPanel contentPane;
private JTextField textField;
//计算器对象
private Calculate calculate;
//保存用户输入的式子
private String Formula;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JSQ frame = new JSQ();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public JSQ() {
//设置标题
setTitle("简易计算器");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 340, 459);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
//文本框
textField = new JTextField();
textField.setFont(new Font("宋体", Font.BOLD, 20));
textField.setToolTipText("");
textField.setEditable(false);
textField.setBounds(37, 51, 247, 44);
contentPane.add(textField);
textField.setColumns(10);
//数字1
JButton btn1 = new JButton("1");
btn1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
String str = textField.getText();
textField.setText(str+"1");
}
});
btn1.setFont(new Font("宋体", Font.BOLD, 14));
btn1.setBounds(37, 188, 44, 44);
contentPane.add(btn1);
//...省略其他数字的代码
//小数点按钮
JButton btnDot = new JButton(".");
btnDot.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
String str = textField.getText();
textField.setText(str+".");
}
});
btnDot.setFont(new Font("宋体", Font.BOLD, 14));
btnDot.setBounds(104, 350, 44, 44);
contentPane.add(btnDot);
//等号“=”按钮
JButton btnEqual = new JButton("=");
btnEqual.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
String str = textField.getText();
str = str+"=";
Formula = str;
//按下等号后,执行计算
//创建计算器对象
calculate = new Calculate(Formula);
//获得返回的答案
double rs = calculate.calculation();
//把式子和答案返回文本框
textField.setText(str+" "+rs);
}
});
btnEqual.setFont(new Font("宋体", Font.BOLD, 14));
btnEqual.setBounds(169, 350, 44, 44);
contentPane.add(btnEqual);
//加号“+”按钮
JButton btnPlus = new JButton("+");
btnPlus.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
String str = textField.getText();
textField.setText(str+"+");
}
});
btnPlus.setFont(new Font("宋体", Font.BOLD, 14));
btnPlus.setBounds(238, 188, 44, 44);
contentPane.add(btnPlus);
//...省略其他运算符的代码
//删除键,这里只是做了个回退,即把文本框的文本去掉最后一个而已
//删除“<---”按钮
JButton btnDel = new JButton("<--");
btnDel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
String str = textField.getText();
if(str.length()>0){
str = str.substring(0, str.length()-1);
}
textField.setText(str);
}
});
btnDel.setFont(new Font("宋体", Font.BOLD, 14));
btnDel.setBounds(158, 134, 70, 44);
contentPane.add(btnDel);
//清屏本质上就是文本框的文本为空,所以只需要设置文本为空字符就可
//清屏“C”按钮
JButton btnC = new JButton("C");
btnC.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
textField.setText("");
}
});
btnC.setFont(new Font("宋体", Font.BOLD, 14));
btnC.setBounds(238, 134, 44, 44);
contentPane.add(btnC);
}
}
实际计算器类的代码:
package swingPackages;
import java.util.Arrays;
import java.util.Stack;
public class Calculate {
//保存计算的式子
private String Formula;
//操作数的栈
static Stack<Double> num_stack = new Stack<Double>();
//操作符的栈
static Stack<Character> opt_stack = new Stack<Character>();
/**
* 计算优先级函数
* @param c 计算符号,包括左括号
* @return 返回符号的优先级
*/
public int priority(char c){
int pro=0;
switch(c){
case '(':
pro = 3;
break;
case '*':
case '/':
pro = 2;
break;
case '+':
case '-':
pro = 1;
break;
default:
pro = 0;
break;
}
return pro;
}
public Calculate(String Formula){
this.Formula = Formula;
}
/**
* 计算函数
* @return 返回式子计算的结果
*/
public double calculation(){
char[] input = new char[1024];
Arrays.fill(input, '\0');
int i = 0,j = 0;
double num1 = 0,num2 = 0;
double tmp = 0.0;
//判断是否为负号
boolean isMinus = false;
//判断是否为负数
boolean isNegative = false;
//记录负号位置
int posMinus = 0;
char[] ss = Formula.toCharArray();
for(int k=0;k<ss.length;k++){
input[k] = ss[k];
}
while(input[i]!='\0' || opt_stack.empty()){
if(input[i]=='-'){
isMinus = true;
posMinus = i;
}
else
isMinus = false;
if(isMinus){
if(posMinus==0){
isNegative = true;
}
else{
if(input[posMinus-1]=='('){
isNegative = true;
}
}
}
if((input[i]>='0'&&input[i]<='9')||input[i]=='.'||(isNegative&&input[i]=='-')){
String num = "";
i++;
if((input[i]>'9' || input[i]<'0')&&(input[i]!='.')){
for(int k = j;k < i;k++){
if((input[k]>='0'&&input[k]<='9')||input[k]=='.'||(isNegative&&input[k]=='-'))
num = num + String.valueOf(input[k]);
}
if(num!=null){
tmp = Double.parseDouble(num);
isNegative = false;
}
num_stack.push(tmp);
tmp = 0.0;
j=i+1;
}
}
else{
if((input[i] == ')')&&(opt_stack.peek()=='(')){
opt_stack.pop();
i++;
continue;
}
if(opt_stack.empty()||(priority(input[i])>priority(opt_stack.peek()))||(opt_stack.peek()=='('&&(input[i]!=')'))){
opt_stack.push(input[i]);
i++;
continue;
}
if(((input[i] == '\0')&&opt_stack.empty()) || ( (input[i]==')')&&(opt_stack.peek()!='(')) ||(priority(input[i])<=priority(opt_stack.peek())) ){
char ch = opt_stack.pop();
switch(ch){
case'+':
num1 = num_stack.pop();
num2 = num_stack.pop();
num_stack.push(num1+num2);
break;
case'-':
num1 = num_stack.pop();
num2 = num_stack.pop();
num_stack.push(num2-num1);
break;
case'*':
num1 = num_stack.pop();
num2 = num_stack.pop();
num_stack.push(num1*num2);
break;
case'/':
num1 = num_stack.pop();
num2 = num_stack.pop();
num_stack.push(num2/num1);
break;
}
}
}
}
return num_stack.peek();
}
}