Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 滚动条没有';不要在喷气式飞机内的JScrollPanel上工作_Java_Swing_Scrollbar_Jscrollpane - Fatal编程技术网

Java 滚动条没有';不要在喷气式飞机内的JScrollPanel上工作

Java 滚动条没有';不要在喷气式飞机内的JScrollPanel上工作,java,swing,scrollbar,jscrollpane,Java,Swing,Scrollbar,Jscrollpane,我试图编写一个JPane,它有一个JScrollPane,我想在其中实时添加面板。我的意思是,我有一些组件,其中一个是一个按钮,它将另一个JPane添加到JScrollPane中的主JPane(secundario)中。问题是,当它添加一些覆盖超过窗口大小的面板时,我放置的滚动条不会移动,因此我无法向下查看下面的面板(它应该是一个垂直滚动条)。我将代码留在这里: 旧代码: private JPanel panelModulos() { JPanel raiz = new JPan

我试图编写一个JPane,它有一个JScrollPane,我想在其中实时添加面板。我的意思是,我有一些组件,其中一个是一个按钮,它将另一个JPane添加到JScrollPane中的主JPane(secundario)中。问题是,当它添加一些覆盖超过窗口大小的面板时,我放置的滚动条不会移动,因此我无法向下查看下面的面板(它应该是一个垂直滚动条)。我将代码留在这里:

旧代码:

    private JPanel panelModulos() {
    JPanel raiz = new JPanel();
    raiz.setLayout(new GridLayout(1, 1));
    raiz.setPreferredSize(new Dimension(490, 790));

    // Lo que guarda el contenedor
    secundario = new JPanel();
    secundario.setPreferredSize(maximumSize);

    // Deficicion del formato
    JLabel etModuloDir = etiqueta("Directorio");
    JLabel etModuloNombre = etiqueta("Nombre");
    JButton botAnModulo = boton("Añadir", "addModulo", 'A', icon("Iconos/addMod_opt.png"));
    JButton botElModulo = boton("Eliminar", "delModulo", 'E', icon("Iconos/delMod_opt.png"));
    JTextField txtNomMod = texto("", "Nombre", true, 25);
    JTextField txtDirMod = texto("", "Directorio", true, 25);
    txtDirMod.setMaximumSize(maximumSize);
    txtNomMod.setMaximumSize(maximumSize);

    // Contenedor de botones y etiquetas
    JPanel tercero = new JPanel();
    tercero.add(etModuloDir);
    tercero.add(txtDirMod);
    tercero.add(etModuloNombre);
    tercero.add(txtNomMod);
    tercero.add(botAnModulo);
    tercero.add(botElModulo);

    secundario.add(tercero);

    principal = new JScrollPane(secundario);
    principal.setPreferredSize(new Dimension(490, 790));
    principal.setVerticalScrollBar(principal.createVerticalScrollBar());
    principal.setWheelScrollingEnabled(true);
    principal.getVerticalScrollBar().setEnabled(true);
    principal.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    raiz.add(principal);

    return raiz;
}
更新: 好吧,我把代码缩减到最低限度,这样你就可以在任何地方运行程序了。在我的问题所在的窗口中显示问题,其余窗口正常工作。 控制该窗口的函数名为panelModulos();我试图做的是将这些组件添加到面板中,当我按下“añadir”按钮时,它会创建另一个JPanel,该JPanel具有相同的组件,并且位于旧面板下方(以列为单位);问题是现在的大小和垂直滚动条,当我添加一些占据超过窗口大小的面板时,垂直滚动条不起作用

代码:

封装问题;
导入java.awt.BorderLayout;
导入java.awt.Checkbox;
导入java.awt.CheckboxGroup;
导入java.awt.Component;
导入java.awt.Dimension;
导入java.awt.FlowLayout;
导入java.awt.GridLayout;
导入java.awt.TextArea;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.ItemEvent;
导入java.awt.event.ItemListener;
导入java.awt.event.WindowAdapter;
导入java.awt.event.WindowEvent;
导入java.io.File;
导入java.sql.Connection;
导入java.util.ArrayList;
导入java.util.EventObject;
导入javax.swing.Icon;
导入javax.swing.ImageIcon;
导入javax.swing.JButton;
导入javax.swing.JCheckBox;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JMenu;
导入javax.swing.JMenuBar;
导入javax.swing.JMenuItem;
导入javax.swing.JOptionPane;
导入javax.swing.JPanel;
导入javax.swing.JPasswordField;
导入javax.swing.JScrollPane;
导入javax.swing.JTabbedPane;
导入javax.swing.JTextField;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
导入javax.swing.filechooser.FileNameExtensionFilter;
/**
*Clase mainApp
*
*格拉菲卡国际酒店。
* 
*@作者
*@作者
* 
*@version 1.0
*
*/
公共类probMain实现ActionListener、ItemListener{
/*
*阿皮利卡翁酒店
*/
私人JButton btnBBDDRep,btnEliminarAntena,btnEliminarPA,btnanadirpaf,btnanadirpa,btnAddRed,
btnEliminarRed、Btneliminarrata、Btnanadiredif、Btneliminarredif、rutaPA1、rutaPA2、cargarDatos、,
Iniciaarlocalizacion、terminarLocalizacion、conectar、iniciar、obtenerDatos、logs;
/*
*阿皮利卡翁营地
*/
私人JTextField txtrlbddrep、txtDriverBBDDRep、txtsuariobbddrep、财务、财务、tuser、tclase、turl;
私有JTextField txtdirecioni=texto(“,“Dirección del edificio”,真,20);
私人JTextField txtTelefonoI=texto(“,“大厦电话”),正确,20);
私有JTextField txtxtx=texto(“,“Posicon X de la antena”,真,3);
私有JTextField txtY=texto(“,“Posicion Y de la antena”,真,3);
私有JTextField txtZ=texto(“,“天线位置”,真,3);
私有JTextField txtDCC=texto(“\\\\192.168.0.0\\publico”,“Direccion de la ru毯a compatida”,真,17);
私有JTextField txtAlcance=texto(“,“AlcanceAntena”,真,5);
私有JTextField txtModelo=texto(“,”ModeloAntena“,true,5);
私有JTextField txtAncho=texto(“,“建筑物的植物”,真,3);
私有JTextField txtAlto=texto(“,“大厦的植物之声”,真,3);
私有JTextField txtlago=texto(“,”建筑工人协会“,真,3);
私有JTextField txtEPA2=texto(“,”巴勒斯坦大厦“,真,10);
私有JTextField txtPPA2=texto(“,”PPlanta del PA“,真,4);
私有JTextField txtEPA=texto(“,“大厦大厦”,真,10);
私有JTextField txtPPA=texto(“,“车前草”,真,4);
私有JTextField txtRed=texto(“,“Red del PA”,真,6);
/*
*Áreas de texto de la aplicación
*/
私有TextArea localizaciontexto=newtextarea(),areatexto=newtextarea();
私人JCheckBox jchx;
私有JComboxElist,pList,antList,antList2,antList3,大厦列表,大厦列表1,大厦列表2,
建筑物列表3,植物列表,植物列表2,植物列表3,栅栏,栅栏2,栅栏3,PA1列表;
私人支票箱组cbg1、cbg2、cbg3;
专用复选框modEd、modPl、modPA、modAnt、jchxFiltro1、jchxFiltro3、jchxFiltro4;
私人JPasswordField tpass,tpassclavebddrep;
二等兵;
私人JFrame cR、cE、cPA、cD;
私有字符串edif=null;
私有字符串planta=null;
私有字符串fIni=null;
私有字符串fFin=null;
静态字符串密码=”;
专用连接conexion、conexionRep、conexionMejora;
私有字符串[]Edificios={”“};
私有字符串[]Plantas={”“};
私有字符串[]PuntosAcceso1={”“};
私有字符串[]天线={”“};
专用文件fichero1、fichero2;
private FileNameExtensionFilter filtroFicherotxt=新FileNameExtensionFilter(“Archivos.txt”、“txt”);
私有字符串rutPA1、rutPA2;
//托多阿尼多约
私有JTextField txtFuera=texto(“,“Fuera(0,1)”,true,2);
私有JTextField txtRssiMin=texto(“,“RSSI mínimo”,真,3);
私有JTextField txtRssiMax=texto(“,“RSSI máximo”,真,3);
私有JTextField-mejorabbddText;
私有ArrayList listFichDatos;
私有ArrayList listFichDisp;
私人JTextField macdispreto;
私有ArrayList listDispConcretos;
私有线程捕获器;
私有线程本地化;
私人JComboBox Puntosacceso;
私有ArrayList listPAActivar;
私人ArrayList rutasModulos;
私有ArrayList参数;
//许可证是国际贸易的基本要素
私人JPanel secundario;
私有维度最大值;
package problem;

import java.awt.BorderLayout;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.EventObject;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 * Clase mainApp
* <p>
 * Interfaz gráfica.
 * 
 * @author <a href="mailto:bgs0010@alu.ubu.es">Berta García Sanz</a>
  * @author <a href="mailto:hma0002@alu.ubu.es">Héctor Mamolar Albitre</a>
 * 
 * @version 1.0
 *
 */

public class probMain implements ActionListener, ItemListener {

/*
 * Botones de la aplicación
 */
private JButton btnBBDDRep, btnEliminarAntena, btnEliminarPA, btnAnnadirPAf, btnAnnadirPA, btnAddRed,
        btnEliminarRed, btnEliminarPlanta, btnAnnadirEdif, btnEliminarEdif, rutaPA1, rutaPA2, cargarDatos,
        iniciarLocalizacion, terminarLocalizacion, conectar, iniciar, obtenerDatos, logs;

/*
 * Campos de la aplicación
 */
private JTextField txtUrlBBDDRep, txtDriverBBDDRep, txtUsuarioBBDDRep, finicial, ffinal, tuser, tclase, turl;
private JTextField txtDireccionI = texto("", " Dirección del edificio ", true, 20);
private JTextField txtTelefonoI = texto("", " Teléfono del edificio ", true, 20);
private JTextField txtX = texto("", " Posicion X de la antena ", true, 3);
private JTextField txtY = texto("", " Posicion Y de la antena ", true, 3);
private JTextField txtZ = texto("", " Posicion Z de la antena ", true, 3);
private JTextField txtDCC = texto("\\\\192.168.0.0\\publico", " Direccion de la carpeta compartida ", true, 17);
private JTextField txtAlcance = texto("", " AlcanceAntena ", true, 5);
private JTextField txtModelo = texto("", " ModeloAntena ", true, 5);
private JTextField txtAncho = texto("", " Ancho de planta del edificio ", true, 3);
private JTextField txtAlto = texto("", " Alto de planta del edificio ", true, 3);
private JTextField txtLargo = texto("", " Largo de planta del edificio ", true, 3);
private JTextField txtEPA2 = texto("", " Edificio del PA ", true, 10);
private JTextField txtPPA2 = texto("", " PPlanta del PA ", true, 4);
private JTextField txtEPA = texto("", " Edificio del PA ", true, 10);
private JTextField txtPPA = texto("", " Planta del PA ", true, 4);
private JTextField txtRed = texto("", " Red del PA ", true, 6);

/*
 * Áreas de texto de la aplicación
 */
private TextArea localizaciontexto = new TextArea(), areatexto = new TextArea();
private JCheckBox jchx;
private JComboBox<String> eList, pList, antList, antList2, antList3, edificiosList, edificiosList1, edificiosList2,
        edificiosList3, plantasList, plantasList2, plantasList3, PAList, PAList2, PAList3, PA1List;
private CheckboxGroup cbg1, cbg2, cbg3;
private Checkbox modEd, modPl, modPA, modAnt, jchxFiltro1, jchxFiltro3, jchxFiltro4;
private JPasswordField tpass, tpassClaveBBDDRep;
private JMenu men;
private JFrame cR, cE, cPA, cD;
private String edif = null;
private String planta = null;
private String fIni = null;
private String fFin = null;
static String password = "";
private Connection conexion, conexionRep, conexionMejora;
private String[] Edificios = { "" };
private String[] Plantas = { "" };
private String[] PuntosAcceso1 = { "" };
private String[] Antenas = { "" };
private File fichero1, fichero2;
private FileNameExtensionFilter filtroFicherotxt = new FileNameExtensionFilter("Archivos .txt", "txt");
private String rutPA1, rutPA2;

// TODO añadido yo
private JTextField txtFuera = texto("", "Fuera (0,1)", true, 2);
private JTextField txtRssiMin = texto("", "RSSI mínimo", true, 3);
private JTextField txtRssiMax = texto("", "RSSI máximo", true, 3);
private JTextField mejorabbddText;
private ArrayList<File> listFichDatos;
private ArrayList<File> listFichDisp;
private JTextField macDispConcreto;
private ArrayList<String> listDispConcretos;
private Thread capturas;
private Thread localizaciones;
private JComboBox<String> boxPuntosAcceso;
private ArrayList<String> listPAActivar;
private ArrayList<String> rutasModulos;
private ArrayList<String> parametros;
// Permite ir añadiendo elementos a la interfaz tras inicializarlo
private JPanel secundario;
private Dimension maximumSize;
private ArrayList<JPanel> panelesModulos;
private JScrollPane principal;

public static void main(String args[]) {
    probMain apli = new probMain(508, 808);
}

// -------------
// CONSTRUCTOR
// -------------

/**
 * Constructor de la clase
 * 
 * @param alt
 *            - Altura de la ventana del interfaz de la aplicación
 * @param anch
 *            - Anchura de la ventana del interfaz de la aplicación
 */
public probMain(int alt, int anch) {

    listFichDatos = new ArrayList<File>();
    listFichDisp = new ArrayList<File>();
    listDispConcretos = new ArrayList<String>();
    listPAActivar = new ArrayList<String>();

    panelesModulos = new ArrayList<JPanel>();

    try {

        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        JFrame f = new JFrame("Universidad de Burgos - Sistema de Localización GUI 2.0");
        f.setIconImage(new ImageIcon("Iconos/ubu.png").getImage());
        f.setSize(anch, alt);
        f.setJMenuBar(menu());
        f.setContentPane(tabpanel());
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

    } catch (ClassNotFoundException e) {
        JOptionPane.showMessageDialog(new JFrame(), e + "\n Clase No encontrada desempaquetando objeto",
                "Excepción java.lang", JOptionPane.WARNING_MESSAGE, null);
    } catch (InstantiationException e) {
        JOptionPane.showMessageDialog(new JFrame(), e + "\n Excepcion instanciando clase de Aspecto",
                "Excepción java.lang", JOptionPane.WARNING_MESSAGE, null);
    } catch (IllegalAccessException e) {
        JOptionPane.showMessageDialog(new JFrame(), e + "\n Acceso ilegal a clase de Aspecto",
                "Excepción java.lang", JOptionPane.WARNING_MESSAGE, null);
    } catch (UnsupportedLookAndFeelException e) {
        JOptionPane.showMessageDialog(new JFrame(), e + "\n Clase de Aspecto no soportada", "Excepción javax.swing",
                JOptionPane.WARNING_MESSAGE, null);
    }
}

// ---------------------
// UTILERIA de INTERFAZ
// ---------------------

/**
 * Creación de los componentes principales del menú.
 * 
 * @return JMenuBar Barra de menú de la aplicación
 */
private JMenuBar menu() {
    JMenuBar mBar = new JMenuBar();
    mBar.add(menuConf('Z', "Configuración"));
    mBar.add(menuTitulo('A', "Ayuda"));
    return (mBar);
}

/**
 * Metodo que crea un submenú del menú principal.
 * 
 * @param mnemonic
 *            Nemotécnico del submenú
 * @param nombre
 *            Nombre del submenú
 * @return JMenu Menú de ayuda
 */
private JMenu menuTitulo(char mnemonic, String nombre) {
    JMenu men = new JMenu(nombre);
    men.setMnemonic(mnemonic);
    men.add(objetoMenu("Acerca de...", 'c', "acerca"));
    return (men);
}

/**
 * Metodo que crea un submenú con tres componentes de configuración del menú
 * principal.
 * 
 * @param mnemonic
 *            Nemotécnico del submenú
 * @param nombre
 *            Nombre del submenú
 * @return JMenu Menú de configuración
 */
private JMenu menuConf(char mnemonic, String nombre) {
    men = new JMenu(nombre);
    men.setMnemonic(mnemonic);
    men.setEnabled(false);
    men.add(objetoMenu("Configuración Edificios", 'e', "confEdif"));
    men.add(objetoMenu("Configuración Puntos de Acceso y Red", 't', "confPA"));
    men.add(objetoMenu("Configuración Representación", 'r', "confRep"));
    return (men);
}

/**
 * Metodo que crea un objeto del menú.
 * 
 * @param nombre
 *            nombre del objeto a crear
 * @param mnemonic
 *            mnemonic
 * @param accion
 *            accion que realiza
 * @return JMenuItem objeto con el objeto implententado
 * 
 */
private JMenuItem objetoMenu(String nombre, char mnemonic, String accion) {
    JMenuItem mT = new JMenuItem(nombre, mnemonic);
    mT.setActionCommand(accion);
    mT.addActionListener(this);
    return (mT);
}

/**
 * Metodo que las pestañas de la ventana principal.
 * 
 * @return JTabbedPane Contenedor de pestañas de la interfaz
 */
private JTabbedPane tabpanel() {
    JTabbedPane jtp = new JTabbedPane();
    jtp.addTab("correct", panelConexion());
    jtp.addTab("correct", panelEscaneo());
    jtp.addTab("correct", panelObtenerDatos());
    jtp.addTab("PROBLEM", panelModulos());
    jtp.addTab("correct", panelLocalizarDisp());
    return (jtp);
}

// PANEL CONEXION BBDD
/**
 * Método que establece el formato deseado de la pestaña de configuración de
 * la base de datos.
 * 
 * @return JPanel Panel de conexión a la BBDD de localización
 */
private JPanel panelConexion() {

    JPanel raiz = new JPanel(new GridLayout(1, 1));
    return (raiz);
}

/**
 * Método que establece el formato deseado de la pestaña de escaneo de
 * redes.
 * 
 * @return JPanel Panel de escaneo de redes
 */
private JPanel panelEscaneo() {

    JPanel raiz = new JPanel(new GridLayout(2, 1));

    return (raiz);
}

/**
 * Método que establece el formato deseado de la pestaña de filtrado de
 * datos.
 * 
 * @return JPanel Panel de filtrado de datos
 */
private JPanel panelObtenerDatos() {

    JPanel raiz = new JPanel();

    return (raiz);
}

/**
 * Método que establece el formato deseado de la pestaña que añade módulos a
 * la aplicación.
 * 
 */
private JPanel panelModulos() {

    JPanel raiz = new JPanel();
    raiz.setLayout(new GridLayout(1, 1));

    // Deficicion del formato
    JLabel etModuloDir = etiqueta("Directorio");
    JLabel etModuloNombre = etiqueta("Nombre");
    JButton botAnModulo = boton("Añadir", "addModulo", 'A', icon("Iconos/addMod_opt.png"));
    JButton botElModulo = boton("Eliminar", "delModulo", 'E', icon("Iconos/delMod_opt.png"));
    JTextField txtNomMod = texto("", "Nombre", true, 25);
    JTextField txtDirMod = texto("", "Directorio", true, 25);
    // Lo que guarda el contenedor
    secundario = new JPanel();
    maximumSize = new Dimension(12, 12);

    etModuloDir.setMaximumSize(maximumSize);
    etModuloNombre.setMaximumSize(maximumSize);
    botAnModulo.setMaximumSize(maximumSize);
    botElModulo.setMaximumSize(maximumSize);
    txtNomMod.setMaximumSize(maximumSize);
    txtDirMod.setMaximumSize(maximumSize);

    GridLayout gridLay = new GridLayout(0, 6);
    BorderLayout borLay = new BorderLayout();

    // Contenedor de botones y etiquetas
    JPanel tercero = new JPanel();
    tercero.setMaximumSize(maximumSize);
    tercero.setLayout(gridLay);
    tercero.add(etModuloDir, BorderLayout.PAGE_START);
    tercero.add(txtDirMod, BorderLayout.PAGE_START);
    tercero.add(etModuloNombre, BorderLayout.PAGE_START);
    tercero.add(txtNomMod, BorderLayout.PAGE_START);
    tercero.add(botAnModulo, BorderLayout.PAGE_START);
    tercero.add(botElModulo, BorderLayout.PAGE_START);

    secundario.setLayout(borLay);
    secundario.add(tercero);

    principal = new JScrollPane(secundario, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    principal.setVerticalScrollBar(principal.createVerticalScrollBar());
    principal.setWheelScrollingEnabled(true);
    principal.getVerticalScrollBar().setEnabled(true);
    // principal.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    raiz.add(principal);

    return raiz;
}

/**
 * Método que establece el formato deseado de la pestaña de localización de
 * dispositivos.
 * 
 * @return JPanel Panel de localización
 */
private JPanel panelLocalizarDisp() {
    JPanel raiz = new JPanel(new FlowLayout(FlowLayout.LEFT));

    return (raiz);
}

/**
 * Método que establece las etiquetas de la interfaz.
 * 
 * @param texto
 *            Texto de la etiqueta
 * @return JLabel Etiqueta de la interfaz
 */
private JLabel etiqueta(String texto) {
    return (new JLabel(texto));
}

/**
 * Método que crea campo de texto.
 * 
 * @param texto
 *            Texto del campo
 * @param tooltip
 *            cadena con el tooltip
 * @param editable
 *            El campo es editable o no
 * @param columnas
 *            Tamaño del campo
 * @return JTextField Panel de escaneo de redes
 */
private JTextField texto(String texto, String tooltip, boolean editable, int columnas) {

    JTextField tf = new JTextField(texto, columnas);
    if (editable)
        tf.setEditable(true);
    else
        tf.setEditable(false);
    tf.setToolTipText(tooltip + texto);
    return (tf);
}

/**
 * Método que crea los botones de la interfaz.
 * 
 * @param nombre
 *            Nombre del botón
 * @param accion
 *            Acción del botón
 * @param memo
 *            Nemotécnico del botón
 * @param icon
 *            Icono asociado al botón
 * @return JPanel Panel de escaneo de redes
 */
private JButton boton(String nombre, String accion, char memo, Icon icon) {
    JButton b = new JButton(nombre, icon);
    b.setActionCommand(accion);
    b.setMnemonic(memo);
    b.addActionListener(this);
    return (b);
}

/**
 * Método que obtiene el icono.
 * 
 * @param ruta
 *            Ruta en la que se encuentra ubicado el icono
 * @return JPanel Panel de escaneo de redes
 */
private ImageIcon icon(String ruta) {
    return (new ImageIcon(ruta));
}

/**
 * Método que devuelve el panel de los que hay en la pestaña de módulos al
 * que se corresponde el objeto botón que se recibe como parámetro.
 * 
 * @param bot
 *            botón a buscar entre los paneles de los módulos de mejora.
 * @return panel correspondiente al botón.
 */
private Component getPanel(JButton bot) {
    for (JPanel panel : panelesModulos) {
        for (int i = 0; i < panel.getComponentCount(); ++i) {
            if (panel.getComponent(i).equals(bot)) {
                return panel;
            }
        }
    }
    return null;
}

/**
 * Añade un panel con sus correspondientes componentes a la pestaña de
 * módulos para que se introduzca otro.
 */
private void añadeFilaModulos() {
    JLabel etModuloDir = etiqueta("Directorio");
    JLabel etModuloNombre = etiqueta("Nombre");
    JButton botAnModulo = boton("Añadir", "addModulo", 'A', icon("Iconos/addMod_opt.png"));
    JButton botElModulo = boton("Eliminar", "delModulo", 'E', icon("Iconos/delMod_opt.png"));
    JTextField txtNomMod = texto("", "Nombre", true, 25);
    JTextField txtDirMod = texto("", "Directorio", true, 25);
    txtDirMod.setMaximumSize(maximumSize);
    txtNomMod.setMaximumSize(maximumSize);

    JPanel tercero = new JPanel();
    tercero.add(etModuloDir);
    tercero.add(txtDirMod);
    tercero.add(etModuloNombre);
    tercero.add(txtNomMod);
    tercero.add(botAnModulo);
    tercero.add(botElModulo);

    panelesModulos.add(tercero);
    secundario.add(tercero);
    secundario.revalidate();
    secundario.repaint();

    principal.revalidate();
    principal.repaint();
}

/**
 * Borra un panel y sus componentes y además los datos del módulo
 * correspondiente.
 * 
 * @param e
 *            evento ocurrido al pulsar el botón de eliminar un módulo.
 */
private void borraFilaModulos(EventObject e) {
    // Elimina el panel correspondiente
    secundario.remove(getPanel((JButton) e.getSource()));
    secundario.revalidate();
    secundario.repaint();

    principal.revalidate();
    principal.repaint();
}

// ---------
// OYENTES
// ---------
// Oyente de Botones
public void actionPerformed(ActionEvent e) {

    // Añade los datos del módulo a la base de datos y añade una nueva fila
    // para poner otro módulo.
    if (e.getActionCommand().equals("addModulo")) {
        añadeFilaModulos();
    }

    if (e.getActionCommand().equals("delModulo")) {
        borraFilaModulos(e);
    }

}

/**
 * Procedimiento para llenar los datos de una planta de un edificio dado
 * como parametro segun los datos de la base de datos.
 * 
 * @param idEdificio
 *            edificio donde se encuentran las plantas
 */
protected void rellenarPlantas(String idEdificio) {

}

/**
 * Procedimiento para llenar los datos de una planta de un edificio dado
 * como parametro segun los datos de la base de datos.
 * 
 * @param idEdificio
 *            edificio donde se encuentran las plantas
 */
protected void rellenarPlantas2(String idEdificio) {

}

/**
 * Procedimiento para llenar los datos de una planta de un edificio dado
 * como parametro segun los datos de la base de datos.
 * 
 * @param idEdificio
 *            edificio donde se encuentran las plantas
 */
protected void rellenarPlantas3(String idEdificio) {

}

/**
 * Procedimiento para llenar los datos de una planta de un edificio dado
 * como parametro segun los datos de la base de datos.
 * 
 * @param idEdificio
 *            edificio donde se encuentran las plantas
 */
protected void rellenarPlantas4(String idEdificio) {

}

/**
 * Procedimiento para rellenar los datos de un punto de acceso según la base
 * de datos.
 * 
 * @param idEdificio
 *            edificio donde se encuentra el punto de acceso.
 * @param idPlanta
 *            planta en la que se encuentra el punto de acceso.
 */
protected void rellenarPAC1(String idEdificio, String idPlanta) {

}

/**
 * Procedimiento para rellenar los datos de un punto de acceso según la base
 * de datos.
 * 
 * @param idEdificio
 *            edificio donde se encuentra el punto de acceso.
 * @param idPlanta
 *            planta en la que se encuentra el punto de acceso.
 */
protected void rellenarPAC2(String idEdificio, String idPlanta) {

}

/**
 * Procedimiento para rellenar los datos de un punto de acceso según la base
 * de datos.
 * 
 * @param idEdificio
 *            edificio donde se encuentra el punto de acceso.
 * @param idPlanta
 *            planta en la que se encuentra el punto de acceso.
 */
protected void rellenarPAC3(String idEdificio, String idPlanta) {

}

/**
 * Procedimiento que rellena los datos de una antena conectada a un punto de
 * acceso pasado como parámetro.
 * 
 * @param idPA
 *            identificador del punto de acceso.
 */
protected void rellenarAnt1(String idPA) {

}

/**
 * Procedimiento que rellena los datos de una antena conectada a un punto de
 * acceso pasado como parámetro.
 * 
 * @param idPA
 *            identificador del punto de acceso.
 */
protected void rellenarAnt2(String idPA) {

}

/**
 * Procedimiento que rellena los datos de una antena conectada a un punto de
 * acceso pasado como parámetro.
 * 
 */
protected void rellenarAnt3() {

}

/**
 * Procedimiento que rellena los datos de la red según la antena a la que
 * esté conectada que se pasa como parámetro.
 * 
 * @param idAntena
 *            identificador de la antena.
 */
protected void rellenarRed(String idAntena) {

}

/**
 * Rellena los datos del punto de acceso 1.
 * 
 * @param idEdificio
 *            identificador del edificio
 * @param idPlanta
 *            identificador de la planta
 */
protected void rellenarPA1(String idEdificio, String idPlanta) {

}

public void itemStateChanged(ItemEvent i) {
    if (i.getItemSelectable() == jchx) {
        if (i.getStateChange() == ItemEvent.SELECTED)
            jchx.setSelected(true);
        else
            jchx.setSelected(false);
    }
}

/**
 * Procedimiento que guarda la información obtenida en un fichero de texto
 * denominado HISTORIAL.txt.
 */
public void guardarInfo() {

}
secundario.setPreferredSize(maximumSize);
// holds a row of data
@SuppressWarnings("serial")
class RowPanel extends JPanel {
    private static final int COLS = 20;
    private JTextField txtDirMod = new JTextField(COLS);
    private JTextField txtNomMod = new JTextField(COLS);
    private ProbMain2 probMain2;
    private int minorStrut = 3;
    private int majorStrut = 6;

    // TODO: add tool tips, ...
    public RowPanel(ProbMain2 probMain2) {
        this.probMain2 = probMain2;
        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
        setBorder(BorderFactory.createEmptyBorder(minorStrut, minorStrut, minorStrut, minorStrut));
        add(new JLabel("Directorio"));
        add(Box.createHorizontalStrut(minorStrut));
        add(txtDirMod);
        add(Box.createHorizontalStrut(majorStrut));
        add(new JLabel("Nombre"));
        add(Box.createHorizontalStrut(minorStrut));
        add(txtNomMod);
        add(Box.createHorizontalStrut(majorStrut));
        add(new JButton(new AnadirAction()));
        add(Box.createHorizontalStrut(minorStrut));
        add(new JButton(new EliminarAction()));
    }

    // to extract data held in the JPanel
    public String getDir() {
        return txtDirMod.getText();
    }

    public String getNom() {
        return txtNomMod.getText();
    }

    private class AnadirAction extends AbstractAction {
        public AnadirAction() {
            super("Anadir");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // add new RowPanel to the main GUI
            probMain2.addRowPanel();
        }
    }

    private class EliminarAction extends AbstractAction {
        public EliminarAction() {
            super("Eliminar");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // tell main GUI to remove *this* RowPanel object
            probMain2.removeRowPanel(RowPanel.this);
        }
    }
}
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class ProbMain2 extends JPanel {
    private static final int PREF_W = 800;
    private static final int PREF_H = 500;
    // holds the rows, has grid layout with variable number of rows and one column:
    private JPanel rowHolderPanel = new JPanel(new GridLayout(0, 1));
    private List<RowPanel> rowPanelList = new ArrayList<>();

    public ProbMain2() {
        // panel below holds the rowHOlderPanel at the PAGE_START position
        JPanel borderLayoutPanel = new JPanel(new BorderLayout());
        borderLayoutPanel.add(rowHolderPanel, BorderLayout.PAGE_START);
        JScrollPane scrollPane = new JScrollPane(borderLayoutPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        addRowPanel();

        setLayout(new BorderLayout());
        add(scrollPane);
    }

    public void addRowPanel() {
        RowPanel rowPanel = new RowPanel(this);
        rowPanelList.add(rowPanel);
        rowHolderPanel.add(rowPanel);
        rowHolderPanel.revalidate();
        rowHolderPanel.repaint();
    }

    public void removeRowPanel(RowPanel row) {
        rowPanelList.remove(row);
        rowHolderPanel.remove(row);
        rowHolderPanel.revalidate();
        rowHolderPanel.repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private static void createAndShowGui() {
        ProbMain2 mainPanel = new ProbMain2();

        JFrame frame = new JFrame("ProbMain2");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }

}


// holds a row of data
@SuppressWarnings("serial")
class RowPanel extends JPanel {
    private static final int COLS = 20;
    private JTextField txtDirMod = new JTextField(COLS);
    private JTextField txtNomMod = new JTextField(COLS);
    private ProbMain2 probMain2;
    private int minorStrut = 3;
    private int majorStrut = 6;

    // TODO: add tool tips, ...
    public RowPanel(ProbMain2 probMain2) {
        this.probMain2 = probMain2;
        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
        setBorder(BorderFactory.createEmptyBorder(minorStrut, minorStrut, minorStrut, minorStrut));
        add(new JLabel("Directorio"));
        add(Box.createHorizontalStrut(minorStrut));
        add(txtDirMod);
        add(Box.createHorizontalStrut(majorStrut));
        add(new JLabel("Nombre"));
        add(Box.createHorizontalStrut(minorStrut));
        add(txtNomMod);
        add(Box.createHorizontalStrut(majorStrut));
        add(new JButton(new AnadirAction()));
        add(Box.createHorizontalStrut(minorStrut));
        add(new JButton(new EliminarAction()));
    }

    // to extract data held in the JPanel
    public String getDir() {
        return txtDirMod.getText();
    }

    public String getNom() {
        return txtNomMod.getText();
    }

    private class AnadirAction extends AbstractAction {
        public AnadirAction() {
            super("Anadir");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // add new RowPanel to the main GUI
            probMain2.addRowPanel();
        }
    }

    private class EliminarAction extends AbstractAction {
        public EliminarAction() {
            super("Eliminar");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // tell main GUI to remove *this* RowPanel object
            probMain2.removeRowPanel(RowPanel.this);
        }
    }
}