java考点之程序看图形界面的布局逻辑

虽然勉强能看懂,但还是不太能理解到底如何理解java的布局逻辑了呢?

如题:2022年4月,第33题程序设计题

分析:

题目给出了部分程序,只需要填缺少的部分,前面28题有类似的,倒是可以比照着写出来,但还是不太明白到底是如何布局的?能准确控制吗?对此还是存有疑问了。同时多了解一下java设计的逻辑。

基本知识:

AWT图形组件的继承关系

虽然AWT已经很少使用了,但SWing组件继承了Container类,所以绝大部分swing组件都可以当作容器使用。这种继承关系决定了操作的顺序。

Swing组件的继承关系

图中可以看到四个顶层容器都直接继承自awt,所以都是重量级组件。需要依赖于本地化的gui平台。

这些组件方法,都很容易可以查到,没什么大不了的,关键是要理解java的布局逻辑?

排列逻辑:

顶层容器就相当于相框的底板,所有的照片都是放在这上面的。如:

Frame相当于一个大的框架,再它里面可以放多个面版,但是组件不能直接放在上面。

再往下是:Panel面板也是一个容器,,但是它不能单独存在,只能存在其他容器,但组件可以直接放在上面。一个Panel对象代表了一个长方形的区域。

前两层,相当于底框与底板的关系,那么底板放到底框上呢?

底框有描述底板的空间方法,底板也有描述底板的空间方法,共同点是都要占一定的空间。两个空间如何叠放,形成一张完整的相框呢?

java设计了内容窗格,想想也知道,这个内容空间的大小是由底框定,当然也可以由底板来定。所以给出了两种方法:

由底框定内容:

通过顶层容器getContentPane( )方法,返回类型为java.awt.Container。格式如下:

Container contentPane=frame.getContentPane( );
contentPane.add(button,BorderLayout.CENTER);

简化的写法为:mw.getContentPane().add(button); //mv就是个框架

由底板定内容:

建立一个JPanel对象的中间容器,把组件添加到这个容器中,再用setContentPane()把这个容器置为内容面板。

JPanel contentPane = new JPanel();

mw.setContentPane(contentPane);

有了相框,就是往里面放照片,也就是组件了,但如何排列呢?

java设计了布局管理器。每一个容器都有默认的布局管理器,

Window、Frame和Dialog的默认布局管理器是BorderLayout,Panel的默认布局管理器是FlowLayout。也可以调用容器的setLayout(null)方法,将布局管理器取消。

组件在容器中的位置和尺寸是由布局管理器来决定的。

FlowLayout

流式布局下,容器会将组件按照添加顺序从左向右放置。FlowLayout(int align,int hgap,int vgap);//可设置对齐方式,及水平垂直距离多少像素。默认是居中(也就是每行平均分布)组件间隔5个像素

如下例子:

        Frame frame = new Frame();
        frame.setVisible(true);

        //组件-button
        Button button1 = new Button("button1");
        Button button2 = new Button("button2");
        Button button3 = new Button("button3");

        //设置流式布局:
        frame.setLayout(new FlowLayout());
//        frame.setLayout(new FlowLayout(FlowLayout.LEFT));  //布局偏左
//        frame.setLayout(new FlowLayout(FlowLayout.RIGHT));   //布局偏右

        frame.setSize(200,200);

        //把button填加到frame:
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);


BorderLayout 边界布局(JWindow、JFrame,JDialog 的默认布局)

空间简单划分为东“East”,西 “West”,南 “South”,北 “North”,中 “Center”
五个区域。

一个位置放一个组件。如果某个位置要加入多个组件,应先将要加入该位置的组件放放另一个容器中,然后再将这个容器加入到这个个位置。

如下例子:

        Frame frame = new Frame("TestBorderLayout:");
        frame.setVisible(true);
        frame.setSize(500,500);

        Button button1 = new Button("East");
        Button button2 = new Button("West");
        Button button3 = new Button("South");
        Button button4 = new Button("North");
        Button button5 = new Button("Center");

        //BorderLayout的使用:
        frame.add(button1,BorderLayout.EAST);	//add(添加的组件,边界布局设置)
        frame.add(button2,BorderLayout.WEST);
        frame.add(button3,BorderLayout.SOUTH);
        frame.add(button4,BorderLayout.NORTH);
        frame.add(button5,BorderLayout.CENTER);


GridLayout网格布局管理器

使用纵横线将容器分成n行m列大小相等的网格,每个网格中放置一个组件

使用例子:

        Frame frame = new Frame("TestGridLayout:");
        frame.setSize(500,500);
        frame.setVisible(true);

        //设置布局格式:3行2列
        frame.setLayout(new GridLayout(3,2));

        Button button1 = new Button("button1");
        Button button2 = new Button("button2");
        Button button3 = new Button("button3");
        Button button4 = new Button("button4");
        Button button5 = new Button("button5");
        Button button6 = new Button("button6");

        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.add(button4);
        frame.add(button5);
        frame.add(button6);

有了相框,可以显示一些东西了,但重要的是要有人机交互,才能实现动态展示一些信息?(简单了解下)

这才是真正的互联网。如何实现呢?java 设计了事件侦听,只介绍几个常用的。

窗口侦听事件(本题所涉及到的)

Window类型的窗口需要实现WindowListener接口。接着通过addWindowListener()方法为事件源注册事件监听器对象,当事件源上发生事件时,便会触发事件监听器对象,由事件监听器调用相应的方法来处理相应的事件。

 public class WindowListeners {
    public static void main(String[] args) {
    new WindowFrame();
    }
}
class WindowFrame extends Frame{
    public WindowFrame(){
        setBounds(100,100,400,300);
		//添加button组件到界面中:
        Button button = new Button("setVisible!");
        add(button);
        setVisible(true);
		//设置窗口监听,使用适配器模式:
        addWindowListener(new WindowAdapter() {
            //监听窗口关闭:
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("windowClosing");
            }
            //监听窗口动态:
            @Override
            public void windowActivated(WindowEvent e) {
                System.out.println("windowActivated");
            }
        });
    }
}

鼠标监听事件

首先需要通过实现MouseListener接口定义监听器(也可以通过继承适配器MouseAdapter类来实现),然后调用addMouseListener()方法将监听器绑定到事件源对象。

public class mouse extends Frame {
    public mouse(){
        setBounds(100,100,400,350);
        setVisible(true);
        Button b1 = new Button("btn1");
        Button b2 = new Button("btn2");
        //添加鼠标事件:
        b1.addMouseListener(new MouseListen());
        add(b1,BorderLayout.SOUTH);
        add(b2,BorderLayout.NORTH);
    }
    class MouseListen extends MouseAdapter {
        //定义鼠标按压触发监听效果:
        @Override
        public void mousePressed(MouseEvent e) {
            Object source = e.getSource();
            System.out.println("鼠标点击了!");
        }
    }
    public static void main(String[] args) {
        new mouse();
    }

输入框TextField

使用例子如下:

public class TestTextField {
    public static void main(String[] args) {
        new MyFrame1();
    }
}
    class MyFrame1 extends Frame{
        public MyFrame1(){
            TextField text = new TextField();
            add(text);

            //监听这个文本输入的文字:
            MyActionL myActionL = new MyActionL();
            //按下enter,触发这个输入框的事件:
            text.addActionListener(myActionL);
            setSize(400,200);
            setVisible(true);
            text.setEchoChar('*');     //设置编码替换:把输入的数据转换为**显示
        }
    class MyActionL implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            TextField field = (TextField) e.getSource();  //获取资源,返回一个对象
            System.out.println(field);
            System.out.println(field.getText());   //获取输入框的文本
            field.setText("");					   //按下回车后文本框重置为空
        }
    }

答案:

public class Test33 {
    public static void main(String[] args) {
        Statement be = new Statement();
        be.go();
    }
}

class Statement extends WindowAdapter implements ActionListener {
    JFrame f;
    JButton myButton;
    JLabel myLabel;
    JTextField tfs;
    String ad = "This is a JFrame!";

    public void go() {
        f = new JFrame("My JFrame");
        f.setLayout(new GridLayout(6 , 1 , 10 , 10));
        f.setSize(650 , 400);
        myLabel = new JLabel("Statement");//标签有了
        JPanel pan1 = new JPanel();
        JPanel pan2 = new JPanel();//面板也有了
        pan1.setLayout(new FlowLayout(FlowLayout.CENTER , 40 , 0));
        //此处填写代码,分析,还少的是文本域和按钮

        tfs = new JTextField("This is a JFrame");//只添加这两句的话,只显示框架,面板里的组件一个也显示不出来???
        pan1.add(myLabel);
        pan1.add(tfs);
        pan2.setLayout(new FlowLayout(FlowLayout.CENTER , 40 , 0));
        myButton = new JButton("OK");
        pan2.add(myButton);

        Container cp = f.getContentPane();//内容窗体,面板是不能单独存在的
        cp.setLayout(new GridLayout(0 , 1));//布局很关键,否则会显示不全?这里决定了这两个面板是是竖着排列的,布局管理器的逻辑是什么?
        cp.add(pan1);
        cp.add(pan2);
        f.pack();//这里也很关键,否则显示不成比例?

        f.addWindowListener(this);
        f.setVisible(true);
    }

    public void windowClosing(WindowEvent event) {
        System.exit(0);
    }

    @Override
    public void actionPerformed(ActionEvent e) {

    }
}

答案中总结的设计窗体的步骤?

  1. 设计一个窗体的类,并且指明要响应的事件,如第一句:class Statement extends WindowAdapter implements ActionListener
  2. 在mian中新一个窗体类,分配内存空间,并调用窗体的go函数
  3. 在go函数里写设计过程
  4. 可先设计一个框架,布局可设置为表格样式,并且设置表格的大小,间距。设置框架的大小。框架的大小决定了显示里面的表格的尺寸,如果格点很大的话,会显示不全。
  5. 然后,设计框架里的面板,面板里添加组件,面板可单独设置布局,这个相当于一块独立的长方体。默认是flowlayout,间隔5个像素。按所选的布局管理器添加组件即可
  6. 可通过内容窗格,把面板放到里面,也可以直接利用框架add面板。内容窗格的添加顺序,或框架的添加顺序,决定了显示顺序。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guangod

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值