Java-图形界面-在获得事件时绘制图形-多重监听-内部类

140 阅读2分钟

GUI的布局:frame默认有5个区域可以安置widget。

每个区域只能安置一项,但是别担心!该项目可以是能够安置包括面板在内的3项东西的面板,所以你可以在面板上放面板。 明确指定加到默认content panel上的位置时比较好的方式。

单一参数的add()方法会自动地把widget加到中心区域

frame.getContentPane().add(button);

两个参数的add()方法可以指定使用的区域

frame.getContentPane().add(BorderLayout.CENTER,button);

示例1:按下按钮圆圈就会改变颜色

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ChangeCircleColor implements ActionListener {
    JFrame frame;
    public static void main(String[] args){
        ChangeCircleColor changeCircleColor=new ChangeCircleColor();
        changeCircleColor.go();
    }

    private void go() {
        frame =new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton button=new JButton("改变颜色");
        //把监听加到按钮上
        button.addActionListener(this);

        GradientColor gradientColor=new GradientColor()
        //依照指定区域把widget放上去
        frame.getContentPane().add(BorderLayout.SOUTH,button);
        frame.getContentPane().add(BorderLayout.CENTER,gradientColor);
        frame.setSize(300,300);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        frame.repaint();//当用户按下按钮时就要求frame重新绘制
    }
}
----------------------------------------------------------------------------------------------
protected void paintComponent(Graphics g) {
    Graphics2D graphics2D=(Graphics2D)g;

    int red=(int)(Math.random()*255);
    int green=(int)(Math.random()*255);
    int blue=(int)(Math.random()*255);
    Color startColor=new Color(red,green,blue);

    red=(int)(Math.random()*255);
    green=(int)(Math.random()*255);
    blue=(int)(Math.random()*255);
    Color endColor=new Color(red,green,blue);

    GradientPaint gradientPaint=new GradientPaint(70,70,startColor,150,150,endColor);
    graphics2D.setPaint(gradientPaint);
    graphics2D.fillOval(70,70,100,100);
}

效果1:

多重监听:当每个按钮执行不同工作时,要如何对两个不同的按钮分别取得事件?

答案:内部类。

一个类可以嵌套子另一个类的内部。这很简单,只要确定内部类的定义是包在外部类的括号中就可以。

内部类可以使用外部所有的方法与变量,就算是私有的也一样。

public class OutClass {
    private int x;
    class InnerClass{
        void go(){
            x=42;//把x当作自己的!
        }
    }//关闭内部类
}//关闭外部类

内部类和外部类关系不一般:内部类的实例一定会绑在外部类的实例上

如何创建内部类的实例

public class OutClass {
    private int x;//外部私有实例变量
    InnerClass innerClass=new InnerClass();//创建内部的实例
    public void doStuff(){
       innerClass.go();//调用内部的方法
    }
    class InnerClass{
        void go(){
            x=42;//内部可以使用外部的x变量!
        }
    }//关闭内部类
}//关闭外部类

示例2:现在就可以实现多重监听了

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TwoButton {//现在的主要GUI类并不实现ActionListener
    JFrame frame;
    JLabel label;
    public static void main(String[] args) {
        TwoButton twoButton = new TwoButton();
        twoButton.go();
    }
    public void go() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //相对于将this传给监听的注册方法,现在传的是对应的实例
        JButton labelButton = new JButton("改变标签");
        labelButton.addActionListener(new labelListener());
        JButton colorButton = new JButton("改变圆圈颜色");
        colorButton.addActionListener(new ColorListener());
        label = new JLabel("我是一个标签");
        GradientColor gradientColor = new GradientColor();
        frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
        frame.getContentPane().add(BorderLayout.CENTER, gradientColor);
        frame.getContentPane().add(BorderLayout.EAST, labelButton);
        frame.getContentPane().add(BorderLayout.WEST, label);
        frame.setSize(400,300);
        frame.setVisible(true);
    }
    //终于可以在单一的类中做出不同的ActionListener
    private class labelListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            label.setText("哎哟!疼死了!");
        }
    }
    private class ColorListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            frame.repaint();
        }
    }
}

效果2: