首页 > 解决方案 > 带有按钮的面板的 ArrayList 访问困难

问题描述

我的问题是:如何获取我的 CustomPanel 的对象,以便我能够访问它的字段(因为在我的真实程序中我有更多的字段)并且还能够从我的 ArrayList 中删除它?

我不知道如何在类窗口中实现一个 ActionListener,以某种方式在我的 Arraylist 中获取对象,其中包含被按下的按钮。

另外我想知道我是否能够以某种方式在类 CustomPanel 中实现一个 ActionListener,它可以影响作为我的类窗口实例的对象的行为。

我有以下代码:

public class Window extends JFrame{
 ArrayList<CustomPanel> aLCustomPanel = new ArrayList();
 JPanel jp = new JPanel();

 public Window() {
  for(int i=0;i<5;i++){
   aLCustomPanel.add(new CustomPanel());
   //here I could put the code from the 1 edit - see below
   jp.add(aLCustomPanel.get(i));
  }
  this.add(jp);
 }
 public static void main(String args[]){
  java.awt.EventQueue.invokeLater(new Runnable() {
   public void run() {
    new Window().setVisible(true);
   }
  });
 }
}


class CustomPanel extends JPanel {
 private JButton button;

 public CustomPanel(){
  button = new JButton("button");
  this.add(button);
 }

 public JButton getButton(){
  return this.button;
 }
} 

我的代码更长更奇怪,所以我试图提取(对于这个问题)导入的东西。

提前感谢您的帮助!


编辑:

例如:我想从 ArrayList 中删除按钮被按下的对象。

//imagine this comment in above code
aLCustomPanel.get(aLCustomPanel.size()-1).getButton().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                button_IwantToDeleteYou(e); //here I want to remove the panel, containing the button that got pressed from the above ArrayList, which is located in Class Window
            }
        });

edit2:添加了一个缺少的括号并修复了一些错误,代码现在应该可以了。

标签: javaarraylistactionlistener

解决方案


你的代码包含一些“空白”,即缺失代码,我将其填写如下:

  1. 添加了对 [ JFrame] 方法setDefaultCloseOperation()pack()和的调用setLocationByPlatform()。我建议您参考这些方法的javadoc以了解它们的作用。
  2. jp我为你的类中的类成员变量设置了一个布局管理器Window

是的,您需要在in 类中注册一个ActionListener,并且该侦听器应该驻留在您的类中 - 扩展的那个。JButtonCustomPanelWindowJFrame

这是我对您的代码的重写。请注意,我将班级名称更改WindowCusPanel以区分您的班级和java.awt.Window班级。并不是说它有什么不同,我只是不喜欢使用 JDK 中的类名。

import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class CusPanel extends JFrame implements ActionListener {
    private static final int COUNT = 5;

    private ArrayList<CustomPanel> aLCustomPanel = new ArrayList<>();
    private JPanel jp = new JPanel(new GridLayout(0, COUNT));

    public CusPanel() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        for (int i = 0; i < COUNT; i++) {
            aLCustomPanel.add(new CustomPanel(this));
            // here I could put the code from the 1 edit - see below
            jp.add(aLCustomPanel.get(i));
        }
        this.add(jp);
        pack();
        setLocationByPlatform(true);
    }

    public void actionPerformed(ActionEvent actionEvent) {
        Object source = actionEvent.getSource();
        if (source instanceof JButton) {
            JButton button = (JButton) source;
            Container parent = button.getParent();
            jp.remove(parent);
            jp.invalidate();
            jp.repaint();
            pack();
//            aLCustomPanel.remove(parent); <- optional
        }
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new CusPanel().setVisible(true);
            }
        });
    }
}

class CustomPanel extends JPanel {
    private JButton button;

    public CustomPanel(ActionListener parent) {
        button = new JButton("button");
        button.addActionListener(parent);
        this.add(button);
    }

    public JButton getButton() {
        return this.button;
    }
} 

请注意,删除 a 后CustomPanel,需要重新布置 GUI 组件,并且JFrame还应相应地调整大小。因此在actionPerformed()方法中,我调用invalidate(), thenrepaint()和 then pack()。我还认为,如果你CustomPanel从 GUI 中删除 a,你也应该从 中删除它ArrayList,但是,嘿,我仍然不明白你为什么要这样做,尽管我显然不知道你想要这样做背后的整个故事这首先。

当然,由于每个按钮(和每个CustomPanel)看起来都完全相同,因此您无法真正知道删除了哪个按钮。同样,我假设你看到了大局,而我没有。


推荐阅读