Java有一道坎叫“传参”

来源:互联网 发布:行业差距 知乎 编辑:程序博客网 时间:2024/06/10 06:06

  Java中运用封装可以做到代码简洁、层次清晰、便于维护的作用。
  但是也带来了传参这类小麻烦。
  现以画图板为例,来说明传参的“小技巧”。
   
  如果定义了一个MyList容器,用于存储数组坐标(用于重绘)。其代码部分粘贴如下:
 
public class MyList {
//初始化一个整型数组
int[] src = new int[0];

//添加一个元素的方法
public void add(int x){
int[] dest = new int[src.length+1];
//复制
for(int i=0;i<src.length;i++){
dest[i] = src[i];
}
dest[src.length] = x;
//交换
src = dest;
}


//输出队列中所有的元素
public void printArray(){
for(int i=0;i<src.length;i++){
System.out.print(src[i]+" ");
}
}

//获取队列的长度
public int getLen(){
return src.length;
}

//获取指定位置的元素
public int getIndex(int index){
return src[index];
}


  而且有一个鼠标监听器,其部分代码如下:
  public class MyMouseAdapter extends MouseAdapter{
private int x1,y1,x2,y2;
Graphics g;
private ToolPanel tool_panel;
String command="line";
private MyList list = new MyList();
//获取容器list
public MyList getList(){
return list;
}


  而真正需要得到坐标的是类:drawPanel,其部分代码如下:
public class DrawPanel extends JPanel{
private MyFrame frame;
//private MyMouseAdapter mouse_listener;
public DrawPanel(MyFrame frame){
this.frame = frame;
mouse_listener = frame.getListener();
//System.out.println("得到mouse_listener");
this.setBackground(Color.white);
this.setPreferredSize(new Dimension(420,420));
}
//重绘
public void paint(Graphics g){
//调用父类的方法
super.paint(g);
MyList list = frame.getListener().getList();
//获取到监听器中的队列list
for(int i=0;i<list.getLen()/4;i++){
g.drawLine(list.getIndex(4*i),list.getIndex(4*i+1),list.getIndex(4*i+2),list.getIndex(4*i+3));
}
}
}

如何在drawPanel中取得MyMouseAdapter中的list呢?
其思路是:因为drawPanel和MyMouseAdapter都在同一个主容器中,其主容器的代码如下:


public class MyFrame extends JFrame{
//鼠标监听器
MyMouseAdapter mouse_listener;

//获取mouse_listener
public MyMouseAdapter getListener(){
return mouse_listener;
}
      //显示界面的方法
public void showUI(){

 
//创建三个面板对象
ToolPanel tool_panel=new ToolPanel();
DrawPanel draw_panel=new DrawPanel(this);
ColorPanel color_panel=new ColorPanel();
//将面板加入到窗体中
this.add(tool_panel,BorderLayout.WEST);
this.add(draw_panel,BorderLayout.CENTER);
this.add(color_panel,BorderLayout.SOUTH);
//设置可见
this.setVisible(true);
 
//获取画布
Graphics g=draw_panel.getGraphics();
 
 
//设置鼠标监听器
mouse_listener=new MyMouseAdapter(g,tool_panel);
System.out.println("准备创建Mouse_listener");
draw_panel.addMouseListener(mouse_listener);
 }
}

  要注意到上面代码中所给出的方法,其文字描述为:在MyMouseAdapter中提供获取容器的方法:private MyList list = new MyList();
//获取容器list
public MyList getList(){
return list;
}

如果在DrawPanel中代码改为

        public class DrawPanel extends JPanel{

//private MyFrame frame;
private MyMouseAdapter mouse_listener;
public DrawPanel(MyFrame frame){
mouse_listener = frame.getListener();
//System.out.println("得到mouse_listener");
this.setBackground(Color.white);
this.setPreferredSize(new Dimension(420,420));
}
//重绘
public void paint(Graphics g){
//调用父类的方法
super.paint(g);
MyList list =mouse_Listener.getList();
//获取到监听器中的队列list
for(int i=0;i<list.getLen()/4;i++){
g.drawLine(list.getIndex(4*i),list.getIndex(4*i+1),list.getIndex(4*i+2),list.getIndex(4*i+3));
}


}
  此时是错误的,因为,在MyFrame中调用DrawPanel()时,会执行DrawPanel中的mouse_listener=frame.getListener();而此时,还没有创建mouse_listener(),在MyFrame()中可以看到代码执行顺序。
  
原创粉丝点击