java删除一个组件

时间:2011-08-23 20:42:44

标签: java swing

当前我可以通过按“添加”JButton将一堆自定义组件对象添加到JPanel。我还有一个“删除”JButton,我希望与“添加”相反。

我的意图是我可以用鼠标选择一个组件,然后单击删除按钮和pressto !,组件就消失了。

我将MouseListener挂钩到面板,并使用MouseEvent,e.getComponent()获取鼠标单击的w / e当前组件。因此,如果它返回自定义组件,则变量“private myComponent current”(已设置为null)将指向该组件。然后我可以点击“删除”按钮将其删除。已经在“删除”按钮中添加了一个actionListener,并在正文中调用了this.remove(current)(如果current不为null)。

但是,这不起作用,因为我无法删除组件!任何指针?

如果有一种优雅的方式来管理添加/删除组件,请建议!

public class MainDisplayPanel extends JPanel implements ActionListener, MouseListener{

private JButton newClassButton;
private JButton deleteButton;
private Resizable current;
private Resizable resizer;
public MainDisplayPanel(LayoutManager layout) {
    super(layout);

    newClassButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
            addResizer();
     }          
    });

    deleteButton = new JButton("Delete");
    deleteButton.addActionListener(this);
    this.addMouseListener(this);
    this.add(newClassButton);
    this.add(deleteButton);

}
public void addResizer() {
    //JPanel panel = new JPanel();
    //panel.setBackground(Color.white);
     resizer = new Resizable( new ClassBox());
    this.add(resizer);
    this.revalidate();
    this.repaint();
}

public void actionPerformed(ActionEvent e) {
          if(current!=null)
          {
              this.remove(current);
              this.revalidate();
              this.repaint();

          }
}

public void mouseClicked(MouseEvent e) {
    System.out.println(e);
            Component component = e.getComponent();

            if(component instanceof Resizable)
                current= (Resizable) e.getComponent();

}


    public static void main(String[] args) {
    JFrame jframe = new JFrame();
    jframe.add(new MainDisplayPanel(null));
    jframe.setSize(new Dimension(600,400));
    jframe.setVisible(true);
    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

} 卫生署!

现在,在addResizer()方法中。每次按下添加按钮添加新的Resizable对象时,以前添加的对象会发生什么?我确定它们变成了null因为resizer变量不再引用它们了吗???即使是这种情况,它们仍然显示在面板上......如果我按下删除,则只删除新添加的Resizable对象。我在这里走在正确的轨道上吗?

编辑:为了总结我的问题,我将MouseListener挂钩到错误的对象。应该是Resizable对象而不是面板。因此,可变电流始终为空。

3 个答案:

答案 0 :(得分:3)

这是非常疯狂的想法,但一切皆有可能,但

1)如果您使用JComponent部分LayoutManager进行了展示,则可以从JComponents删除Container,然后您必须/必须致电{{1} } + revalidate(),但此操作有副作用 - > repaint()然后Container的内容可能看起来非常ReLayout Container

2)如果您使用***放置Container,那应该是最好的但问题是AbsoluteLayout

中的emtpy空间是什么

有很简单的方法,您需要将Container添加到JPopupMenu

    Container
  • 您必须在RightMouseClick

    下找到JComponent
  • 然后致电MouseCursor,之后您必须致电Container#remove(myComponent) + revalidate()进行刷新GUI

或对我来说是一样的

答案 1 :(得分:3)

你的问题是你的MouseLisetener。您正在侦听MainDisplayPanel,因此当您单击JPanel时,您在mousePressed方法中返回的MouseEvent#getComponent方法将返回MainDisplayPanel实例,因为这是正在被侦听的内容,而不是Resizable实例。在老鼠的手下。

解决方案包括:

  • 创建一个MouseListener对象并将此同一对象添加到每个Resizable作为Resizable的MouseListener,或
  • 使用您当前的设置,但将您的Resizable保存在ArrayList中,然后在mousePressed方法中遍历数组列表,以查看是否已使用componentAt(...)方法单击任何Resizable。

请注意,我必须创建自己的SSCCE才能解决此问题。在将来再次,请帮助我们,为我们这样做,因为它符合您和我们的最大利益,并表明您尊重我们的时间和我们的帮助。

编辑1
我的SSCCE:

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.*;

@SuppressWarnings("serial")
public class MainDisplayPanel extends JPanel {
   private static final int RESIZABLE_COUNT = 40;
   private JButton deleteButton;
   private Resizable current;
   private Resizable resizer;
   private List<Resizable> resizableList = new ArrayList<Resizable>();

   public MainDisplayPanel(LayoutManager layout) {
      super(layout);

      deleteButton = new JButton("Delete");
      deleteButton.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            deleteButtonActionPerformed(e);
         }
      });
      this.addMouseListener(new MyMouseAdapter());
      this.add(deleteButton);

      for (int i = 0; i < RESIZABLE_COUNT; i++) {
         addResizer();
      }
   }

   private void deleteButtonActionPerformed(ActionEvent e) {
      if (current != null) {
         this.remove(current);
         resizableList.remove(current);
         current = null;
         this.revalidate();
         this.repaint();
      }
   }

   public void addResizer() {
      resizer = new Resizable();
      this.add(resizer);
      resizableList.add(resizer);
      this.revalidate();
      this.repaint();
   }

   private class MyMouseAdapter extends MouseAdapter {

      @Override
      public void mousePressed(MouseEvent e) {
         current = null;
         Component c = getComponentAt(e.getPoint());
         for (Resizable resizable : resizableList) {
            if (resizable == c) {
               current = resizable;
               resizable.setFill(true);
            } else {
               resizable.setFill(false);
            }
         }
      }
   }

   public static void main(String[] args) {
      JFrame jframe = new JFrame();
      // !! jframe.add(new MainDisplayPanel(null));
      jframe.add(new MainDisplayPanel(new FlowLayout()));
      jframe.setSize(new Dimension(600, 400));
      jframe.setVisible(true);
      jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }

}

@SuppressWarnings("serial")
class Resizable extends JPanel {

   private static final int RESIZE_WIDTH = 50;
   private static final int RESIZE_HEIGHT = 40;
   private static final int THICKNESS = 5;
   private static final Color FILL_COLOR = Color.pink;

   public Resizable() {
      Random rand = new Random();

      // different color border so we can see that it was the clicked one that was deleted.
      Color color = new Color(
               rand.nextInt(255), 
               rand.nextInt(255), 
               rand.nextInt(255));
      setBorder(BorderFactory.createLineBorder(color, THICKNESS));
   }

   @Override // so we can see it
   public Dimension getPreferredSize() {
      return new Dimension(RESIZE_WIDTH, RESIZE_HEIGHT);
   }

   public void setFill(boolean fill) {
      Color fillColor = fill ? FILL_COLOR : null;
      setBackground(fillColor);
      repaint();
   }

}

答案 2 :(得分:2)

我认为问题是您需要强制Swing在删除组件后再次布局组件。删除(当前)后,调用revalidate()。