Java 动态儿童沟通

Java 动态儿童沟通,java,swing,listener,parent,Java,Swing,Listener,Parent,背景:我有一个JPanel(PanelCarga Extended JPanel),它显示的子JPanel(DatosArchivo Extended JPanel)与我希望在程序中打开的文件(n个DatosArchivo面板)一样多,用于不同的目的。此DatosArchivos包含一个“X”按钮,我希望它关闭此DatosArchivos面板,然后通知相应的面板Carga它已关闭,以便可以在其网格中重新组织剩余的n-1个DatosArchivo面板 Tha PanelCarga等级: p

背景:我有一个JPanel(PanelCarga Extended JPanel),它显示的子JPanel(DatosArchivo Extended JPanel)与我希望在程序中打开的文件(n个DatosArchivo面板)一样多,用于不同的目的。此DatosArchivos包含一个“X”按钮,我希望它关闭此DatosArchivos面板,然后通知相应的面板Carga它已关闭,以便可以在其网格中重新组织剩余的n-1个DatosArchivo面板

Tha PanelCarga等级:

    package gui;

    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    import java.sql.SQLException;
    import java.util.LinkedList;
    import javax.swing.GroupLayout;
    import javax.swing.GroupLayout.Alignment;
    import javax.swing.JButton;
    import javax.swing.JDialog;
    import javax.swing.JFileChooser;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextField;
    import javax.swing.LayoutStyle.ComponentPlacement;
    import logica.Cargador;

    public class PanelCarga extends JPanel {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private JTextField textField;
        private final JPanel panel = new JPanel();

        /**
         * Create the panel.
         */
        public PanelCarga() {

            JLabel lblArchivosA = new JLabel("Archivo (-s) a cargar");

            textField = new JTextField();
            textField.setEditable(false);
            textField.setColumns(10);

            final JScrollPane scrollPane = new JScrollPane();

            scrollPane.setViewportView(panel);
            panel.setLayout(new GridLayout(0, 2, 0, 0));

            JButton btnAbrir = new JButton("Abrir");
            btnAbrir.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    JFileChooser escoger = new JFileChooser();
                    escoger.setMultiSelectionEnabled(true);
                    int resultado = escoger.showOpenDialog(null);
                    File[] archivos = null;
                    String nombres = "";

                    if (resultado == JFileChooser.APPROVE_OPTION) {
                        archivos = escoger.getSelectedFiles();

                        for (int i = 0; i<archivos.length;i++){

                            if (i==0){
                                nombres = nombres + archivos [i].getName() ;
                            }else{
                                nombres = nombres + "; " +archivos [i].getName() ;
                            }                       

                            DatosArchivo datos = null;
                            try {
                                datos = new DatosArchivo();
                            } catch (SQLException e) {
                                JDialog error = new JDialog ();
                                error.setTitle("error");
                                JLabel mensaje = new JLabel(e.getMessage());
                                error.getContentPane().add(mensaje);
                                error.validate();                       
                            }
                            datos.textField_Ruta.setText(archivos[i].toString());
                            JTextField texto = new JTextField ();
                            texto.setBounds(10, 10, 100, 100);
                            panel.add(datos);

                        }

                        textField.setText(nombres);

                        panel.validate();
                        scrollPane.validate();
                    }


                }
            });


            GroupLayout groupLayout = new GroupLayout(this);
            groupLayout.setHorizontalGroup(
                groupLayout.createParallelGroup(Alignment.LEADING)
                    .addGroup(groupLayout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
                            .addComponent(scrollPane, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                            .addGroup(groupLayout.createSequentialGroup()
                                .addComponent(lblArchivosA)
                                .addGap(18)
                                .addComponent(textField, GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(btnAbrir)))
                        .addContainerGap())
            );
            groupLayout.setVerticalGroup(
                groupLayout.createParallelGroup(Alignment.LEADING)
                    .addGroup(groupLayout.createSequentialGroup()
                        .addGap(6)
                        .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
                            .addComponent(lblArchivosA)
                            .addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                            .addComponent(btnAbrir))
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 423, Short.MAX_VALUE)
                        .addContainerGap())
            );



            setLayout(groupLayout);

        }

        public LinkedList <Cargador> getCargadores (){
            LinkedList <Cargador> cargadores = new LinkedList <Cargador> ();

            for (int i = 0; i < panel.getComponentCount(); i++){
                cargadores.add(((DatosArchivo) panel.getComponent(i)).getCargador());
            }

            return cargadores;
        }


        public JPanel getPanel (){
            return this.panel;      
        }

    }

提前感谢

我不确定是否有最好的方法,但我认为有两种可能的方法:

一种方法是允许外部类向DatosArchivo中持有的btnX添加ActionListener,方法是为该类提供一个公共方法。比如:

   public void addbtnXActionListener(ActionListener listener) {
      btnX.addActionListener(listener);
   }
然后外部类可以根据需要从其显示中删除该JPanel。这样做的好处是,DatosArchivo不需要知道保存它的gui。当我这样做时,我还为DatosArchivo提供了一个公共getBtnX()方法来返回btnX JButton。这样我就可以匹配从ActionListener的actionPerformed方法的getSource方法获得的JButton,从而能够决定要处理哪个DatoArchivo对象

例如:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class Foo002 {

   private static void createAndShowUI() {
      JFrame frame = new JFrame("Foo002");
      frame.getContentPane().add(new PanelCarga2());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

@SuppressWarnings("serial")
class PanelCarga2 extends JPanel {
   private static final Dimension PREF_SIZE = new Dimension(600, 400);
   private JPanel datosArchivoContainer = new JPanel();
   private BtnXListener btnXListener = new BtnXListener();

   public PanelCarga2() {
      JButton btnAbrir = new JButton("Abrir");
      btnAbrir.addActionListener(new ActionListener() {
         int index = 1;
         public void actionPerformed(ActionEvent e) {
            DatosArchivo2 datosArchivo2 = new DatosArchivo2(index);
            datosArchivo2.addbtnXActionListener(btnXListener);
            datosArchivoContainer.add(datosArchivo2);
            datosArchivoContainer.revalidate();
            index++;
         }
      });

      JPanel topPanel = new JPanel();
      topPanel.add(btnAbrir);

      datosArchivoContainer.setLayout(new BoxLayout(datosArchivoContainer, BoxLayout.LINE_AXIS));
      JScrollPane scrollPane = new JScrollPane(datosArchivoContainer);
      scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

      setPreferredSize(PREF_SIZE);
      setLayout(new BorderLayout());
      add(topPanel, BorderLayout.PAGE_START);
      add(scrollPane, BorderLayout.CENTER);
   }

   private class BtnXListener implements ActionListener {
      public void actionPerformed(ActionEvent e) {
         Object source = e.getSource();
         Component[] components = datosArchivoContainer.getComponents();
         for (int i = components.length - 1; i >= 0; i--) {
            if (components[i] instanceof DatosArchivo2) {
               DatosArchivo2 datoArchivo = (DatosArchivo2) components[i];
               if (source.equals(datoArchivo.getBtnX())) {
                  datosArchivoContainer.remove(components[i]);   
               }
            }
         }
         datosArchivoContainer.revalidate();
         datosArchivoContainer.repaint();
      }
   }
}

@SuppressWarnings("serial")
class DatosArchivo2 extends JPanel {
   private JButton btnX = new JButton("X");

   public DatosArchivo2(int index) {
      setPreferredSize(new Dimension(200, 200));
      setBorder(BorderFactory.createEtchedBorder());
      add(btnX);
      add(new JLabel("Index: " + index));
   }

   public void addbtnXActionListener(ActionListener listener) {
      btnX.addActionListener(listener);
   }

   public JButton getBtnX() {
      return btnX;
   }
}
另一种方法是给DatosArchivo一个对其包含类的引用,然后让DatosArchivo对象处理自己的删除。这样做的缺点是,我相信会增加一些凝聚力。为此,我将包含PanelCarga的引用传递到DatosArchivo的构造函数中,然后给PanelCarga一个DatosArchivo方法将调用的公共RemoveDataSarchivo,并将其自身作为参数传递:

public void removeDatosArchivo(DatosArchivo3 datosArchivo) {
   datosArchivoContainer.remove(datosArchivo);
   datosArchivoContainer.revalidate();
   datosArchivoContainer.repaint();
}
整个示例程序如下所示:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class Foo003 {

   private static void createAndShowUI() {
      JFrame frame = new JFrame("Foo002");
      frame.getContentPane().add(new PanelCarga3());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

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

   private static final Dimension PREF_SIZE = new Dimension(600, 400);
   private JPanel datosArchivoContainer = new JPanel();

   public PanelCarga3() {
      JButton btnAbrir = new JButton("Abrir");
      btnAbrir.addActionListener(new ActionListener() {
         int index = 1;
         public void actionPerformed(ActionEvent e) {
            DatosArchivo3 datosArchivo3 = new DatosArchivo3(index, PanelCarga3.this);
            datosArchivoContainer.add(datosArchivo3);
            datosArchivoContainer.revalidate();
            index++;
         }
      });

      JPanel topPanel = new JPanel();
      topPanel.add(btnAbrir);

      datosArchivoContainer.setLayout(new BoxLayout(datosArchivoContainer, BoxLayout.LINE_AXIS));
      JScrollPane scrollPane = new JScrollPane(datosArchivoContainer);
      scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

      setPreferredSize(PREF_SIZE);
      setLayout(new BorderLayout());
      add(topPanel, BorderLayout.PAGE_START);
      add(scrollPane, BorderLayout.CENTER);
   }

   public void removeDatosArchivo(DatosArchivo3 datosArchivo) {
      datosArchivoContainer.remove(datosArchivo);
      datosArchivoContainer.revalidate();
      datosArchivoContainer.repaint();
   }
}

@SuppressWarnings("serial")
class DatosArchivo3 extends JPanel {
   private PanelCarga3 panelCarga;
   private JButton btnX = new JButton("X");

   public DatosArchivo3(int index, PanelCarga3 panelCarga) {
      this.panelCarga = panelCarga;
      btnX.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            btnXActionPerformed(e);
         }
      });
      setPreferredSize(new Dimension(200, 200));
      setBorder(BorderFactory.createEtchedBorder());
      add(btnX);
      add(new JLabel("Index: " + index));
   }

   private void btnXActionPerformed(ActionEvent e) {
      panelCarga.removeDatosArchivo(this);
   }
}

我不确定是否有最好的方法,但我认为有两种可能的方法:

一种方法是允许外部类向DatosArchivo中持有的btnX添加ActionListener,方法是为该类提供一个公共方法。比如:

   public void addbtnXActionListener(ActionListener listener) {
      btnX.addActionListener(listener);
   }
然后外部类可以根据需要从其显示中删除该JPanel。这样做的好处是,DatosArchivo不需要知道保存它的gui。当我这样做时,我还为DatosArchivo提供了一个公共getBtnX()方法来返回btnX JButton。这样我就可以匹配从ActionListener的actionPerformed方法的getSource方法获得的JButton,从而能够决定要处理哪个DatoArchivo对象

例如:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class Foo002 {

   private static void createAndShowUI() {
      JFrame frame = new JFrame("Foo002");
      frame.getContentPane().add(new PanelCarga2());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

@SuppressWarnings("serial")
class PanelCarga2 extends JPanel {
   private static final Dimension PREF_SIZE = new Dimension(600, 400);
   private JPanel datosArchivoContainer = new JPanel();
   private BtnXListener btnXListener = new BtnXListener();

   public PanelCarga2() {
      JButton btnAbrir = new JButton("Abrir");
      btnAbrir.addActionListener(new ActionListener() {
         int index = 1;
         public void actionPerformed(ActionEvent e) {
            DatosArchivo2 datosArchivo2 = new DatosArchivo2(index);
            datosArchivo2.addbtnXActionListener(btnXListener);
            datosArchivoContainer.add(datosArchivo2);
            datosArchivoContainer.revalidate();
            index++;
         }
      });

      JPanel topPanel = new JPanel();
      topPanel.add(btnAbrir);

      datosArchivoContainer.setLayout(new BoxLayout(datosArchivoContainer, BoxLayout.LINE_AXIS));
      JScrollPane scrollPane = new JScrollPane(datosArchivoContainer);
      scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

      setPreferredSize(PREF_SIZE);
      setLayout(new BorderLayout());
      add(topPanel, BorderLayout.PAGE_START);
      add(scrollPane, BorderLayout.CENTER);
   }

   private class BtnXListener implements ActionListener {
      public void actionPerformed(ActionEvent e) {
         Object source = e.getSource();
         Component[] components = datosArchivoContainer.getComponents();
         for (int i = components.length - 1; i >= 0; i--) {
            if (components[i] instanceof DatosArchivo2) {
               DatosArchivo2 datoArchivo = (DatosArchivo2) components[i];
               if (source.equals(datoArchivo.getBtnX())) {
                  datosArchivoContainer.remove(components[i]);   
               }
            }
         }
         datosArchivoContainer.revalidate();
         datosArchivoContainer.repaint();
      }
   }
}

@SuppressWarnings("serial")
class DatosArchivo2 extends JPanel {
   private JButton btnX = new JButton("X");

   public DatosArchivo2(int index) {
      setPreferredSize(new Dimension(200, 200));
      setBorder(BorderFactory.createEtchedBorder());
      add(btnX);
      add(new JLabel("Index: " + index));
   }

   public void addbtnXActionListener(ActionListener listener) {
      btnX.addActionListener(listener);
   }

   public JButton getBtnX() {
      return btnX;
   }
}
另一种方法是给DatosArchivo一个对其包含类的引用,然后让DatosArchivo对象处理自己的删除。这样做的缺点是,我相信会增加一些凝聚力。为此,我将包含PanelCarga的引用传递到DatosArchivo的构造函数中,然后给PanelCarga一个DatosArchivo方法将调用的公共RemoveDataSarchivo,并将其自身作为参数传递:

public void removeDatosArchivo(DatosArchivo3 datosArchivo) {
   datosArchivoContainer.remove(datosArchivo);
   datosArchivoContainer.revalidate();
   datosArchivoContainer.repaint();
}
整个示例程序如下所示:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class Foo003 {

   private static void createAndShowUI() {
      JFrame frame = new JFrame("Foo002");
      frame.getContentPane().add(new PanelCarga3());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

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

   private static final Dimension PREF_SIZE = new Dimension(600, 400);
   private JPanel datosArchivoContainer = new JPanel();

   public PanelCarga3() {
      JButton btnAbrir = new JButton("Abrir");
      btnAbrir.addActionListener(new ActionListener() {
         int index = 1;
         public void actionPerformed(ActionEvent e) {
            DatosArchivo3 datosArchivo3 = new DatosArchivo3(index, PanelCarga3.this);
            datosArchivoContainer.add(datosArchivo3);
            datosArchivoContainer.revalidate();
            index++;
         }
      });

      JPanel topPanel = new JPanel();
      topPanel.add(btnAbrir);

      datosArchivoContainer.setLayout(new BoxLayout(datosArchivoContainer, BoxLayout.LINE_AXIS));
      JScrollPane scrollPane = new JScrollPane(datosArchivoContainer);
      scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

      setPreferredSize(PREF_SIZE);
      setLayout(new BorderLayout());
      add(topPanel, BorderLayout.PAGE_START);
      add(scrollPane, BorderLayout.CENTER);
   }

   public void removeDatosArchivo(DatosArchivo3 datosArchivo) {
      datosArchivoContainer.remove(datosArchivo);
      datosArchivoContainer.revalidate();
      datosArchivoContainer.repaint();
   }
}

@SuppressWarnings("serial")
class DatosArchivo3 extends JPanel {
   private PanelCarga3 panelCarga;
   private JButton btnX = new JButton("X");

   public DatosArchivo3(int index, PanelCarga3 panelCarga) {
      this.panelCarga = panelCarga;
      btnX.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            btnXActionPerformed(e);
         }
      });
      setPreferredSize(new Dimension(200, 200));
      setBorder(BorderFactory.createEtchedBorder());
      add(btnX);
      add(new JLabel("Index: " + index));
   }

   private void btnXActionPerformed(ActionEvent e) {
      panelCarga.removeDatosArchivo(this);
   }
}

请编辑您的文章,选择完整代码,然后按{}代码标记请编辑您的文章,选择完整代码,然后按{}代码标记