功能需求:
一个窗口包含三个物品,有三个购买按钮。鼠标移动到按钮上,按钮图片改变。移出,还原。
基本技术:层叠面板,用一个小的面板代替按钮。
一、先看实现效果:
表示这个窗口的子类,只用50行
public class UIBuy extends UIFrame{
/
public UIBuy(){
w=640;
h=410;
title=" ";
imgpath.add("img/frame/equipbuy.png");
imgpath.add("img/frame/buyIdle.png");
imgpath.add("img/frame/buy.png");
imgpath.add("img/frame/buyIdle.png");
imgpath.add("img/frame/buy.png");
imgpath.add("img/frame/buyIdle.png");
imgpath.add("img/frame/buy.png");
//110, 260, 410
int btnw=105,btnh=30;
xywh=new int[]{0,0,w,h,
110,280,btnw,btnh,
110,280,btnw,btnh,
260,280,btnw,btnh,
260,280,btnw,btnh,
410,280,btnw,btnh,
410,280,btnw,btnh
};
//
super.init();
//移动到一个图片上,调整另一个图片的位置
// pane, btnidle, btn_mouse_on, frame, btn_index
BtnBuy_buy b1 =new BtnBuy_buy(getLayeredPane(),
getBtn(1), getBtn(2),getFrame(), 0);
b1.addevent();
BtnBuy_buy b2 =new BtnBuy_buy(getLayeredPane(),
getBtn(3), getBtn(4),getFrame(), 1);
b2.addevent();
BtnBuy_buy b3 =new BtnBuy_buy(getLayeredPane(),
getBtn(5), getBtn(6),getFrame(), 2);
b3.addevent();
}
@Override
public JFrame fac_getNewFrame() {
return ToolFac.newTmpFrame();
}
public static void main(String[] args) {
new UIBuy();
}
}
子类,给出3个按钮的默认坐标宽高,鼠标移上去的坐标宽高。
子类,给出窗口背景图片,3张默认图片,3张鼠标移上去的图片。
其他事情,父类完成。
二、父类设计
用数组存放每个图片路径,每个窗口组件。
public abstract class UIFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
String title;
int w;
int h;
ArrayList<String> imgpath=new ArrayList<String>();
//ImageIcon kaishi2 = new ImageIcon("img/kaishi3.png");
ArrayList<ImageIcon> imgpath_ImageIcon =new ArrayList<ImageIcon>();
ArrayList<BackgroundPanel> btn_Ar =new ArrayList<BackgroundPanel>();
int xywh[];
JFrame frame;
JLayeredPane layeredPane;
/
public abstract JFrame fac_getNewFrame();
public void init(){
/*
1.创建一个 居中显示的窗体。
a、创建一个JFrame
b、设置标题
c、设置默认的关闭方式
d、设置窗体的大小以及屏幕中的显示方式
e、设置为可见,设置窗体的大小不变
*/
frame=fac_getNewFrame();
layeredPane = new JLayeredPane();
//
frame.setTitle(title);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Dimension dim=Toolkit.getDefaultToolkit().getScreenSize();
frame.setBounds((dim.width-w)/2,(dim.height-h)/2,w,h);
// 0, back img
// 1,button
//设置各个按钮,数组保存
for(int i=0;i<imgpath.size();i++)
{
// 图片数组
imgpath_ImageIcon.add(new ImageIcon(imgpath.get(i)));
BackgroundPanel tmp=new BackgroundPanel(imgpath_ImageIcon.get(i).getImage());
tmp.setBounds(xywh[i*4], xywh[i*4+1], xywh[i*4+2],xywh[i*4+3]); //
btn_Ar.add(tmp);
}
// 面板添加按钮
// back
layeredPane.add(btn_Ar.get(0), new Integer(5), 1);
// buttons
for(int i=1;i<imgpath.size();i++)
{
if(i%2 ==1) //default img
layeredPane.add(btn_Ar.get(i), new Integer(6), 1);
else
layeredPane.add(btn_Ar.get(i), new Integer(2), 1);
}
frame.setContentPane( layeredPane);
// 显示窗体
frame.setVisible(true);
frame.setResizable(false);
}
// get函数
public JLayeredPane getLayeredPane() {
return layeredPane;
}
public BackgroundPanel getBtn(int i) {
return btn_Ar.get(i);
}
public JFrame getFrame() {
return frame;
}
}
三、用到模板方法的地方
父类,没有直接new JFrame();
程序中的各个窗口,被工厂类管理。
由子类调工厂函数,获取某一个JFrame。
父类预留一个抽象函数。这是模板方法。
父类没有写事件监听,那么,预留get函数,返回JFrame和层叠面板JLayeredPane。
这两个对象,留给鼠标监听,需要调JFrame的关闭函数,关闭窗口。
需要调JLayeredPane,调整位置,当鼠标移到某一个图片上时,某个小面板靠前输出。
具体案例,可以参见我上传的案例资源、代码、讲解视频: