如果你直接new一个组件的话,组件是标准外观 如果需要改变组件的外观,最关键的就是要就需要重写组件的paintCoponent(Graphics g)方法,同时需要调整组件的大小
下面用代码说话
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
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方法,更新图像
下面还是用代码说话
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可以直接当成是插入图片去用)##
下面是两种结果,分别是背景透明和背景不透明
下面仍然是用代码说话
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只是设置了这个按钮的默认外观,实际开发还需要设置以下几种外观: 1.光标按下去时的外观——setPressedIcon(ImageIcon) 2.鼠标滚动外观——setRolloverIcon(ImageIcon) 3.选中外观——setSelectedIcon(ImageIcon) …..
下面是结果