zoukankan      html  css  js  c++  java
  • Java GUI

    java GUI

    Date: Feb. 15th, 2017
    Author: xiang

    依据毕向东老师的授课, 我组织了本文内容.

    Graphical User Interface
    Java的GUI部件在java.awt(抽象窗口工具包,需调用本地系统方法实现功能,重量级组件,不同系统窗口的样子不同)和javax.swing(基于awt,不同系统,组件的样子都一样,轻量级控件,移植性更强)两个包中。
    基本组件继承关系:

    Component (在awt里)
        |--Button
        |--Label  
        |--Checkbox 复选框
        |--TextComponent 文本部件  
            |--TextArea  内容(文本区域)
            |--TextField 标题(文本框)
        |--Container  容器
            |--Panel  面板(窗体的一部分,不能独立存在)
            |--Window 窗体(能独立存在)
                |--Frame  框架
                |--Dialog 对话框(当当弹出来的)
                    |--FileDialog(文件选取对话框)
    

    Layout 布局

    容器中组件的排放方式,是布局

    • FlowLayout 流式布局
      • 左到右
      • Panel的默认布局
    • BorderLayout 边界布局
      • 东南西北中
      • Frame的默认布局
    • GradeLayout 网格布局
    • CardLayout 卡片布局(选项卡)
    • GridBagLayout 网格包布局

    e.g.

    public class FrameDemo {
    	public static void main(String[] args) {
    		// 1. 创建窗体 最初不可见的Frame对象
    		Frame f = new Frame("My frame");
    
    		//f.setSize(500, 400); 	//横轴,纵轴		
    		//f.setLocation(400, 150); // 窗体出现的位置
    
    		// 2. 设置各种边界,位置,布局
    		f.setBounds(400, 200, 500, 400); //代表上面两句		
    
    		f.setLayout(new FlowLayout()); //设置流式布局
    
    		// 3. 创建并添加组件
    		Button but = new Button("一个按钮");
    
    		f.add(but); // 大按钮,Frame对象默认"BorderLayout"
    
    		// 4. 设置可见
    		f.setVisible(true);
    		System.out.println("over");
    	}
    }
    

    事件监听机制

    • 事件源(组件)
    • 事件(Event)
    • 监听器(Listener)
    • 事件处理(引发事件后处理方式)

    主人公: 小强 <-------------保镖 保护小强,主管小强 拳打(被拳打){} 脚踢(被脚踢){踢回}
    事儿: 被揍(拳打,脚踢)

    拳头(外力),打小强,被揍事发生在小强身上。

    事件源: 小强
    事件: 事情儿,有些事儿在小强身上无法发生
    监听器: 保镖, 可能保护多人, 发生了被打的事,应传到保镖这
    处理方式: 拳打(被拳打){挡住} 脚踢(被脚踢){踢回}

    窗体监听

    CAUSION: 窗体监听 addWindowListener()

    public class FrameDemo {
    	public static void main(String[] args) {
    		Frame f = new Frame("My frame");
    		f.setBounds(400, 200, 500, 400);
    		f.setLayout(new FlowLayout());
    
    		Button but = new Button("一个按钮");
    		f.add(but);
    
    		//CAUSION: addWindowListener() 窗体监听
    		// 请个啥样的保镖?
    		f.addWindowListener(new WindowAdapter() {
    
    			@Override
    			public void windowClosing(WindowEvent e) {
    				// 这很像异常处理,catch(e){}自动接收try{}中引发的异常对象
    				System.out.println("closing......" + e);
    				System.exit(0); // 关窗体
    			}
    		});
    
    		f.setVisible(true);
    		System.out.println("over");
    	}
    }
    

    按钮监听

    CAUSION: 按钮监听 addActionListener()
    在上述代码,窗体监听器后,添加如下代码:
    通常addXxxListener(new XxxListener(){{要覆盖的方法}})

    // 按钮上加一个监听。
    but.addActionListener(new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    });
    

    鼠标监听

    CAUSION: 鼠标监听 addMouseListener()

    鼠标事件:按下,释放,单击,进入 或 离开
    下面代码提到的:

    • 按钮同时有action和click两种监听,谁先被触发? 答:click先触发
    • 双击按钮,这事件,代码咋写?
    
    /**
     * 鼠标键盘监听示例
     */
    public class MouseAndKeyboardDemo {
    
    	private Frame f;
    	private TextField tf;
    	private Button but;
    
    	// alt shift s
    	public MouseAndKeyboardDemo() {
    		init();
    	}
    
    	private void init() {
    		f = new Frame("演示鼠标和键盘监听");
    		f.setBounds(400, 200, 500, 400);
    		f.setLayout(new FlowLayout());
    
    		tf = new TextField(35);
    		but = new Button("一个按钮");
    		f.add(tf);
    		f.add(but);
    
    		myEvent(); // 添加事件监听
    
    		f.setVisible(true);
    	}
    
    	private void myEvent() {
    
    		// 给Frame对象添加 “关窗体监听”
    		f.addWindowListener(new WindowAdapter() {
    
    			@Override
    			public void windowClosing(WindowEvent e) {
    				System.exit(0);
    			}
    		});
    
    		// 实验: 按钮同时有action和click两种监听,谁先被触发?
    		// 答: click先被触发
    		// but.addActionListener(new ActionListener() {
    		//
    		// @Override
    		// public void actionPerformed(ActionEvent e) {
    		// System.out.println("action done");
    		// }
    		// });
    
    		// 鼠标事件:按下,释放,单击,进入 或 离开
    		// 要在 按钮上添加一个鼠标监听
    		but.addMouseListener(new MouseAdapter() {
    
    			private int count = 1;
    
    			@Override
    			public void mouseEntered(MouseEvent e) {
    				// System.out.println("我进");
    				// tf.setText("我进..." + this.count++);
    			}
    
    			@Override
    			public void mouseClicked(MouseEvent e) {
    				// 双击按钮, 这种事件,代码咋写
    				if (e.getClickCount() == 2)
    					tf.setText("我点..." + this.count++);
    				// System.out.println("click done"+count++);
    			}
    
    		});
    	}
    
    	public static void main(String[] args) {
    		new MouseAndKeyboardDemo();
    	}
    }
    

    键盘监听

    CAUSION: 键盘监听 addKeyListener()
    在上述代码的myEvent()里添加如下代码:
    下面代码展示了:

    • 记录键盘按键
    • 只识别键盘的数字,不认别的键,咋办?
    • ctrl + enter 咋办?
    // 给文本框添加键盘监听
    // 1.确定事件源
    // 2.确定事件和监听器
    // 3.确定具体动作,并把要设定的内容写入该动作所示的方法体
    
    tf.addKeyListener(new KeyAdapter() {
    
      @Override
      public void keyPressed(KeyEvent e) {
        // 1. 记录键盘按键
        // System.out.println("keyboard..."+e.getKeyChar()+"..."+e.getKeyCode());
        // 展示shift ^^
        // System.out.println("keyboard..." +
        // KeyEvent.getKeyText(e.getKeyCode()) + "..." +
        // e.getKeyCode());
        //
        // 2. 只认数字,不认别的键,咋办?
        // int code = e.getKeyCode();
        // if(!(code>=KeyEvent.VK_0 && code<=KeyEvent.VK_9)){
        // System.out.println("必须是数字");
        // e.consume(); //不起作用
        // }
    
        // 3. ctrl + enter 咋办??
        if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) {
          System.out.println("enter run...");
        }
      }
    });
    

    向Eclipse安装swing插件

    http://jingyan.baidu.com/album/4853e1e57194641909f7269f.html?picindex=1
    步骤:

    1. 查看自己的Eclipse版本: 点击elcipse界面下拉菜单的 help->about eclipse
    2. 百度搜索 "windowbuilder", 进入第一个搜索结果
    3. 进入界面,点 "Download"
    4. 选对应版本,点"Link"
    5. 进入界面,复制浏览器地址栏中的地址
    6. 打开Eclipse-Help-Install new Software
    7. 将刚才复制的地址粘贴到work with中。并选中下面的多个选项(不同Eclipse版本,选项个数不同,都选上)
    8. 点击各种next, “同意”, finish (中间大约7分钟安装下载时间)
    9. 重启动Eclipse
    10. 重启之后在新建里出现“WindowBuilder”说明安装成功

    小例子

    e.g.:

    public class JFrameDemo extends JFrame {
    	private JPanel contentPane;
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					JFrameDemo frame = new JFrameDemo();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    	public JFrameDemo() {
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setBounds(100, 100, 450, 300);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		setContentPane(contentPane);
    		contentPane.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
    
    		JButton button = new JButton("退出");
    		button.addMouseListener(new MouseAdapter() {
    			@Override
    			public void mouseClicked(MouseEvent e) {
    				System.exit(0);
    			}
    		});
    		contentPane.add(button);
    	}
    }
    
    

    再来一个例子,实现c:一回车

    public class MyWindow extends JFrame {
    
    	protected static final String LINE_SEPARATOR = System.getProperty("line.separator");
    	private JPanel contentPane;
    	private JTextField textField;
    	private JTextArea textArea;
    	private JButton btnNewButton;
    
    	/**
    	 * Launch the application.
    	 */
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					MyWindow frame = new MyWindow();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    
    	/**
    	 * Create the frame.
    	 */
    	public MyWindow() {
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setBounds(100, 100, 597, 461);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		setContentPane(contentPane);
    		contentPane.setLayout(null);
    
    		textField = new JTextField();
    		textField.setBounds(12, 23, 392, 21);
    		contentPane.add(textField);
    		textField.setColumns(10);
    		textArea = new JTextArea();
    		textArea.setBounds(12, 95, 573, 297);
    		contentPane.add(textArea);
    
    		btnNewButton = new JButton("转到");
    		btnNewButton.setBounds(439, 20, 107, 27);
    		contentPane.add(btnNewButton);
    
    		textField.addKeyListener(new KeyAdapter() {
    			@Override
    			public void keyPressed(KeyEvent e) {
    
    				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
    					showDir();
    				}
    			}
    		});
    
    		btnNewButton.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				showDir();
    			}
    		});
    	}
    
    	protected void showDir() {
    		/*
    		 * 通过点击按钮,获取文本框中目录, 将目录中的内容显示在文本区域中。
    		 */
    		String dir_str = textField.getText();
    		File dir = new File(dir_str);
    
    		if (dir.exists() && dir.isDirectory()) {
    			// textArea.setText("is directory");
    			textArea.setText("");
    			String[] names = dir.list();
    			for (String name : names) {
    				textArea.append(name + LINE_SEPARATOR);
    			}
    		}
    	}
    }
    

    添加滚动条

    针对上面代码,删掉Jpanl容器,取而代之的添加JScrollPane容器,在它上面添加JTextArea组件。如下:

    public class MyWindow extends JFrame {
    
    	protected static final String LINE_SEPARATOR = System.getProperty("line.separator");
    	private JPanel contentPane;
    	private JTextField textField;
    	private JButton btnNewButton;
    	private JTextArea textArea;
    
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					MyWindow frame = new MyWindow();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    
    	public MyWindow() {
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setBounds(100, 100, 597, 461);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		setContentPane(contentPane);
    		contentPane.setLayout(null);
    
    		textField = new JTextField();
    		textField.setBounds(12, 23, 392, 21);
    		contentPane.add(textField);
    		textField.setColumns(10);
    
    		btnNewButton = new JButton("转到");
    		btnNewButton.setBounds(439, 20, 107, 27);
    		contentPane.add(btnNewButton);
    
    		JScrollPane scrollPane = new JScrollPane();
    		scrollPane.setBounds(12, 80, 534, 309);
    		contentPane.add(scrollPane);
    
    		textArea = new JTextArea();
    		scrollPane.setViewportView(textArea);
    
    		textField.addKeyListener(new KeyAdapter() {
    			@Override
    			public void keyPressed(KeyEvent e) {
    
    				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
    					showDir();
    				}
    			}
    		});
    
    		btnNewButton.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				showDir();
    			}
    		});
    	}
    
    	protected void showDir() {
    		/*
    		 * 通过点击按钮,获取文本框中目录, 将目录中的内容显示在文本区域中。
    		 */
    		String dir_str = textField.getText();
    		File dir = new File(dir_str);
    
    		if (dir.exists() && dir.isDirectory()) {
    			// textArea.setText("is directory");
    			textArea.setText("");
    			String[] names = dir.list();
    			for (String name : names) {
    				textArea.append(name + LINE_SEPARATOR);
    			}
    		}
    	}
    }
    

    添加下拉菜单 Menu

    • JMenuBar
    • JMenuBar上添加JMenu
    • JMenu上添加JMenuItem

    06 gui 14:04

  • 相关阅读:
    android添加群组源码
    onItemClickListener不起作用解决办法2(原创)
    Android中layout过程详解
    android上一些方法的区别和用法的注意事项 (转载)
    Android中mesure过程详解
    AlertDialog dismiss 和 cancel方法的区别
    按Notification 回到正在运行的activity
    android添加联系人源码
    Use Eclipse
    数据区的内存模型
  • 原文地址:https://www.cnblogs.com/ZhongliangXiang/p/7357190.html
Copyright © 2011-2022 走看看