5 创建布局器 &手动布局

布局管理器 Layout Manager

负责对子空间的布局,当窗口变化的时候,动态调节子控件的位置和大小
代码:

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

public class Demo {

	public static void main(String[] args) {
		MyFrame frame = new MyFrame("Demo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(300, 600);
		frame.setVisible(true);
	}
}

class MyFrame extends JFrame{
	
	JLabel a1 = new ColorfulLabel("HelloWorld", Color.YELLOW);
	JLabel a2 = new ColorfulLabel("HelloWorld", Color.BLUE);
	
	public MyFrame(String title) {
		super(title);
		
		//根容器
		Container root = this.getContentPane();
		
		//设置一个自定义的布局器
		LayoutManager layout = new SimpleLayout();
		root.setLayout(layout);
		
		root.add(a1);
		root.add(a2);

	}
	
	private class ColorfulLabel extends JLabel{
		
		public ColorfulLabel(String text, Color color) {
			this.setText(text);
			this.setBackground(color);
			this.setOpaque(true);
			this.setHorizontalAlignment(SwingConstants.CENTER);
			this.setPreferredSize(new Dimension(60, 30));
		}
	}
	
	private class SimpleLayout implements LayoutManager{

		@Override
		public void addLayoutComponent(String name, Component comp) {
		}

		@Override
		public void removeLayoutComponent(Component comp) {
		}

		@Override
		public Dimension preferredLayoutSize(Container parent) {
			return null;
		}

		@Override
		public Dimension minimumLayoutSize(Container parent) {
			return null;
		}

		@Override
		public void layoutContainer(Container parent) {
			int w = parent.getWidth();  //父窗口的宽度 width
			int h = parent.getHeight();  //父窗口的高度 height
			System.out.println("父容器: " + w + ", " + h);
			
			//a1显示在中间,以Preferred Size作为大小
			if(a1.isVisible()) {
				//取得该空间所需的显示尺寸
				Dimension size = a1.getPreferredSize();
				int x = (w - size.width) / 2;
				int y = (h - size.height) / 2;
				
				//在设置子控件位置时,其坐标是相对于父窗口的
				a1.setBounds(new Rectangle(x, y, size.width, size.height));
			}
			
			//a2显示在右上角
			if(a2.isVisible()) {
				Dimension size = a2.getPreferredSize();
				int x = w - size.width;
				int y = 0;
				
				a2.setBounds(new Rectangle(x, y, size.width, size.height));
			}
		}
		
	}
}

布局器的运行机制:

  • 给容器设置一个布局器
    root.setLayout(layoutMgr)

  • 当容器大小改变时,自动调用布局器重新布局
    layoutMgr.layoutContainer(…) //这个是Swing内部自动调用的!!

要点和细节:

  • Preferred Size,指控件的最佳大小
    当调用label.getPreferredSize()时,由它自行测算自己所需的显示尺寸。

  • Dimension 表示尺寸信息

  • 普通内部类,静态内部类的区别

手动布局

用创建布局器的方式来进行布局,称为手动布局。

手动布局时,只需重写LayoutManager接口的layoutContainer()方法

但是这个接口有很多其他方法我们不需要实现,每次都要写出来,很麻烦。所以可以设计一个类重写这些方法,我们只需要继承这个类,然后实现我们需要的那个方法即可!!

AfSimpleLayout.java:

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;

public abstract class AfSimpleLayout implements LayoutManager{

	@Override
	public void addLayoutComponent(String name, Component comp) {
	}

	@Override
	public void removeLayoutComponent(Component comp) {
	}

	@Override
	public Dimension preferredLayoutSize(Container parent) {
		return null;
	}

	@Override
	public Dimension minimumLayoutSize(Container parent) {
		return null;
	}

}
private class SimpleLayout extends AfSimpleLayout{
	@Override
	public void layoutContainer(Container parent) {
		int w = parent.getWidth();  //父窗口的宽度 width
		int h = parent.getHeight();  //父窗口的高度 height
		System.out.println("父容器: " + w + ", " + h);
		
		//a1显示在中间,以Preferred Size作为大小
		if(a1.isVisible()) {
			//取得该空间所需的显示尺寸
			Dimension size = a1.getPreferredSize();
			System.out.println(size.width + " " + size.height);
			int x = (w - size.width) / 2;
			int y = (h - size.height) / 2;
			
			//在设置子控件位置时,其坐标是相对于父窗口的
			a1.setBounds(new Rectangle(x, y, size.width, size.height));
		}
		
		//a2显示在右上角
		if(a2.isVisible()) {
			Dimension size = a2.getPreferredSize();
			int x = w - size.width;
			int y = 0;
			
			a2.setBounds(new Rectangle(x, y, size.width, size.height));
		}
	}
}

要点和细节:

  • AfSimpleLayout implements了 LayoutManager,但并没有实现LayoutContainer这个方法,所以定义成了抽象方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值