模拟ATM课设小结

小结

这算是我第一个比较完整的项目吧,虽然项目不大,但还是有所收获,发现了一些之前未知的工具、领域以及方法。在最后答辩的时候,发现了更好的写前端的方式(JavaFX)。本次我自己总的缺点有: 类的设计不够好,不能很好地使用抽象类,造成复用和维护的复杂性比较高,还有界面之间的切换不够滑畅。界面的图片和按钮以及风格设计做起来虽然有趣,但是太累了。要好好学下设计模式。

部分效果图

先上部分效果图(我做的是管理员模块):

管理员主菜单界面

开户界面

冻结界面

查询交易界面

下面写一些设计界面的细节
描述1:JFrame去掉窗口修饰,增加背景图片,并且还能继续拖动窗口。

package test;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

/**
 * @Title: JFrameDemo.java 
 * @Package test 
 * @Description: JFrame去掉窗口修饰,增加背景图片,并且还能继续拖动窗口。
 * @author Cqh_i
 * @date 2018年10月31日 下午6:59:07   
 */
public class JFrameDemo extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JPanel imagePanel;//用来指向内容窗格
    //用于处理拖动事件
    int xOld = 0;//表示鼠标按下时的x坐标,相对于JFrameDemo
    int yOld = 0;//表示鼠标按下时的y坐标,相对于JFrameDemo

    public JFrameDemo() {
        /*
         * 实现窗口拖动事件
         */
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                //按住鼠标按住时,记下旧坐标(相对于JFrameDemo)
                xOld = e.getX();
                yOld = e.getY();
            }
        });
        this.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                //按住鼠标按键并移动鼠标时,记下鼠标坐标
                int xOnScreen = e.getXOnScreen();//相对于屏幕的x坐标
                int yOnScreen = e.getYOnScreen();//相对于屏幕的y坐标
                int xNew = xOnScreen - xOld;
                int yNew = yOnScreen - yOld;
                JFrameDemo.this.setLocation(xNew, yNew);
            }
        });
        
        /*
         * JFrame增加背景图片
         */
        ImageIcon background = new ImageIcon("image/Dog.png");// 背景图片图像图标
        JLabel label = new JLabel(background);// 把背景图片显示在一个标签里面
        //把标签的大小位置设置为图片刚好填充整个面板
        label.setBounds(0, 0, background.getIconWidth(), background.getIconHeight());
        //把内容窗格转化为JPanel,否则不能用方法setOpaque()来使内容窗格透明
        imagePanel = (JPanel) this.getContentPane();
        imagePanel.setOpaque(false);
        //内容窗格默认的布局管理器为null
        imagePanel.setLayout(null);
        this.getLayeredPane().setLayout(null);
        //把背景图片添加到分层窗格的最底层作为背景
        this.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
        
        
        this.setUndecorated(true);// 去掉窗口的装饰
        setSize(588, 588);
        setLocationRelativeTo(null);// 窗口居中
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new JFrameDemo();
    }
}

结构如下:

运行结果:

描述2:鼠标移动到组件(JButton、JPanel)上,改变样式(改变背景)。 

        我这次用的方法有点简单粗暴,但依然有效。图片采用png格式,因为png格式支持透明格式,然后把JButton的背景也设置为透明,同样,这种方法对JPanel也有效,这样你想要有什么形状的图片都可以了,但是需要指出的是,虽然是透明的,但是它的边角却是实实在在存在的。我这次样式的选择有反相、发光处理等,也可以在按钮不同状态设置按钮在不同的位置,来展现点击感。
        填坑:为了按钮的实际范围仅在图片的非透明区域(不包括透明的边角),需要重写组件中的contains方法。
        先看看自定义的JPanel和JButton效果。

package button;

import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * @Title: ButtonPanel.java 
 * @Package button 
 * @Description: 自定义的JPanel, 鼠标经过时更换背景图片,JPanel的形状取决于图片的形状
 * @author Cqh_i   
 */
public class ButtonPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private ImageIcon icon1;// 要变换的图片1
    private ImageIcon icon2;// 要变换的图片2
    // 下面的三个变量用于处理透明区域
    private BufferedImage bi;
    private int rgb, alpha;
    private boolean isEntered = false; // 鼠标是否在组件里
    private boolean isFirstCreated = true;// 是否是首次绘制的

    public ButtonPanel(String path1, String path2) {
        icon1 = new ImageIcon(path1);
        icon2 = new ImageIcon(path2);
        try {
            bi = ImageIO.read(new File(path1));
        } catch (IOException e) {
            e.printStackTrace();
        }
        addListener();
        setLayout(null);
        setOpaque(false); // 把panel的背景色设为透明
    }

    @Override
    public void paintComponent(Graphics g) {
        int x = 0, y = 0;
        // g.drawImage(icon.getImage(), x, y, getSize().width, getSize().height,
        // this);// 图片会自动缩放
        // g.drawImage(icon1.getImage(), x, y,this);//图片不会自动缩放
        if (isFirstCreated) {
            g.drawImage(icon1.getImage(), x, y, this);
            isFirstCreated = false;
        } else if (isEntered) {
            g.drawImage(icon2.getImage(), x, y, this);
        } else {
            g.drawImage(icon1.getImage(), x, y, this);
        }
    }

    /**
     * 设置按钮点击范围仅在图片的非透明区域。
     */
    @Override
    public boolean contains(int x, int y) {
        try {
            rgb = bi.getRGB(x, y);
            alpha = (rgb >> 24) & 0xFF;
            if (alpha == 0) {
                return false;
            } else {
                return true;
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            // 当搜索到透明区域时,就getRGB抛出下表越界异常
            return false;
        }
    }

    public void addListener() {
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                JOptionPane.showMessageDialog(ButtonPanel.this, "你点击了自定义的JPanel!", "提示", JOptionPane.INFORMATION_MESSAGE);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                isEntered = false;
                repaint();
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                isEntered = true;
                repaint();
            }
        });
    }
}
package button;

import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;

/**
 * @Title: MyButton.java 
 * @Package button 
 * @Description: 自定义的JButton, 鼠标点击时改变图片的位置,JButton的形状取决于图片的形状
 * @author Cqh_i  
 */
public class MyButton extends JButton {

    private static final long serialVersionUID = 1L;
    private ImageIcon icon;// 背景图片
    // 下面的三个变量用于处理透明区域
    private BufferedImage bi;
    private int rgb, alpha;

    public MyButton(String path) {
        this.icon = new ImageIcon(MyButton.class.getResource(path));
        setContentAreaFilled(false);// 按钮设置为透明
        setBorderPainted(false);// 去掉按钮的边框的设置
        setSize(icon.getIconWidth(), icon.getIconHeight());
        try {
            bi = ImageIO.read(MyButton.class.getResource(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        addListener();
    }

    @Override
    public void paintComponent(Graphics g) {
        // 在按钮不同状态设置按钮在不同的位置,可以体现出点击感
        if (this.getModel().isPressed()) {
            g.drawImage(icon.getImage(), 2, 2, this);
        } else {
            g.drawImage(icon.getImage(), 0, 0, this);
        }
    }

    /**
     * 设置按钮点击范围仅在图片的非透明区域。
     */
    @Override
    public boolean contains(int x, int y) {
        try {
            rgb = bi.getRGB(x, y);
            alpha = (rgb >> 24) & 0xFF;
            if (alpha == 0) {
                return false;
            } else {
                return true;
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            // 当搜索到透明区域时,就getRGB抛出下表越界异常
            return false;
        }
    }

    public void addListener() {
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseEntered(e);
                JOptionPane.showMessageDialog(MyButton.this, "你点击了自定义的JButton!", "提示", JOptionPane.INFORMATION_MESSAGE);
            }
        });
    }
}
package button;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
 
/**
 * @Title: ButtonPanelDemo.java 
 * @Package test 
 * @Description: 测试自定义的JButton和自定义的JPanel
 * @author Cqh_i
 * @date 2018年10月31日22:23:05
 */
public class ButtonPanelDemo extends JFrame {
 
    private static final long serialVersionUID = 1L;
 
    public ButtonPanelDemo() {
        
        JLabel Label1 = new JLabel("这是一个自定义的JButton");
        Label1.setBounds(273, 13, 178, 18);
        getContentPane().add(Label1);
        
        /*
         * 按钮JButton部分
         */
        JButton ResetButton = new MyButton("WhiteBack.png");
        ResetButton.setLocation(311, 32);
        getContentPane().add(ResetButton);
        /*
         * JPanel部分
         */
        ButtonPanel HomePanel = new ButtonPanel("WhiteBack.png","BlackArrowBack.png");
        HomePanel.setBounds(67, 32, 114, 114);
        getContentPane().add(HomePanel);
        
        JLabel lblNewLabel = new JLabel("这是一个自定义的JPanel");
        lblNewLabel.setBounds(37, 13, 175, 18);
        getContentPane().add(lblNewLabel);
        
        getContentPane().setLayout(null);
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(500,300);
        setLocationRelativeTo(null);// 窗口居中
        setTitle("Demo make by Cqh_i");
    }
    
    public static void main(String[] args) {
        new ButtonPanelDemo();
    }
}

 描述3:动态检测输入框的内容,给出相应信息,主要是实现在删除和添加字符时监听。

package test;

import java.awt.Color;
import java.awt.Font;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

/**
 * @Title: ButtonPanelDemo.java 
 * @Package test 
 * @Description: 动态检测输入框的内容,给出相应信息。
 * 这里以输入数字为有效字符,其他字符无效,19位号码为有效号码
 * @author Cqh_i
 */
public class CheckTextDemo extends JFrame {

    private static final long serialVersionUID = 1L;
    private JTextField cardnumber_text;
    private JLabel HintCardNumberInfo;
    private boolean isCardNumberValid;// 卡号输入是否合法

    public CheckTextDemo() {
        HintCardNumberInfo = new JLabel();
        HintCardNumberInfo.setForeground(Color.BLACK);
        HintCardNumberInfo.setBounds(250, 70, 72, 18);

        cardnumber_text = new JTextField();
        cardnumber_text.setToolTipText("");
        cardnumber_text.setFont(new Font("宋体", Font.BOLD, 18));
        cardnumber_text.setBounds(41, 66, 206, 30);
        cardnumber_text.setColumns(10);

        /*
         * 利用Document实现动态监听
         */
        Document doc = cardnumber_text.getDocument();
        doc.addDocumentListener(new DocumentListener() {
            @Override
            public void changedUpdate(DocumentEvent e) {
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                if (cardnumber_text.isEditable() == true) {
                    try {
                        String str = doc.getText(0, doc.getLength());
                        isCardNumberValid = true;
                        for (int i = 0; i < str.length(); i++) {
                            if (str.charAt(i) < '0' || str.charAt(i) > '9') {
                                HintCardNumberInfo.setText("无效的字符");
                                isCardNumberValid = false;
                                break;
                            }
                            if (isCardNumberValid && str.length() > 0 && str.length() < 19) {
                                isCardNumberValid = false;
                                HintCardNumberInfo.setText("小于19位");
                            }
                            if (isCardNumberValid && str.length() > 19) {
                                isCardNumberValid = false;
                                HintCardNumberInfo.setText("大于19位");
                            }
                        }
                        if (isCardNumberValid && str.length() == 19) {
                            HintCardNumberInfo.setText("");
                        }
                        if (str.length() == 0) {
                            HintCardNumberInfo.setText("");
                        }
                    } catch (BadLocationException e1) {
                        e1.printStackTrace();
                    }
                }
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                insertUpdate(e);
            }
        });
        getContentPane().setLayout(null);
        getContentPane().add(cardnumber_text);
        getContentPane().add(HintCardNumberInfo);

        JLabel lblNewLabel = new JLabel("请输入待检测内容");
        lblNewLabel.setBounds(41, 35, 144, 18);
        getContentPane().add(lblNewLabel);
        setSize(400, 300);
        setLocationRelativeTo(null);// 窗口居中
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setTitle("Demo make by Cqh_i");
    }

    public static void main(String[] args) {
        new CheckTextDemo();
    }
}

运行结果:

Java Swing中还有一个类JFormattedTextField,可以对输入文本框做出一些限制,有些轮子就不必重复造了,JFormattedTextField的使用见JFormattedTextField使用心得

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值