Swing-布局管理器应用--WIN7上计算器的UI实现

学完了Swing布局管理器,为了加深理解我决定做一些UI的实现,那就从WIN7上的计算器开始吧!首先,我们来研究一下它的UI。该计算机的UI主要有3个,分别是标准型、科学型和程序员型,如下图所示。

 

 标准型UI

 

科学型UI

 

程序员型UI

首先分析标准型UI:

标准型UI分析

该UI除菜单栏外,分两部分。考虑到它们在不同的UI中都会复用,我们将其分别使用screenPanel和standardPanel来进行实现。screenPanel没什么好说的,使用一个按钮独占整个面板,并设置按钮文字右对齐即可。为了实现按钮的充满效果,srceenPanel需要使用BorderLayout,并将按钮位置设置为CENTER。

standardPanel则是标准的GridBagLayout样式,“MC”按钮位置为(0,0),“=”按钮独占2行1列,“0”按钮独占1行2列,其余按钮各只占1行1列。可以使用一个二维数组来定义这些键位,并在for循环中添加这些按钮。

接下来分析科学型UI:

科学型UI分析

窗体的整体布局和layout不变,而且显示部分不变,复用screePanel即可。下部为一个mainPanel,它内含scitificFunctionPanel和standardNumPanel。而scitificFunctionPanel又内含一个angelPanel。mainPanel也采用GridBagLayout,位置分别位于(0,0)和(1,0)。当然也可以采用BorderLayout,这两个子面板分别放置在WEST和CENTER,那么这样有一个问题,全屏放大后缩放比例是不一样的,如下图:

使用BorderLayout时的UI放大效果图

而使用GridBagLayout就可以保证这两个子面板的缩放是完全平等的,缩放效果如下图:

使用GridBagLayout时的UI放大效果图

接下来分析程序员型UI:

程序员型UI分析

screenPanel保持不变,而mainPanel这次被划分成3部分,分别是binaryPanel、programFunctionPanel和standardNumPanel。它们分别使用GridBagLayout来实现。

bitPanel的布局分解如下:

bitPanel布局分析

整个界面可分割为32个bitPanel;其中,第0、2行的bitPanel由4个label组成(因为每一位数均具有独立的事件响应);第1、3行的bitPanel只包含1个label。

programFunctionPanel的布局分解如下:

programFunctionPanel布局分析

可见,除(0,0)和(0,3)的位置上各为1个占据3行1列的panel外,其余位置均为1个button。Panel内包含4个combobox。

好啦,到现在所有的布局都分析完毕啦。下面是最终效果图:

标准型效果

标准型放大效果

科学型效果

科学型放大效果

程序员型效果

程序员型放大效果

具体的代码:

CalculatorUI.java

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

/*
 * 主UI
 */
public class CalculatorUI extends JFrame {
    JPanel contentPane;
    private JMenuBar menuBar = new JMenuBar();// 菜单栏
    private JButton screenButton = new JButton("0");// 结果显示栏
    String[] menuViewItemNames = { "标准型", "科学型", "程序员" };
    String[] menuNames = { "查看", "编辑", "帮助" };

    MenuItemHandler menuItemHandler = new MenuItemHandler();

    public CalculatorUI() {
        // 设置窗体属性
        setTitle("计算器");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // 添加菜单栏和菜单
        setJMenuBar(menuBar);
        for (String name : menuNames) {
            JMenu menu = new JMenu(name);
            menuBar.add(menu);
        }

        // “查看”菜单添加菜单项
        for (String name : menuViewItemNames) {
            JMenuItem menuItem = new JMenuItem(name);
            menuItem.addActionListener(menuItemHandler);
            menuBar.getMenu(0).add(menuItem);
        }
    }

    public void setBasicPane() {
        System.out.println("setBasicFrame called");
        // 设为窗体默认面板
        contentPane = new JPanel();
        contentPane.setLayout(new GridBagLayout());
        setContentPane(contentPane);

        // 添加显示按钮
        JPanel srceenPanel = new JPanel();
        srceenPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
        srceenPanel.setLayout(new BorderLayout());
        srceenPanel.add(screenButton, BorderLayout.CENTER);
        screenButton.setHorizontalAlignment(SwingConstants.RIGHT);// 文字右对齐

        // 添加显示面板
        contentPane.add(
                srceenPanel,
                new GBC(0, 0).setFill(GridBagConstraints.BOTH).setWeight(100,
                        100));
    }

    public void setStandardMode() {
        System.out.println("切换到标准型");
        setTitle("计算机-标准型");
        setBasicPane();
        StandardNumPanel standardPanel = new StandardNumPanel();
        getContentPane().add(
                standardPanel,
                new GBC(0, 1).setFill(GridBagConstraints.BOTH).setWeight(100,
                        100));
        showFrame();
    }

    public void setScitificMode() {
        System.out.println("切换到科学型");
        setTitle("计算机-科学型");
        setBasicPane();
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new GridBagLayout());
        ScitificFunctionPanel scitificFunctionPanel = new ScitificFunctionPanel();
        StandardNumPanel standardNumPanel = new StandardNumPanel();
        mainPanel.add(
                scitificFunctionPanel,
                new GBC(0, 0).setFill(GridBagConstraints.BOTH).setWeight(100,
                        100));
        mainPanel.add(
                standardNumPanel,
                new GBC(1, 0).setFill(GridBagConstraints.BOTH).setWeight(100,
                        100));
        getContentPane().add(
                mainPanel,
                new GBC(0, 1).setFill(GridBagConstraints.BOTH).setWeight(100,
                        100));
        showFrame();
    }

    public void setProgramerMode() {
        System.out.println("切换到程序员型");
        setBasicPane();
        setTitle("计算机-程序员型");
        // 添加binaryPanel
        JPanel binaryPanel = new BinaryPanel();
        getContentPane().add(
                binaryPanel,
                new GBC(0, 1).setFill(GridBagConstraints.BOTH).setWeight(100,
                        100).setInsets(5));
        //构造mainPanel,使用ProgramFunctionPanel和StandardNumPanel填充
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new GridBagLayout());
        mainPanel.add(new ProgramFunctionPanel(), new GBC(0,0).setFill(GridBagConstraints.BOTH).setWeight(100,
                        100).setInsets(5));
        mainPanel.add(new StandardNumPanel(), new GBC(1,0).setFill(GridBagConstraints.BOTH).setWeight(100,
                100).setInsets(5));
        //添加mainPanel
        getContentPane().add(
                mainPanel,
                new GBC(0, 2).setFill(GridBagConstraints.BOTH).setWeight(100,
                        100));
        showFrame();
    }

    public void calculateBinary() {

    }

    public void showFrame() {
        pack();
        setVisible(true);
    }

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

        CalculatorUI frame = new CalculatorUI();
        // frame.setScitificMode();
        frame.setProgramerMode();
        // frame.setStandardMode();
        // frame.setSize(200, 200);
        // frame.setVisible(true);
    }

    class MenuItemHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() instanceof JMenuItem) {
                JMenuItem menuItem = (JMenuItem) e.getSource();
                String name = menuItem.getText();
                if (name != null && name.equals("标准型")) {

                    setStandardMode();
                } else if (name != null && name.equals("科学型")) {
                    setScitificMode();
                } else if (name != null && name.equals("程序员")) {
                    setProgramerMode();
                    // System.out.println("切换到程序员");
                }
            }
        }
    }

    class BitButtonHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() instanceof JButton) {
                JButton button = (JButton) e.getSource();
                String text = button.getText();
                String newText = text.equals("0") ? "1" : "0";
                button.setText(newText);
                // 计算数值并更新显示屏
                calculateBinary();
            }
        }
    }
}

StandardNumPanel.java

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JPanel;

public class StandardNumPanel extends JPanel {

    public StandardNumPanel() {
        // 设置窗体layout
        setLayout(new GridBagLayout());

        // add buttons
        String[][] btnStrings = { { "MC", "MR", "MS", "M+", "M-" },
                { "←", "CE", "C", "+-", "sqrt" },
                { "7", "8", "9", "/", "%" }, { "4", "5", "6", "*", "1/x" },
                { "1", "2", "3", "-", "=" }, { "0", "0", ".", "+", "=" } };

        boolean isBtnEqualsNeedsAdded = true;
        boolean isBtnPlusNeedsAdded = true;

        for (int i = 0; i < btnStrings.length; i++) {
            for (int j = 0; j < btnStrings[0].length; j++) {
                if (btnStrings[i][j].equals("=") && isBtnEqualsNeedsAdded) {
                    add(new JButton(btnStrings[i][j]), new GBC(j, i , 1, 2)
                            .setFill(GridBagConstraints.BOTH).setInsets(3)
                            .setWeight(100, 100));
                    isBtnEqualsNeedsAdded = false;
                    continue;
                }
                if (btnStrings[i][j].equals("0") && isBtnPlusNeedsAdded) {
                    add(new JButton(btnStrings[i][j]), new GBC(j, i , 2, 1)
                            .setFill(GridBagConstraints.BOTH).setInsets(3)
                            .setWeight(100, 100));
                    isBtnPlusNeedsAdded = false;
                    continue;
                }
                add(new JButton(btnStrings[i][j]), new GBC(j, i , 1, 1)
                        .setFill(GridBagConstraints.BOTH).setInsets(3)
                        .setWeight(100, 100));
            }
        }
    }

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

ScitificFunctionPanel.java

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

public class ScitificFunctionPanel extends JPanel {

    public ScitificFunctionPanel() {
        // 设置窗体layout
        setLayout(new GridBagLayout());

        // 用于放置“度”、“弧度”、“梯度”这三个按钮
        JPanel angelPanel = new JPanel();
        BoxLayout boxLayout = new BoxLayout(angelPanel, BoxLayout.X_AXIS);
        angelPanel.setLayout(boxLayout);
        angelPanel.setBorder(BorderFactory.createEtchedBorder());
        JRadioButton angelButton = new JRadioButton("度");
        JRadioButton radianButton = new JRadioButton("弧度");
        JRadioButton gradientButton = new JRadioButton("梯度");

        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(angelButton);
        buttonGroup.add(radianButton);
        buttonGroup.add(gradientButton);

        angelPanel.add(angelButton);
        angelPanel.add(Box.createHorizontalGlue());
        angelPanel.add(radianButton);
        angelPanel.add(Box.createHorizontalGlue());
        angelPanel.add(gradientButton);

        // 添加角度面板
        add(angelPanel, new GBC(0, 0, 5, 1).setFill(GridBagConstraints.BOTH)
                .setInsets(5).setWeight(100, 100));

        // 添加按钮
        String[][] btnStrings = { { "", "Inv", "In", "(", ")" },
                { "Int", "sinh", "sin", "x^2", "n!" },
                { "dms", "cosh", "cos", "x^y", "y√x" },
                { "π", "tanh", "tan", "x^3", "3√x" },
                { "F-E", "Exp", "Mod", "log", "10^x" } };

        for (int i = 0; i < btnStrings.length; i++) {
            for (int j = 0; j < btnStrings[0].length; j++) {
                JButton button = new JButton(btnStrings[i][j]);
                add(button,
                        new GBC(j, i + 1, 1, 1)
                                .setFill(GridBagConstraints.BOTH).setInsets(5)
                                .setWeight(100, 100));
                if (i + j == 0)
                    button.setEnabled(false);
            }
        }

    }

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

    }

}

BinaryPanel.java

import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class BinaryPanel extends JPanel{

    List<JPanel> bitPanelList = new ArrayList<JPanel>();

    public BinaryPanel(){
        setLayout(new GridBagLayout());
        setBorder(BorderFactory.createEtchedBorder());
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 8; j++) {
                if (i == 0 || i == 2) {
                    // 建立一个面板并设置为左对齐的flowLayout,它容纳4个label
                    JPanel bitPanel = new JPanel();
                    FlowLayout flowLayout = new FlowLayout();
                    flowLayout.setAlignment(FlowLayout.LEFT);
                    flowLayout.setHgap(0);
                    bitPanel.setLayout(flowLayout);
                    bitPanel.setName(String.valueOf(bitPanelList.size()));
                    bitPanelList.add(bitPanel);
                    // 添加4个label
                    for (int k = 0; k < 4; k++) {
                        JLabel label = createBitLabel();
                        String buttonName = String.valueOf(k);
                        label.setName(buttonName);
                        //label.setText(buttonName);
                        bitPanel.add(label);
                        System.out.println("add createBitButton of "
                                + buttonName);

                    }
                    // 将包含4个button的小面板作为一个单元格添加到binaryPanel
                    add(bitPanel,
                            new GBC(j, i).setFill(GridBagConstraints.BOTH)
                                    .setWeight(100, 100).setInsets(5));
                } else if (i == 1) {
                    String[] texts = { "63", null, null, null, "47", null,
                            null, "     32" };
                    for (int k = 0; k < texts.length; k++) {
                        JLabel indexLabel = new JLabel();
                        if (texts[k] == null)
                            continue;
                        indexLabel.setText(texts[k]);
                        add(indexLabel,    new GBC(k, i).setFill(GridBagConstraints.BOTH)
                                        .setWeight(100, 100).setInsets(5));
                    }

                } else if (i == 3) {
                    String[] texts = { "31", null, null, null, "15", null,
                            null, "       0" };
                    for (int k = 0; k < texts.length; k++) {
                        JLabel indexLabel = new JLabel();
                        if (texts[k] == null)
                            continue;
                        indexLabel.setText(texts[k]);
                        add(indexLabel,
                                new GBC(k, i).setFill(GridBagConstraints.BOTH)
                                        .setWeight(100, 100).setInsets(5));
                    }
                }
            }
        }
    }

    private JButton createBitButton() {
        JButton bitButton = new JButton();
        bitButton.setText("0");
        bitButton.setEnabled(false);
        return bitButton;
    }

    private JLabel createBitLabel() {
        JLabel bitLabel = new JLabel();
        bitLabel.setText("0");

        // bitLabel.setEnabled(false);
        return bitLabel;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new BinaryPanel());
        frame.pack();
        frame.setVisible(true);
    }

}

ProgramFunctionPanel.java

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

public class ProgramFunctionPanel extends JPanel{

    public ProgramFunctionPanel(){
        // 设置窗体layout
        setLayout(new GridBagLayout());
        add(createRadixPanel(), new GBC(0,0, 1, 3).setWeight(100, 100).setFill(GridBagConstraints.BOTH));
        add(createBytePanel(), new GBC(0,3, 1, 3).setWeight(100, 100).setFill(GridBagConstraints.BOTH));

        String textString [][] = {
                {null, "", "Mod","A"},
                {null, "(", ")","B"},
                {null, "RoL", "RoR","C"},
                {null, "Or", "Xor","D"},
                {null, "Lsh", "Rsh","E"},
                {null, "Not", "And","F"},};

        for (int i = 0; i< textString.length; i++) {
            for (int j = 0; j< textString[i].length; j++) {
                String text = textString[i][j];
                if(text != null){
                    JButton button = new JButton(text);
                    if(text.equals(""))
                        button.setEnabled(false);
                    add(button, new GBC(j, i).setWeight(100, 100).setFill(GridBagConstraints.BOTH).setInsets(5));
                    //System.out.printf("add btn at (%d,%d)\n", j,i);
                }
            }
        }
    }

    private JPanel createRadixPanel()
    {
        JPanel radixPanel = new JPanel();

        BoxLayout boxLayout=new BoxLayout(radixPanel, BoxLayout.Y_AXIS);
        radixPanel.setLayout(boxLayout);
        radixPanel.setBorder(BorderFactory.createEtchedBorder());
        String [] radixStrings = {"十六进制", "十进制","八进制","二进制"};
        ButtonGroup btnGroup = new ButtonGroup();
        for (String radixString : radixStrings) {
            JRadioButton radioButton = new JRadioButton(radixString);
            //注册事件
            btnGroup.add(radioButton);
            radixPanel.add(radioButton);
        }
        return radixPanel;
    }

    private JPanel createBytePanel()
    {
        JPanel bytePanel = new JPanel();
        BoxLayout boxLayout=new BoxLayout(bytePanel, BoxLayout.Y_AXIS);
        bytePanel.setLayout(boxLayout);
        bytePanel.setBorder(BorderFactory.createEtchedBorder());
        String [] byteStrings = {"四字", "双字","字","字节"};
        ButtonGroup btnGroup = new ButtonGroup();
        for (String byteString : byteStrings) {
            JRadioButton radioButton = new JRadioButton(byteString);
            //注册事件
            btnGroup.add(radioButton);
            bytePanel.add(radioButton);
        }
        return bytePanel;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new ProgramFunctionPanel());
        frame.pack();
        frame.setVisible(true);
    }

}
时间: 2024-12-17 02:07:34

Swing-布局管理器应用--WIN7上计算器的UI实现的相关文章

swing布局管理器简介

转载:http://stevencjh.blog.163.com/blog/static/1218614612010101775336729/ swing布局管理器简介 一 .BorderLayout布局管理器:BorderLayout 也是一种非常简单的布局策略,它把容器内的空间简单地划分为东.西.南.北.中无个区域,没加入一个组件都应该指明把这个组件加在哪个区域中. BorderLayout是顶层容器( JFrame, JDialog, 和 JApplet )的默认布局管理器.有五个位置组件

Java Swing布局管理器GridBagLayout的使用示例 [转]

GridBagLayout是java里面最重要的布局管理器之一,可以做出很复杂的布局,可以说GridBagLayout是必须要学好的的, GridBagLayout 类是一个灵活的布局管理器,它不要求组件的大小相同便可以将组件垂直.水平或沿它们的基线对齐. 每个 GridBagLayout 对象维持一个动态的矩形单元网格,每个组件占用一个或多个这样的单元,该单元被称为显示区域. 下面就通过一个记事本案例去说明GridBagLayout的使用方法. 分析: 带有箭头的说明可以拉伸的. 4占用4个格

【Java Swing探索之路系列】之三:Java Swing布局管理器组件

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell 一 BorderLayout BorderLayout是一种简单的布局策略,可以将其看作一个组件.它把容器分为东.南.西.北.中5个区域,每个组件将占据某个区域.而 这5个区域分别被命名为NORTH, WEST, EAST, CENTER, SOUTH,它们都被定义为静态 常量.静态常量可以直接引用,如

Swing布局管理器

package cn.Douzi.Graphics; import java.awt.*; import javax.swing.*; /** * BorderLayout 演示 * 1. 继承JFrame * 2. 定义你需要的各个组件 * 3. 创建组件(构造函数) * @author Douzi * */ public class Demo_layout extends JFrame { //定义组件 JButton jb1, jb2, jb3, jb4, jb5; public stat

android v7兼容包RecyclerView的使用(三)——布局管理器的使用

前两篇文章 android v7兼容包RecyclerView的使用(二) android v7兼容包RecyclerView的使用(一) 介绍了RecyclerView的基本用法以及与它相关的重要的几个类,本篇文章介绍布局管理器的具体用法. 为了演示布局管理器的使用,找了很多个例子,都没有找到感觉合适的例子,后来google了一把,发现了一个比较适合说明问题的例子.所以就拿该例子来解释吧. 在演示布局管理器前,我们先把UI部分搭建完成.由于使用到了V7兼容包的另一个包CardView,所以在这

【Swing 2】布局管理器上

很苦逼的是,每次想记录一个小程序,发现,要给别人讲清楚,总是得分很多模块讲解. 所以今天来讲下Swing组件的三大布局管理器. 参考:<Head First Java>第十三章 1. BorderLayout--边界布局 2. FlowLayout--顺序布局 3. BoxLayout--不知道叫啥 1. BorderLayout(边界布局) 该管理器把背景分成东南西北中五大块,这是框架默认的布局管理器 1 package demo; 2 3 import javax.swing.*; 4 i

Java Swing 之流式布局管理器

/** * java 之流式布局 * @author gao */ package com.gao; import java.awt.FlowLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; @SuppressWarnings("serial") public class Flow

Java 的swing.GroupLayout布局管理器的使用方法和实例(转)

GroupLayout 是一个 LayoutManager,它将组件按层次分组,以决定它们在 Container 中的位置.GroupLayout 主要供生成器使用,但也可以手工编码.分组由 Group 类的实例来完成.GroupLayout 支持两种组.串行组 (sequential group) 按顺序一个接一个地放置其子元素.并行组 (parallel group) 能够以四种方式对齐其子元素. 每个组可以包含任意数量的元素,其中元素有 Group.Component 或间隙 (gap).

(转)Java 的swing.GroupLayout布局管理器的使用方法和实例

摘自http://www.cnblogs.com/lionden/archive/2012/12/11/grouplayout.html (转)Java 的swing.GroupLayout布局管理器的使用方法和实例 GroupLayout 是一个 LayoutManager,它将组件按层次分组,以决定它们在 Container 中的位置.GroupLayout 主要供生成器使用,但也可以手工编码.分组由 Group 类的实例来完成.GroupLayout 支持两种组.串行组 (sequenti