代码改变世界

创建被图像填充的组件

2015-12-27 19:57  v_ZSW  阅读(257)  评论(0编辑  收藏  举报

如果你直接new一个组件的话,组件是标准外观
如果需要改变组件的外观,最关键的就是要就需要重写组件的paintCoponent(Graphics g)方法,同时需要调整组件的大小

DIY的JPanel

下面用代码说话

import javax.swing.*;
import java.awt.*;

class ImagePanel extends JPanel{
    private Image image;//用来储存背景对象
    private Dimension dimension;//用来储存背景对象的尺寸
  public ImagePanel(Image image){
    this.image=image;
    dimension=new Dimension(image.getWidth(null),image.getHeight(null));//panel大小的对象
    setSize(dimension);
    setPreferredSize(dimension);
    setMinimumSize(dimension);
    setMaximumSize(dimension);
    //setLayout(null);
}
public void paintComponent(Graphics g){//Graphics图形类中有很多绘画方法
    //g.drawImage(image,0,0,null);//画背景,大小为原始大小
    g.drawImage(image,0,0,(int)(dimension.getWidth()*0.5),(int)(dimension.getHeight()*0.5),null);//大小缩放为原来的百分之50
}
}
class Demo{
    public static void main(String[] args){
    ImagePanel panel=new ImagePanel(new ImageIcon("D:\\微信截图_20151227195429.png").getImage());//Image对象的获取方法,Image是一个抽象类
    JFrame frame=new JFrame("haha");
    frame.getContentPane().add(panel);
    frame.pack();//加完所有组件后自动调整窗口的大小
    frame.setVisible(true);
}
}

下面是结果
这里写图片描述

用到了以下几个类
1.Graphics用来绘画图像, java.awt
2.Dimension用来设置各种大小,java.awt
3.Image用来储存背景的抽象类,java.awt
4.ImageIcon用来创建Image的实例,此类实现了Icon接口,javax.swing

解释几处做法

一、为什么这里设置了4个尺寸呢?

    setSize(dimension);
    setPreferredSize(dimension);
    setMinimumSize(dimension);
    setMaximumSize(dimension);

尺寸,偏好尺寸,最小尺寸,最大尺寸
因为并不确定要放进容器的布局
因为当布局为null也就是绝对布局的时候,只需要设置serSize就可以了
当布局不为空时,此时布局管理器会相应的调整图像的尺寸了

如何进行图像缩放

当组件的图像太大时,甚至超过了屏幕,此时就需要进行缩放了
处理的地方是

    //g.drawImage(image,0,0,null);//画背景,大小为原始大小
    g.drawImage(image,0,0,(int)(dimension.getWidth()*0.5),(int)(dimension.getHeight()*0.5),null);//大小缩放为原来的百分之50

这里就要说说Graphics类中绘制图像的方法了
drawImage(Image image,int x,int y,ImageObserver observer);
drawImage(Image image,int x,int y,int width,int height,ImageObserver observer);
第一种方法是没有进行缩放的,第二种方法进行了缩放
缩放后的大小为width*height,缩放的方法可以参照上面代码,进行等比例缩放
至于那个ImageObserver有什么用,我还不知道
API是这样解释的

此方法在任何情况下都立刻返回,甚至在要绘制的图像区域没有针对当前输出设备完成缩放、抖动或转换的情况下也是如此。如果当前的输出表示形式尚未完成,则 drawImage 返回 false。随着更多的图像可用,加载图像的进程将通知指定的图像观察者。 
observer - 当缩放并转换了更多图像时要通知的对象。 
ImageObserver用于在构造 Image 时,接收有关 Image 信息通知的异步更新接口。 

我的理解是,当设置好了背景之后,并不一定是马上在输出设备上体现出来,需要一定的时间
如果上一个设置图像还在输出的时候又设置一次图像的话,那么方法返回false,并等到上一次设置图像输出完毕了之后,通知指定的图像观察者,图像观察者就调用imageUpdate方法,更新图像

DIY的JLable

下面还是用代码说话

import java.awt.*;
import javax.swing.*;
class JLabelDemo extends JLabel{
    JLabelDemo(String image){
        this((new ImageIcon(image)).getImage());
        }
    JLabelDemo(Image image){
        setSize(image.getWidth(null),image.getHeight(null));//方便测试透明的效果
        setIcon(new ImageIcon(image));//设置图标,也就是说JLabel类自带有绘画图像的方法,不需要我们去覆写
        setText(null);//不设置Label文本内容
        setBorder(null);//不设置边框
        setIconTextGap(0);//设置图标和文本的距离
        setOpaque(false);//是否不透明
        }
    }

如果要自定义一个JLabel,有以下几步需要做的:
1.设置icon,JLabel类中有setIcon()方法,也就自然不需要我们来覆写paintComponent方法啦
2.设置Label尺寸
3.设置Label是否有边框
4.设置Label是否透明(这点很重要,直接影响效果(如果面板有背景的话))
5.设置文本内容
6.设置文本内容和图标的距离##(如果不需要文本内容的话,这时候Label可以直接当成是插入图片去用)##

下面是两种结果,分别是背景透明和背景不透明
这种是设置为不透明
这种是设置为透明

DIY的JButton

下面仍然是用代码说话

import javax.swing.*;
import java.awt.*;
class JButtonDemo extends JButton{
    JButtonDemo(String image){
        this(new ImageIcon(image),null);
        }
    JButtonDemo(String image,String text){
        this(new ImageIcon(image),text);
        }
    JButtonDemo(ImageIcon icon,String text){
        setSize(icon.getImage().getWidth(null),icon.getImage().getHeight(null));//尺寸
        setIcon(icon);//图标
        setText(text);//文本
        setIconTextGap(0);//文本与图标的距离
        setBorder(null);//边框
        setBorderPainted(false);//是否画边框
        setMargin(new Insets(0,0,0,0));//边空
        }
}

自定义Label和自定义Button的步骤差不多
只是多了边空和边框这两个属性

解释几点

一、边空是什么呢?

边空就是当图标和文本都画完了之后,图标和文本离边框还有一定距离时,就会绘画边空了,就是白边
用setMargin(Insets m)可以设置

setMargin(new Insets(0,1,2,3));

注意到实例化Insets有四个参数分别是距离上左下右边界的距离

需要注意的是:::::如果不想要边空的话

setMargin(null);

这样子做的话,是不会起效果的,反而是用了默认边空,由Border对象适当的建立边空

如果想不需要边空的话,只能这样做

setMargin(new Insets(0,0,0,0));

二、setIcon远远不够

setIcon只是设置了这个按钮的默认外观,实际开发还需要设置以下几种外观:
1.光标按下去时的外观——setPressedIcon(ImageIcon)
2.鼠标滚动外观——setRolloverIcon(ImageIcon)
3.选中外观——setSelectedIcon(ImageIcon)
…..

下面是结果
这里写图片描述