一个图形计算器 Java(使用GridBagLayout布局完成的)
目前正在详细总结一下以前写的一些东西,这是之前学着写的一个Java计算器小程序。
先说一下GridBagLaout,GridBagLayout是swing提供的一种十分灵活的布局方式。它不要求组件的大小相同便可以将
组件垂直、水平或沿它们的基线对齐。每个 GridBagLayout 对象维持一个动态的矩形单元网格,每个组件占用一个或多个这样的单元,该单元被称为显示区域。大致来说,它将父容器看成了一个表格 ,你可以将你的组件随意的放入一个或多个矩形单元格中,而每个组件,要占几个网格单元,每个组件要占领的位置在哪等等,都是要用GridBagConstraints类的对象来设置。并且它的添加组件是讲究顺序的,所以在进行之前,最好拟表格大致规划一下每个组件的位置及大小。
GridBagConstraints属性:
1、gridx,gridy:(gridx,gridy)组件的左上角坐标
2、gridwidth,gridheight: 组件占用的网格行数和列数
3、weightx,weighty:分布额外空间(单元格区域外,容器边缘内的间隔)
4、fill:组件填充显示区域的方式
5、ipadx,ipady:组件的内边距
6、insets :组件外边距
放一下代码,具体里面的这些属性都写了详细的注解可以慢慢看一下。
package text;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
/**
*
* @author Administrator
*/
public class SimpleCalculate extends JFrame{
private Container container =this.getContentPane();//定义一个私有的抽象组件类container,获取内容面版容器,简单说就是初始化一个容器,在这里是初始化一个容器并命名该容器为container
private GridBagLayout gridBagLayout=new GridBagLayout();//定义一个私有的面板类
//GridBagLayout是java中一种复杂的布局管理器
//设置为FridBagLayout的容器必须使用add(Component comp, Object constraints)来添加组件,要注意其参数的填写
private GridBagConstraints gridBagConstraints=new GridBagConstraints();//定义一个私有类用于添加和删除
//要使用GridBagLayout,必须使用GridBagConstraints对象来指定GridBagLayout中组件的位置
private JTextField displayField;//计算器结果显示区
//JTextField类是一个允许编辑单行文本的组件。
private String command="=";
private boolean start=true;
private double result=0;
public static void main(String[] args) {
new SimpleCalculate();
}
private SimpleCalculate(){
super("简易计算器");//super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
container.setLayout(gridBagLayout);//建立GridLayou版面配置格子
DisplayArea();
Frame();
Buttons();
}
private void Frame() {
setSize(500,500);
setVisible(true);//可以运行开始画图了
setResizable(false);//设置此窗体是否可由用户调整大小
setForeground(Color.WHITE);//设置前景色
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
private void Buttons() {
// 注册监听器以监听事件源产生的事件
ActionListener math = new SimpleCalculate.MathAction();
ActionListener command = new SimpleCalculate.CommandAction();
addButton("删除",0,1,2,1,math);addButton("清空",2,1,2,1,math);
addButton("7",0,2,1,1,math);addButton("8",1,2,1,1,math);addButton("9",2,2,1,1,math);addButton("+",3,2,1,1,command);
addButton("4",0,3,1,1,math);addButton("5",1,3,1,1,math);addButton("6",2,3,1,1,math);addButton("-",3,3,1,1,command);
addButton("1",0,4,1,1,math);addButton("2",1,4,1,1,math);addButton("3",2,4,1,1,math);addButton("*",3,4,1,1,command);
addButton("0",0,5,1,1,math);addButton(".",1,5,1,1,math);addButton("%",2,5,1,1,command);addButton("/",3,5,1,1,command);
addButton("=",0,6, 4, 1, command);
}
private void DisplayArea() {
displayField = new JTextField(20);
displayField.setHorizontalAlignment(4);
displayField.setBackground(Color.GRAY);
displayField.setDisabledTextColor(Color.WHITE);
displayField.setEnabled(false);//按钮设置为不可点击
// setClickable():设置成true时,按钮为可点击,设置为false时,按钮不可点击,不能响应点击事件,但此时如果setEnabled()为true,那么按钮即使不可点击(setClickable()为false),也会产生变化(一闪一闪)。
//
// setEnabled():设置成true时,相当于激活了按钮,按钮的状态不再是死的,而是会对触摸或者点击产生反应,并且可以响应一些触发事件。而设置成false时,按钮是灰色的,无论是否可点击(即使将setClickable()设置成true),都无法响应任何触发事件。
displayField.setFont(new Font("宋体", Font.BOLD, 50));
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.gridwidth = 4;
gridBagConstraints.gridheight = 1;
gridBagConstraints.fill = 1;
gridBagConstraints.weightx = 1;
gridBagConstraints.weighty = 1;
gridBagLayout.setConstraints(displayField, gridBagConstraints);
container.add(displayField);
}
private void addButton(String label ,int col ,int row ,int width ,int height ,ActionListener actionListener) {
JButton button=new JButton(label);
button.setForeground(Color.BLACK);
button.addActionListener(actionListener);
button.setFont(new Font("楷体", Font.BOLD, 36));
//(gridx,gridy)组件的左上角坐标,gridwidth,gridheight:组件占用的网格行数和列数
gridBagConstraints.gridx=col;
gridBagConstraints.gridy=row;
gridBagConstraints.gridwidth=width;
gridBagConstraints.gridheight=height;
gridBagConstraints.fill=GridBagConstraints.BOTH;// 当格子有剩余空间时,填充空间
gridBagConstraints.insets=new Insets(1, 1, 1, 1);// 组件彼此的间距
gridBagLayout.setConstraints(button, gridBagConstraints);//setConstraints()是在GridBagLayout中定义的一个方法,它接收两个参数:组件和该组件的约束
container.add(button);
}
public void calculate(double x) {
if (command.equals("+")) {
this.result += x;
} else if (this.command.equals("-")) {
this.result -= x;
} else if (this.command.equals("*")) {
this.result *= x;
} else if (this.command.equals("/")) {
this.result /= x;
} else if (this.command.equals("%")) {
this.result %= x;
} else if (this.command.equals("=")) {
this.result = x;
}
this.displayField.setText("" + this.result);
}
private class MathAction implements ActionListener {
public MathAction() {
}
public void actionPerformed(ActionEvent event){//actionPerformed是ActionListenner里面定义的一个抽象方法,重写这个方法去实现你想要进行的操作
String input = event.getActionCommand();//通过getActionCiommand获取按钮名称
// e.getSource() 返回的当前动作所指向的对象,包含对象的所有信息
// 而e.getActionCommand() 返回的是当前动作指向对象的名称
if (SimpleCalculate.this.start) {
SimpleCalculate.this.displayField.setText("");
SimpleCalculate.this.start = false;
}
if (input.equals("删除")) {
String str = SimpleCalculate.this.displayField.getText();
if (str.length() > 0) {
SimpleCalculate.this.displayField.setText(str.substring(0, str.length() - 1));
}
} else if (input.equals("清空")) {
SimpleCalculate.this.displayField.setText("0");
result=0.0d;
SimpleCalculate.this.start = true;
} else{
if (input.equals(".")) {
if (SimpleCalculate.this.displayField.getText().trim().indexOf(".") == -1) { //indexOf()检索字符串是否含有“.”,如果没有则返回-1
SimpleCalculate.this.displayField.setText(SimpleCalculate.this.displayField.getText() + input);
}
} else {
SimpleCalculate.this.displayField.setText(SimpleCalculate.this.displayField.getText() + input);
}
}
}
}
private class CommandAction implements ActionListener {
public CommandAction() {
}
public void actionPerformed(ActionEvent event){
String command = event.getActionCommand();//通过getActionCiommand获取按钮名称
if (SimpleCalculate.this.start) {
SimpleCalculate.this.command = command;
if(command.equals("-")){
SimpleCalculate.this.displayField.setText( "-");
}
} else {
SimpleCalculate.this.calculate(Double.parseDouble(SimpleCalculate.this.displayField.getText()));
SimpleCalculate.this.command = command;
SimpleCalculate.this.start = true;
}
}
}
}
通过这个项目简单了解了GridbagLayout,也发现看别人的解释及代码,都不如自己上手再敲一遍理解得深刻。
感谢一下在查资料中主要看到的这几个博客主及资料
https://blog.csdn.net/wstz_5461/article/details/78067176
https://wenku.baidu.com/view/966c58854793daef5ef7ba0d4a7302768f996f6d.html
https://www.cnblogs.com/mohanchen/p/10268821.html
https://blog.csdn.net/qq_37482202/article/details/84257553(代码参考)