双按钮双事件监听机制的简单java GUI
来源:互联网 发布:nba2k16捏脸数据游侠网 编辑:程序博客网 时间:2024/05/18 10:04
写在前面:
前两篇博客我们分别介绍了简单java GUI的基本结构及事件监听机制。这一次我们将介绍双事件(多事件)监听机制,并引入内部类。
1.设计任务
设计一个GUI,包含基本组件:按钮(两个),标签(一个),随机颜色圆-面板(一个),要求点击其中一个按钮可以改变标签文字,点击另一个按钮可以改变圆的颜色,实现双事件监听。
2.任务分析
本任务的难度在于双事件如何同时监听。我们已经知道,要实现事件监听,就必须实现ActionListener接口并具体实现actionPerformed方法。但是注意对于任何一个实现ActionListener接口的类而言,只能实现一个actionPerformed方法,那么如何对两个不同的按钮实施监听并且有不同的actionPerformed方法处理呢?我们使用内部类解决这个问题。内部类的形式如下所示:
class Outer { int outer_int; class Inner { int inner_int; }
使用内部类的一个好处是在内部类中,可以直接使用外部类中的属性和方法。我们用以下代码试图实现本设计任务。
3.代码Version1
import javax.swing.*;import java.awt.*;import java.awt.event.*;public class newTwoButtons { JFrame frame; JLabel label; public static void main(String[] args) { newTwoButtons tb = new newTwoButtons(); tb.go(); } public void go() { frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); label = new JLabel("I am waiting for you!"); JButton labelButton = new JButton("Change a label"); labelButton.addActionListener(new LabelListener()); JButton circleButton = new JButton("Change a circle"); circleButton.addActionListener(new CircleListener()); MyDrawPanel myPanel = new MyDrawPanel(); frame.getContentPane().add(BorderLayout.EAST, labelButton); frame.getContentPane().add(BorderLayout.SOUTH, circleButton); frame.getContentPane().add(BorderLayout.WEST, label); frame.getContentPane().add(BorderLayout.CENTER, myPanel); frame.setSize(300, 300); frame.setVisible(true); } class LabelListener implements ActionListener { public void actionPerformed(ActionEvent event) { label.setText("OhCh!"); } } class CircleListener implements ActionListener { public void actionPerformed(ActionEvent event) { frame.repaint(); } }}class MyDrawPanel extends JPanel { public void paintComponent(Graphics g) { // this method is called every time the button is clicked g.fillRect(0, 0, this.getWidth(), this.getHeight()); int red = (int) (Math.random() * 255); int green = (int) (Math.random() * 255); int blue = (int) (Math.random() * 255); Color randomColor = new Color(red, green, blue); g.setColor(randomColor); // Set random color g.fillOval(70, 70, 100, 100); // Make a oval(circle) }}
4.结果测试
将窗口适当拉大以显示所有组件,如下图所示。
点击“change a circle”按钮,结果如下图所示:
说明“change a circle”按钮工作正常。
接下来点击“change a label”按钮,结果如下图所示:
我们看到,屏幕左方的label文字改变了,说明“change a label”按钮工作正常。不!等等!我们惊奇地发现圆形的颜色也改变了,可是我们并没有点击“change a circle”按钮啊!
为什么会这样呢?
5.问题在哪
其实,我们在尝试拉动窗口调整大小时,圆形的颜色也会改变,附图如下所示:
那么这里可以推断出当panel组件大小发生变化时(比如点击“change a label”按钮导致panel左侧区域展宽或者直接拉动窗口展宽),paintComponent函数就会执行。而我们希望的是,除了第一次生成图形之外,当且仅当点击“change a circle”按钮,才执行paintComponent函数。
6.解决方案
由以上分析我们可以初步给出一个方案:设置flag,当flag为false时不执行paintComponent函数,仅当其为true时才执行。给出代码如下所示:
7.代码Version2
import javax.swing.*;import java.awt.*;import java.awt.event.*;public class newTwoButtons { JFrame frame; JLabel label; boolean flag = false; public static void main(String[] args) { newTwoButtons tb = new newTwoButtons(); tb.go(); } public void go() { frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); label = new JLabel("I am waiting for you!"); JButton labelButton = new JButton("Change a label"); labelButton.addActionListener(new LabelListener()); JButton circleButton = new JButton("Change a circle"); circleButton.addActionListener(new CircleListener()); flag = true; MyDrawPanel myPanel = new MyDrawPanel(); frame.getContentPane().add(BorderLayout.EAST, labelButton); frame.getContentPane().add(BorderLayout.SOUTH, circleButton); frame.getContentPane().add(BorderLayout.WEST, label); frame.getContentPane().add(BorderLayout.CENTER, myPanel); frame.setSize(300, 300); frame.setVisible(true); } class LabelListener implements ActionListener { public void actionPerformed(ActionEvent event) { label.setText("OhCh!"); } } class CircleListener implements ActionListener { public void actionPerformed(ActionEvent event) { flag = true; frame.repaint(); } } class MyDrawPanel extends JPanel { public void paintComponent(Graphics g) { // this method is called every time the button is clicked g.fillRect(0, 0, this.getWidth(), this.getHeight()); if (flag == true) { int red = (int) (Math.random() * 255); int green = (int) (Math.random() * 255); int blue = (int) (Math.random() * 255); Color randomColor = new Color(red, green, blue); g.setColor(randomColor); // Set random color g.fillOval(70, 70, 100, 100); // Make a oval(circle) flag = false; } } }}
8.仍有问题?
测试发现,虽然现在只有点击按钮才能改变圆形的颜色,但是当改变窗口大小时,panel内圆形不显示(即paintComponent函数只执行了一个语句),这也并不是我们想要的结果。
9.最终方案
为了解决这个问题,我们的最终方案是使color成为公共变量,这样在扩展窗口时,依然执行paintComponent函数,但是绘图的颜色与上一次没有变化。代码如下所示:
10.代码Version3
import javax.swing.*;import java.awt.*;import java.awt.event.*;public class newTwoButtons { JFrame frame; JLabel label; boolean flag = false; int red = 0, green = 0, blue = 0; public static void main(String[] args) { newTwoButtons tb = new newTwoButtons(); tb.go(); } public void go() { frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); label = new JLabel("I am waiting for you!"); JButton labelButton = new JButton("Change a label"); labelButton.addActionListener(new LabelListener()); JButton circleButton = new JButton("Change a circle"); circleButton.addActionListener(new CircleListener()); flag = true; MyDrawPanel myPanel = new MyDrawPanel(); frame.getContentPane().add(BorderLayout.EAST, labelButton); frame.getContentPane().add(BorderLayout.SOUTH, circleButton); frame.getContentPane().add(BorderLayout.WEST, label); frame.getContentPane().add(BorderLayout.CENTER, myPanel); frame.setSize(300, 300); frame.setVisible(true); } class LabelListener implements ActionListener { public void actionPerformed(ActionEvent event) { label.setText("OhCh!"); } } class CircleListener implements ActionListener { public void actionPerformed(ActionEvent event) { flag = true; frame.repaint(); } } class MyDrawPanel extends JPanel { public void paintComponent(Graphics g) { // this method is called every time the button is clicked g.fillRect(0, 0, this.getWidth(), this.getHeight()); if (flag == true) { red = (int) (Math.random() * 255); green = (int) (Math.random() * 255); blue = (int) (Math.random() * 255); Color randomColor = new Color(red, green, blue); g.setColor(randomColor); // Set random color g.fillOval(70, 70, 100, 100); // Make a oval(circle) flag = false; } else { Color randomColor2 = new Color(red, green, blue); g.setColor(randomColor2); // Set random color g.fillOval(70, 70, 100, 100); // Make a oval(circle) } } } }
- 双按钮双事件监听机制的简单java GUI
- 带按钮监听机制的简单java GUI
- 创建图形用户界面GUI和事件监听机制的简单实现(java)
- **JAVA** GUI图形界面编程-事件监听机制
- GUI事件监听机制
- Java:简单的Swing用户界面和监听按钮点击事件
- 25-GUI-03-GUI(事件监听机制)
- JAVA基础再回首(二十七)——JAVA中的图形化界面、GUI概述、简单的窗体创建、事件监听机制、动作事件、GUI布局、鼠标事件
- 实现简单的按钮事件监听
- JAVA的事件监听机制
- Java的事件监听机制
- GUI(Frame)-(事件监听机制)-(窗体事件)
- JAVA之旅(三十一)——JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件
- GUI__【GUI概述】【布局】【Frame】【事件监听机制】【窗体事件】【按钮】【鼠标事件】【键盘事件】【Dialog对话框】【菜单】
- 按钮监听事件的实现方式【JAVA】
- java中对按钮的事件监听
- java Gui 键盘监听事件
- 黑马程序员_java GUI 事件监听机制
- sublime 安装 php xdebug
- 算法_7:动态规划
- 建造者模式
- 快速排序算法
- swift基本语法(总结提炼版)之008 swift 之字典
- 双按钮双事件监听机制的简单java GUI
- UIAutomator定位Android控件的方法实践和建议
- C#Winform在数据库中读取图片文件和上传数据文件
- Android中ScrollView嵌套ListView
- 静态代理模式
- swift基本语法(总结提炼版)之009 swift 之字符串
- 1047. 编程团体赛
- 进程管理
- db link的使用