zoukankan      html  css  js  c++  java
  • 创建被图像填充的组件

    如果你直接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)
    …..

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

  • 相关阅读:
    关于java.lang.reflect.InvocationTargetException
    Java并发编程(三)后台线程(Daemon Thread)
    Lab 7-2
    Lab 7-1
    Lab 6-3
    Lab 6-2
    Lab 6-1
    Lab 5-1
    Lab 3-4
    Lab 3-3
  • 原文地址:https://www.cnblogs.com/wewill/p/5588751.html
Copyright © 2011-2022 走看看