haoxiang hen mafan a !!每次生成删除一次都要刷新一下页面。

解决方案 »

  1.   

    调用你最大哪个容器的 repaint();函数,
     重画界面。
     通常这个函数在 其内部容器有 改动是自动调用
      

  2.   

    之前我也研究过类似的问题,不过用的语言是C#。总的来说这涉及到执行期间动态生成组件,因为是执行期间生成的,所以需要用一些手段来判别该组件是哪次生成的。我当时的做法是写一个类继承按钮,并设置一个标志变量,每次生成按钮的时候给该标志位不同的值,并用ArrayList存储。当单击删除的时候首先判断标志位来确定是哪个按钮,再在List中查找该按钮删除,最后做重绘工作。java和c#机制上都差不多,解决方法类似。
      

  3.   

    对了,这个操作还需要拆箱和装箱,使用泛型技术。用java1.5版比较好。
      

  4.   

    我用的是jbuilder
    最好帮我实现一下,因为现在我都实在没时间研究这个了——所以才压上了200分,请朋友们帮忙。
      

  5.   

    我知道为什么baidu google都用不来了了 我只能回去个您发资料了
      

  6.   

    用Visual C#动态生成组件
    [本页面推荐在1024x768分辩率下浏览]
    文章类别:C#应用   发表日期:2003-12-29  星期一  
    网站首页 —> C#应用 
     
      以前在用Delphi写程序的时候,总不喜欢在窗体上排放很多组件,这一方面有点不美观,并且在调试程序时候,也不是十分方便。通常在写程序的时候,当要用到某些组件,采用的方法一般都是动态创建,用完以后就释放掉。Visual C#在程序运行的时候也可以动态创建组件,下面就结合一个程序例子来具体介绍如何用Visual C#动态生成组件。首先让我们了解一下,在动态创建组件的过程中要用到的一些概论和理论。  一. Boxing (装箱)和Unboxing (出箱):  在用Visual C#动态创建组件的时候,要涉及到二种数据类型变量的转换,这二种类型变量就是实值类型(Value Type)变量和参考类型(Reference Type)变量,而这种转换过程在Visual C#中被称为Boxing (装箱)和Unboxing (出箱)。其中把实值类型变量转换成参考类型变量就是Boxing (装箱);把参考类型变量转换成实值类型变量就是Unboxing (出箱)。那么什么是实值类型,说的简单些,就是我们平常使用的整型、布尔型、枚举型等,这些类型的变量就是实值类型变量了;所谓参考类型,在Visual C#中指的就是Object、Class、Interface、Delegate、String、Array等,他和实值类型最主要的不同之处就是,参考类型变量存放的是指向实体对象的指针,而实值类型变量却是实实在在地实体对象。在本文介绍的程序中,主要涉及的是出箱。具体的处理方法,在下面有着具体介绍。  二. 本文中程序设计和运行的环境:  (1).微软公司视窗2000服务器版  (2)..Net FrameWork SDK Beta 2  三. 程序设计中的关键步骤以及解决方法:  文中软件主要功能是用通过窗体上的二个按钮来创建二个不同类型的WinForm组件--Button组件和TextBox组件,并在创建的同时为每一个组件的属性赋值,给每一个创建的组件也创建了事件。  (1).如何在窗体上创建Button组件:    其实用Visual C#创建一个组件是十分方便的,只用下列二行语句就可以完成了://创建一个新的Button组件
    Button myButton = new Button ( ) ;
    //在窗体中显示此按钮
    this.Controls.Add ( myButton ) ;
    但此时创建的这个Button组件没有任何属性,并且也没有任何事件,在本文中介绍的程序中创建的Button组件,不仅有属性也有事件,下列语句就是本文程序创建Button组件源代码:
    //按钮数量计算器在每次按钮按动后加"1"
    counter += 1 ;
    //对要产生的按钮的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加"3"
    locY += this.btnAdd.Height + 3 ;
    //创建一个新的Button组件
    Button myButton = new Button ( ) ;
    //设定他的名称和Text属性,以及产生的相对位置
    myButton.Name = "Button " + counter ;
    myButton.Text = "按钮 " + counter ;
    myButton.Location = new Point ( btnAdd.Location.X , locY ) ; 
    //为产生的新的Button组件设定事件,本文中为产生的按钮设定了三个事件
    myButton.MouseEnter += new System.EventHandler ( this.btn_MouseEnter ) ;
    myButton.MouseLeave += new System.EventHandler ( this.btn_MouseLeave ) ;
    myButton.Click += new System.EventHandler ( this.btn_Click ) ;
    //在窗体中显示此按钮
    this.Controls.Add ( myButton ) ;   程序不仅为每一个组件的属性都赋值,而且为每一个组件都创建了三个事件。细心的读者可能已经注意到,程序为每一个组件创建的事件的名称都是一样的。这样就有一个问题,如何在这一样的事件中,识别到底是哪个Button组件触发了事件。  (2).确定是哪个组件触发了事件:  由于程序中为每一个创建的Button组件的事件都是一样的,要想正确处理这些组件的事件,就需要在事件触发的程序中判断到底是哪个组件触发了这个事件。这就需要用到上面所提出的装箱和出箱。我们知道Sender对象是一个参考类型变量,他存放的是指向触发当前事件实体对象的指针。要把他给转换成实值对象类型,通过下列语句就可以确定是哪个组件触发了当前事件:private void btn_MouseEnter ( object sender , System.EventArgs e )
    {
    //出箱
    Button currentButton = ( Button ) sender ;
    //设定按钮的背景色
    currentButton.BackColor = Color.Red ;
    }   其他事件可以仿照此事件的处理过程来处理。  (3). 如何在窗体上创建TextBox组件:  创建TextBox组件的过程和创建Button组件过程相类似,只是在创建的组件类型上面有一点区别,具体实现语句如下://文本框数量计算器在每次按钮按动后加"1"
    counter01 += 1 ;
    //对要产生的文本框的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加"3
    locY1 += this.txtAdd.Height + 3 ;
    //创建一个新的TextBox组件
    TextBox myBox = new TextBox ( ) ;
    //设定他的名称和Text属性,以及产生的位置
    myBox.Name = "TextBox " + counter01 ;
    myBox.Text = "文本框 " + counter01 ;
    myBox.Location = new Point ( txtAdd.Location.X , locY1 ) ; 
    //为产生的新的TextBox组件设定事件,本文中为产生的文本框设定了一个事件
    myBox.Click += new System.EventHandler ( this.btn_Click ) ;
    //在窗体中显示此文本框
    this.Controls.Add ( myBox ) ;   此时细心的读者又会发现,为每一个TextBox组件创建Click事件和为Button组件创建的Click事件也是一样的,这样在Click事件中不仅要判断是哪个组件触发了事件,还要判断是那种类型的组件触发了事件,下面语句是实现这些判断地具体方法:private void btn_Click ( object sender , System.EventArgs e )
    {
    if ( sender.GetType ( ) == typeof ( Button ) ) 
    {
    Button control = ( Button ) sender ;
    MessageBox.Show ( control.Text + "被按动了!");
    }
    else 
    {
    TextBox control = ( TextBox ) sender ; 
    MessageBox.Show ( control.Text + "被按动了!" ) ;
    }
    }   当然如果你也可以单独为TextBox组件创建Click事件。此时创建的事件语句可改为:myBox.Click += new System.EventHandler ( this.txt _Click ) ;   下面是实现txt _Click ( )事件的程序代码:private void txt_Click ( object sender , System.EventArgs e )
    {
    TextBox currentButton = ( TextBox ) sender ;
    MessageBox.Show ( currentButton.Text + "被按动了!");
    }  
      

  7.   

    四. 本文中源程序已经程序运行的界面:  下面这些图是程序运行:
    图01:程序中动态创建了组件 
    图02:单击创建的按钮的结果图 
    图03:单击创建的文本框的结果图   下面是实现上面结果的程序源代码:using System ;
    using System.Drawing ;
    using System.Collections ;
    using System.ComponentModel ;
    using System.Windows.Forms ;
    using System.Data ;
    namespace DynamicControls
    {
    public class Form1 : Form
    {
    private Button btnAdd ;
    private System.ComponentModel.Container components = null ;
    private Button txtAdd ;
    //给产生的按钮定义一个数量计算器
    private int counter ;
    //给产生的按钮定义相对位置的纵坐标
    private int locY ;
    //给产生的文本框定义一个数量计算器
    private int counter01 ;
    //给产生的文本框定义相对位置的纵坐标
    private int locY1 ;
    public Form1 ( )
    {
    InitializeComponent ( ) ;
    //初始化产生的按钮何文本框位置的纵坐标
    locY = this.btnAdd.Location.Y ;
    locY1 = this.txtAdd.Location.Y ;
    }//清除在程序中使用到的资源
    protected override void Dispose ( bool disposing )
    {
    if ( disposing )
    {
    if ( components != null ) 
    {
    components.Dispose ( ) ;
    }
    }
    base.Dispose ( disposing ) ;
    }private void InitializeComponent ( )
    {
    this.btnAdd = new Button ( ) ;
    this.txtAdd = new Button ( ) ;
    this.SuspendLayout ( ) ;this.btnAdd.FlatStyle = FlatStyle.Popup ;
    this.btnAdd.Location = new System.Drawing.Point ( 8 , 16 ) ;
    this.btnAdd.Name = "btnAdd" ;
    this.btnAdd.TabIndex = 0 ;
    this.btnAdd.Text = "生成按钮!" ;
    this.btnAdd.Click += new System.EventHandler ( this.btnAdd_Click ) ;this.txtAdd.FlatStyle = FlatStyle.Popup ;
    this.txtAdd.Location = new System.Drawing.Point ( 108 , 16 ) ;
    this.txtAdd.Name = "txtAdd" ;
    this.txtAdd.TabIndex = 1 ;
    this.txtAdd.Text = "生成文本框!" ;
    this.txtAdd.Click += new System.EventHandler ( this.txtAdd_Click ) ;this.AutoScaleBaseSize = new System.Drawing.Size ( 5 , 13 ) ;
    this.ClientSize = new System.Drawing.Size ( 292 , 273 ) ;
    this.Controls.Add ( btnAdd ) ;
    this.Controls.Add ( txtAdd ) ;
    this.Name = "Form1" ;
    this.Text = "在Visual C#中如何动态产生组件!" ;
    this.ResumeLayout ( false ) ; }
    static void Main ( ) 
    {
    Application.Run ( new Form1 ( ) ) ;
    }
    private void btnAdd_Click ( object sender , System.EventArgs e )
    {
    //按钮数量计算器在每次按钮按动后加"1"
    counter += 1 ;
    //对要产生的按钮的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加"3"
    locY += this.btnAdd.Height + 3 ;
    //创建一个新的Button组件
    Button myButton = new Button ( ) ;
    //设定他的名称和Text属性,以及产生的位置
    myButton.Name = "Button " + counter ;
    myButton.Text = "按钮 " + counter ;
    myButton.Location = new Point ( btnAdd.Location.X , locY ) ; //为产生的新的Button组件设定事件,本文中为产生的按钮设定了三个事件
    myButton.MouseEnter += new System.EventHandler ( this.btn_MouseEnter ) ;
    myButton.MouseLeave += new System.EventHandler ( this.btn_MouseLeave ) ;
    myButton.Click += new System.EventHandler ( this.btn_Click ) ;
    //在窗体中显示此按钮
    this.Controls.Add ( myButton ) ;
    }private void txtAdd_Click ( object sender , System.EventArgs e )
    {
    //文本框数量计算器在每次按钮按动后加"1"
    counter01 += 1 ;
    //对要产生的文本框的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加"3
    locY1 += this.txtAdd.Height + 3 ;
    //创建一个新的TextBox组件
    TextBox myBox = new TextBox ( ) ;
    //设定他的名称和Text属性,以及产生的位置
    myBox.Name = "TextBox " + counter01 ;
    myBox.Text = "文本框 " + counter01 ;
    myBox.Location = new Point ( txtAdd.Location.X , locY1 ) ; 
    //为产生的新的TextBox组件设定事件,本文中为产生的文本框设定了一个事件
    myBox.Click += new System.EventHandler ( this.btn_Click ) ;
    //在窗体中显示此文本框
    this.Controls.Add ( myBox ) ;
    }
    private void btn_MouseEnter ( object sender , System.EventArgs e )
    {
    //出箱
    Button currentButton = ( Button ) sender ;
    //设定按钮的背景色
    currentButton.BackColor = Color.Red ;
    }private void btn_MouseLeave ( object sender , System.EventArgs e )
    {
    //出箱
    Button currentButton = ( Button ) sender ;
    currentButton.BackColor = Control.DefaultBackColor ;
    }private void btn_Click ( object sender , System.EventArgs e )
    {
    if ( sender.GetType ( ) == typeof ( Button ) ) 
    {
    Button control = ( Button ) sender ;
    MessageBox.Show ( control.Text + "被按动了!");
    }
    else 
    {
    TextBox control = ( TextBox ) sender ; 
    MessageBox.Show ( control.Text + "被按动了!" ) ;
    }
    }}
    }  
      

  8.   

    这个有很难吗?修改原来代码
        void addButton(int i) {// 新增的函数
            // 动态添加条件窗口控件的程序
            JButton jb = new JButton("" + nextId);
            
            jb.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e) {
                    jPanel1.remove(((JButton)e.getSource()).getParent());     
                    jPanel1.repaint();
    //Remove e.getSource() From 数组,
    ...
                }
                
            });
    由于 e.getSource()返回的就是你点击的Button,所以就应该可以了啊!!!
      

  9.   

    ChDw(米)的思路不错!可以试验一下!
      

  10.   

    借用ChDw(米)同志的思路,实现鼠标单击和双击删除按钮的代码:package untitled1;import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;/**
     * <p>Title: </p>
     * <p>Description: </p>
     * <p>Copyright: Copyright (c) 2005</p>
     * <p>Company: </p>
     * @author not attributable
     * @version 1.0
     */public class Frame1 extends JFrame {
      static int nextId = 0;
      static JButton[] mnJB = new JButton[30];
      static JLabel[] myLB= new JLabel[30];
      static JPanel[] myJP = new JPanel[30];
      JPanel jPanel1 = new JPanel();
      JButton jB_add = new JButton();
      JButton jB_close = new JButton();
      JLabel jLabel1 = new JLabel();
      Box box1;
      JScrollPane jScrollPane1 = new JScrollPane();
      public Frame1() {
        try {
          jbInit();
        }
        catch(Exception e) {
          e.printStackTrace();
        }
      }
      private void jbInit() throws Exception {//里面是纯粹布局的代码,可以省略不看
        box1 = Box.createVerticalBox();
        this.getContentPane().setLayout(null);
        this.setSize(new Dimension(420, 350));
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension screenSize = kit.getScreenSize(); //获得屏幕的大小
        this.setLocation(screenSize.width / 2 - 210, screenSize.height / 2 - 175);
        jPanel1.setBorder(BorderFactory.createLoweredBevelBorder());
        jB_add.setBounds(new Rectangle(73, 251, 73, 25));
        jB_add.setText("ok");
        jB_add.addActionListener(new Frame1_jB_add_actionAdapter(this));
        jB_close.setBounds(new Rectangle(264, 249, 73, 25));
        jB_close.setText("close");
        jB_close.addActionListener(new Frame1_jB_close_actionAdapter(this));
        jLabel1.setText("jLabel1");
        jLabel1.setBounds(new Rectangle(180, 261, 34, 16));
        box1.setBounds(new Rectangle(7, 9, 405, 228));
        this.getContentPane().add(jB_add, null);
        this.getContentPane().add(jB_close, null);
        this.getContentPane().add(jLabel1, null);
        this.getContentPane().add(box1, null);
        box1.add(jScrollPane1, null);
        jScrollPane1.getViewport().add(jPanel1, null);
         jPanel1.setLayout(new GridLayout(100, 0));
      }  void jB_close_actionPerformed(ActionEvent e) {//退出的按钮
        System.exit(0);
      }  void jB_add_actionPerformed(ActionEvent e) {//一个按钮用来新增
         addButton(nextId);
         jLabel1.setText(""+nextId);
         nextId++;
         this.setTitle(""+nextId);
      }
      void addButton(int i) {//新增的函数
      //动态添加条件窗口控件的程序
      JButton jb = new JButton(""+nextId);
      JLabel lb = new JLabel(""+nextId);
      JPanel jp = new JPanel();
      /*jb.addActionListener(new ActionListener(){
       public void actionPerformed(ActionEvent evt){
       //jPanel1.removeAll();
       jPanel1.remove(((JButton)evt.getSource()).getParent());
       jPanel1.repaint();
       }
      });去掉注释后就是鼠标单击了*/
    //下面是鼠标双击删除按钮的实现
      jb.addMouseListener(new MouseAdapter(){
       public void mouseClicked(MouseEvent me){
       int count=me.getClickCount();
       if(count==2){
       jPanel1.remove(((JButton)me.getSource()).getParent());
           jPanel1.repaint();
       }
       }
      });  jp.setBorder(BorderFactory.createEtchedBorder());
      jp.setLayout(new GridLayout(0, 2));
      jPanel1.add(jp);
      jp.add(jb);
      jp.add(lb);  mnJB[nextId] = jb;
      myLB[nextId] = lb;
      myJP[nextId] = jp;
      }  static public void main(String[] args) {//主函数
      Frame1 frame = new Frame1();
      frame.setVisible(true);
    }}class Frame1_jB_close_actionAdapter implements java.awt.event.ActionListener {
      Frame1 adaptee;  Frame1_jB_close_actionAdapter(Frame1 adaptee) {
        this.adaptee = adaptee;
      }
      public void actionPerformed(ActionEvent e) {
        adaptee.jB_close_actionPerformed(e);
      }
    }class Frame1_jB_add_actionAdapter implements java.awt.event.ActionListener {
      Frame1 adaptee;  Frame1_jB_add_actionAdapter(Frame1 adaptee) {
        this.adaptee = adaptee;
      }
      public void actionPerformed(ActionEvent e) {
        adaptee.jB_add_actionPerformed(e);
      }
    }
      

  11.   

    给大家看一个别的论坛有人帮我写的,完全实现我的功能,可以给这里的朋友一点提示。唯一不足的是,我必须有静态的数组,保存这些控件,当控件被删除后,数组中后面的值,向前移动,最后要保持,这个数组中的各个值,完全和界面上看到的顺序一样。他刚好把这个关键的部分删掉了=========================================
    package untitled1;import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;public class Frame2 extends JFrame {
    JPanel jPanel1 = new JPanel();
    JButton jB_add = new JButton();
    JButton jB_close = new JButton();
    JLabel jLabel1 = new JLabel();
    Box box1;
    JScrollPane jScrollPane1 = new JScrollPane();int nextId = 0;public Frame2() {
    try {
    jbInit();
    }
    catch(Exception ex) {
    ex.printStackTrace();
    }
    }void jbInit() throws Exception {
    box1 = Box.createVerticalBox();
    this.getContentPane().setLayout(null);
    this.setSize(new Dimension(420, 350));
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize(); //获得屏幕的大小
    this.setLocation(screenSize.width / 2 - 210, screenSize.height / 2 - 175);
    jPanel1.setBorder(BorderFactory.createLoweredBevelBorder());
    jB_add.setBounds(new Rectangle(73, 251, 73, 25));
    jB_add.setText("ok");
    jB_add.addActionListener(new Frame2_jB_add_actionAdapter(this));
    jB_close.setBounds(new Rectangle(264, 249, 73, 25));
    jB_close.setText("close");
    jB_close.addActionListener(new Frame2_jB_close_actionAdapter(this));
    jLabel1.setText("jLabel1");
    jLabel1.setBounds(new Rectangle(180, 261, 34, 16));
    box1.setBounds(new Rectangle(7, 9, 405, 228));
    this.getContentPane().add(jB_add, null);
    this.getContentPane().add(jB_close, null);
    this.getContentPane().add(jLabel1, null);
    this.getContentPane().add(box1, null);
    box1.add(jScrollPane1, null);
    jScrollPane1.getViewport().add(jPanel1, null);
    jPanel1.setLayout(new GridLayout(100, 0));
    }void jB_close_actionPerformed(ActionEvent e) { //退出的按钮
    System.exit(0);
    }void jB_add_actionPerformed(ActionEvent e) { //一个按钮用来新增
    addChildPanel(nextId);
    jLabel1.setText("" + nextId);
    nextId++;
    this.setTitle("" + nextId);
    }void addChildPanel(int nextId) {
    ChildPanel cp = new ChildPanel(nextId, this.jPanel1);
    this.jPanel1.add(cp);
    }public static void main(String[] args) {
    Frame2 f = new Frame2();
    f.setVisible(true);
    }
    }class Frame2_jB_close_actionAdapter
    implements java.awt.event.ActionListener {
    Frame2 adaptee;Frame2_jB_close_actionAdapter(Frame2 adaptee) {
    this.adaptee = adaptee;
    }public void actionPerformed(ActionEvent e) {
    adaptee.jB_close_actionPerformed(e);
    }
    }class Frame2_jB_add_actionAdapter
    implements java.awt.event.ActionListener {
    Frame2 adaptee;Frame2_jB_add_actionAdapter(Frame2 adaptee) {
    this.adaptee = adaptee;
    }public void actionPerformed(ActionEvent e) {
    adaptee.jB_add_actionPerformed(e);
    }
    }package untitled1;import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;public class ChildPanel extends JPanel {int nextId;
    JPanel parent;JButton jb;
    JLabel lb;public ChildPanel(int nextId, JPanel parent) {
    this.nextId = nextId;
    this.parent = parent;
    this.jb = new JButton("" + nextId);
    this.lb = new JLabel("" + nextId);
    this.add(lb);
    this.add(jb);this.jb.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    removePancel();
    }
    });
    }void removePancel() {
    this.setVisible(false);
    this.parent.remove(this);
    }
    }
      

  12.   

    对于是否回收的问题,我实在不知道JVM的回收是怎么回事,是在内存中回收按钮所占的资源吗?但JVM不是有自动回收机制吗——对于没有用的组件,JVM应该会自动GC它吧
    不过要让它自动上移,则是很好办的,在jPanel1.repaint();后加一句jPanel1.revalidate();让容器在每次删除按钮后重新布局就可以了。
      

  13.   

    如果不能回收,和那么我在下一步收集这些组件的数据的时候的时候就会有问题我之所以设计了几个静态的数组,就是为了收集这些组件的texe值
    但是因为这些值是可以让用户随便改了——我收集的是最终结果
      

  14.   

    to :drugon(想换工作,准备跳槽........................................) 
    可否相告gc()是什么东西 谢谢
      

  15.   

    抢着回答问题,呵呵。
    gc()就是“传说中”的Java的垃圾收集器,神奇吧!!