Java GUI设计概述

来源:互联网 发布:by是什么网络语 编辑:程序博客网 时间:2024/05/21 18:00

之前本科课程学习Java,大半个学期在讲前五章的类和面向对象的概念,之后就是第六章Java GUI设计。加之当时第一个接触程序设计语言实现GUI(之前的C语言没有这些),就晕菜了,而后又是java非常重要的几个概念和应用:流和文件,多线程,网络编程,数据库编程,servlet技术和JSP技术。因为中间的GUI设计已经让我失去上课的兴趣,之后的这些重要概念和技术到大四的时候才开始捡起来再学,都堪称Java必备经典 ----  两年后我才在《Java核心技术卷 I》上看到“如果只想用Java编写服务器端的应用程序,对GUI编程不感兴趣,可以跳过这几章(图形程序设计,事件处理,Swing用户界面组件)”。 悲催。。。

吐槽完毕。

一:简单的图形程序设计(不涉及事件处理)

一般来说就是设计一个扩展了 JFrame 的类( class SimpleFrame extends JFrame),在这个类的实例化方法中用setTitle、setBounds、setSize等方法设置框架的标题位置大小等信息,具体可以到JFrame类中。

      JFrame的结构画图来说确实有点复杂(详见《Java核心技术卷 I》P250),但是可以简单的把JFrame就当做一个框架,上面的标题栏,下面的大片空白区域就是内容窗格,这也是程序员最关心的部分。通过 frame.add() 方法可以加入很多元素,button, panel等。 可以有层层叠加,JButton添加到JPanel中,然后再将JPanel添加到JFrame中等。另外对需要将一个绘制消息的组件添加大框架中的话,绘制一个组件,这个组件是一个扩展了JComponent的类,并且覆盖了JComponent类中的paintComponent方法。 这个方法中有一个 Graphics 类型的参数,保存了用语绘制图像和文本的设置(字体颜色等)。 在java中,所有的绘制都必须使用 Graphics 对象。

class DrawFrame extends JFrame{private static final int DEFAULT_WIDTH = 400;private static final int DEFAULT_HEIGHT = 400;public DrawFrame(){setTitle("DrawTest");setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);DrawComponent component = new DrawComponent();add(component);}}class DrawComponent extends JComponent{public void paintComponent(Graphics g){Graphics2D g2 = (Graphics2D)g;double leftx = 100;double topy = 100;double width = 200;double height = 150;Rectangle2D rect = new Rectangle2D.Double(leftx, topy, width, height);g2.draw(rect);Ellipse2D ellipse = new Ellipse2D.Double();ellipse.setFrame(rect);g2.draw(ellipse);g2.draw(new Line2D.Double(leftx, topy, leftx+width, topy+height));double centerx = rect.getCenterX();double centery = rect.getCenterY();double radius = 150;Ellipse2D circle = new Ellipse2D.Double();circle.setFrameFromCenter(centerx, centery, centerx+radius, centery+radius);g2.draw(circle);}}

二、事件处理

这也是Java GUI设计的核心,java事件处理采用的是事件委托模型。关键是理解三个对象: 事件对象,监听器对象,事件源(对象)。

事件对象: java是将事件的相关信息封装在一个事件对象中,所有的事件对象都派生于java.util.EventObject类,当然每个事件类型还有子类,如ActionEvent和WindowEvent,类的继承关系如下图


ActionEvent:指示发生了组件定义的动作的语义事件。当特定于组件的动作(比如被按下)发生时,由组件(比如 Button)生成此高级别事件。事件被传递给每一个ActionListener 对象,这些对象是使用组件的 addActionListener 方法注册的,用以接收这类事件。 

WindowEvent:指示窗口状态改变的低级别事件。当打开、关闭、激活、停用、图标化或取消图标化 Window 对象时,或者焦点转移到 Window 内或移出 Window 时,由 Window 对象生成此低级别事件。 该事件被传递给每一个使用窗口的 addWindowListener 方法注册以接收这种事件的 WindowListener 或 WindowAdapter 对象。


       监听器对象:是一个实现了特定接听器接口的类的实例; //类定义:class ColorAction implements ActionListener{},必须实现接听接口ActionListener中的public void actionPerformed(ActionEvent event)方法; 事件处理的核心就是把监听器类写好。

     事件源对象:是一个能够注册监听器对象并发送事件对象的对象。// 前面事件源如果是一个button, 用button.addActionListener(new ColorAction)即可完成监听器对象在事件源中的注册;

    那么上面三个对象之间的关系就组成了java AWT事件处理的机制:

  • 监听器对象是一个实现了特定监听器接口的类的实例;
  • 事件源是一个能够注册监听器对象并发送事件对象的对象;
  • 当事件发生时,事件源将事件对象传递给所有注册的监听器;
  • 监听器对象将利用事件对象中的信息决定如何对事件作出响应;
import java.awt.Color;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;public class ButtonTest {public static void main(String[] args){ButtonFrame frame = new ButtonFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}}class ButtonFrame extends JFrame{private JPanel buttonPanel;public static final int DEFAULT_WIDTH = 300;public static final int DEFAULT_HEIGHT = 200;public ButtonFrame(){setTitle("ButtonTest");setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);buttonPanel = new JPanel();//makeButton("red", Color.RED);JButton  yellowButton = new JButton("YellowButton"); JButton  blueButton = new JButton("Blue");JButton  redButton = new JButton("Red");buttonPanel = new JPanel();buttonPanel.add(yellowButton);buttonPanel.add(blueButton);buttonPanel.add(redButton);add(buttonPanel);ColorAction yellowAction = new ColorAction(Color.YELLOW);ColorAction blueAction = new ColorAction(Color.BLUE);ColorAction redAction = new ColorAction(Color.RED);yellowButton.addActionListener(yellowAction);blueButton.addActionListener(blueAction);redButton.addActionListener(redAction);}private class ColorAction implements ActionListener{private Color backgroudColor;public ColorAction(Color c){backgroudColor = c;}public void actionPerformed(ActionEvent event){buttonPanel.setBackground(backgroudColor);}}public void makeButton(String name, final Color backgroundColor){JButton button = new JButton(name);buttonPanel.add(button);button.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent event){buttonPanel.setBackground(backgroundColor);}});}

三:Swing用户界面组件

这个主要是掌握在类的设计时一种设计模式思想:MVC即模型-视图-控制器模式。另外理解不同布局管理器的特点。各个界面组件(文本输入、单复选按钮/框、菜单、对话框等)可以参考《java核心技术卷 I》都有详细的例子。

      下面贴一个简单计算器的实现,主要是布局管理器的练习:

import java.awt.BorderLayout;import java.awt.DisplayMode;import java.awt.GridLayout;import java.awt.Label;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;//Demo 主要是练习java GUI设计几种布局管理器的使用public class Calculator {public static void main(String[] args){CalculatorFrame frame = new CalculatorFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}}class CalculatorFrame extends JFrame{public CalculatorFrame(){setTitle("Calculator");CalculatorJPanel panel = new CalculatorJPanel();add(panel);pack(); // 调整此窗口的大小,以适合其子组件的首选大小和布局。}}class CalculatorJPanel extends JPanel{private JButton display;private JPanel panel;private double result;private String lastcommand;private boolean start;public CalculatorJPanel(){setLayout(new BorderLayout());result = 0;lastcommand = "=";start = true;//add displaydisplay = new JButton("0");display.setEnabled(false);  //add(display, BorderLayout.NORTH);ActionListener insert = new insertAction();ActionListener command = new commandAction();//add the button in a 4*4 gridpanel = new JPanel();  panel.setLayout(new GridLayout(4, 4));addButton("1", insert);addButton("2", insert);addButton("3", insert);addButton("4", insert);addButton("5", insert);addButton("6", insert);addButton("7", insert);addButton("8", insert);addButton("9", insert);addButton("0", insert);addButton("+", command);addButton("-", command);addButton("*", command);addButton("/", command);addButton("=", command);addButton(".", insert);add(panel, BorderLayout.CENTER);}private void addButton(String lable, ActionListener listener){JButton button = new JButton(lable);button.addActionListener(listener);panel.add(button);}private class insertAction implements ActionListener //定义监听器类,监听输入数字和小数点{public void actionPerformed(ActionEvent event){String input = event.getActionCommand();if(start){display.setText("");start = false;}display.setText(display.getText() + input);}}private class commandAction implements ActionListener //定义监听器类,监听输入运算符和负号{public void actionPerformed(ActionEvent event){String command = event.getActionCommand();if(start){if(command.equals("-"))  //  负号{display.setText(command);start = false;}else {lastcommand = command;}}else {calculate(Double.parseDouble(display.getText()));lastcommand = command;start = true;}}}public void calculate(double x){if(lastcommand.equals("+"))result += x;else if (lastcommand.equals("-")) {result -= x;}else if (lastcommand.equals("*")) {result *= x;}else if (lastcommand.equals("/")) {result /= x;}else if (lastcommand.equals("=")) {result = x;}display.setText("" + result);}}

    

      

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 成都车牌网上选号次数用完了怎么办 在志愿服务中遇到突发状况怎么办 商铺没有房产证不能办理消防怎么办 亳州办事大厅登录密码忘记了怎么办 户口已迁出结婚证丢了怎么办 户口已迁出多年结婚证丢了怎么办 芜湖长信正式工没转正怎么办辞职 买到9个月库存车怎么办 买到5个月库存车怎么办 把4s店新车撞了怎么办 网址导航已取消打不开网页是怎么办 如果邦华手机充电口有杂物怎么办? 当发生灾害或突发事故时怎么办 物流信息和和收货地址不一样怎么办 小孩手被电梯门夹了怎么办 车管所50选一没看中的号码怎么办 长沙芙蓉区电动车被交警扣了怎么办 驾照正在考的时候住址变了怎么办 身份证到期了驾驶证上的号码怎么办 小车占道跟大车刮交警怎么办 邻居把消防栓的位置占用了怎么办 查环保要停业整改一个月怎么办 抽油烟机管道公共排烟道漏烟怎么办 深圳龙华电动车被交警扣了怎么办 英国平邮寄到中国丢件怎么办 安卓app与设备不兼容怎么办 手机卡坏了收不到快递短信怎么办 pph手术后钛钉没有脱落怎么办 右侧附件囊状透明声可怎么办 刚刚出生小孩睾丸没有掉下来怎么办 汽车被依非法营运之由扣押怎么办 老婆结婚小孩两个又上夜场该怎么办 对于不断无理要求赔偿的房东怎么办 欠的钱越来越多不知道怎么办了 手机壳的开机按键不好按怎么办 对方把保权的房子卖给我怎么办 内存卡在手机上显示损坏怎么办 内存卡显示但是下载不了东西怎么办 相机sd卡没办法读卡怎么办 尼康相机新sd卡显示满了怎么办 修冰箱没几个月又坏了怎么办