背景:我有一个JPanel(PanelCarga扩展了JPanel),显示的子JPanels(DatosArchivo扩展了JPanel)与我希望在程序中打开的文件(n个DatosArchivo面板)一样多。这个DatosArchivos包含一个“ X”按钮,希望它关闭此DatosArchivos面板,然后通知相应的PanelCarga它已关闭,以便可以在他的网格中重组剩余的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类:
package gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.BevelBorder;
import logica.Cargador;
import logica.Conector;
public class DatosArchivo extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
public JTextField textField_Ruta;
private JTextField textField_Anio;
private JTextField textField_UbicacionNueva;
private String usuario = "rpatrizio";
private final JComboBox comboBox_Ubicacion ;
private JComboBox comboBox_Dia;
private JComboBox comboBox_mes;
/**
* Create the panel.
* @throws SQLException
*/
public DatosArchivo() throws SQLException {
setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
JPanel panel = new JPanel();
JLabel lblArchivo = new JLabel("Archivo:");
textField_Ruta = new JTextField();
textField_Ruta.setEditable(false);
textField_Ruta.setColumns(10);
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addContainerGap()
.addComponent(lblArchivo)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_Ruta, GroupLayout.DEFAULT_SIZE, 190, Short.MAX_VALUE)
.addContainerGap())
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(5)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(lblArchivo)
.addComponent(textField_Ruta, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
panel.setLayout(gl_panel);
JPanel panel_1 = new JPanel();
JLabel lblUbicación = new JLabel("Ubicaci\u00F3n");
textField_UbicacionNueva = new JTextField();
textField_UbicacionNueva.setEditable(false);
textField_UbicacionNueva.setColumns(10);
String [] ubicaciones = Conector.getUbicacion();
comboBox_Ubicacion = new JComboBox(ubicaciones);
comboBox_Ubicacion.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (comboBox_Ubicacion.getSelectedItem().toString().equals("Agregar Nueva")){
textField_UbicacionNueva.setEditable(true);
}else {
textField_UbicacionNueva.setEditable(false);
}
}
});
String [] dias = {"","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"};
String [] meses = {"","enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre"};
JPanel panel_2 = new JPanel();
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(panel, GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 296, Short.MAX_VALUE)
.addComponent(panel_2, GroupLayout.PREFERRED_SIZE, 296, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(8)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(panel_2, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addGap(16))
);
JLabel lblFecha = new JLabel("Fecha");
comboBox_Dia = new JComboBox(dias);
JLabel lblDe = new JLabel("de");
comboBox_mes = new JComboBox(meses);
JLabel lblDe_1 = new JLabel("de");
textField_Anio = new JTextField();
textField_Anio.setColumns(10);
JButton btnX = new JButton("X");
btnX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
}
});
GroupLayout gl_panel_2 = new GroupLayout(panel_2);
gl_panel_2.setHorizontalGroup(
gl_panel_2.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_2.createSequentialGroup()
.addContainerGap()
.addComponent(lblFecha)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(comboBox_Dia, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblDe)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(comboBox_mes, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblDe_1)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_Anio, GroupLayout.PREFERRED_SIZE, 38, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnX)
.addGap(49))
);
gl_panel_2.setVerticalGroup(
gl_panel_2.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_2.createSequentialGroup()
.addGap(5)
.addGroup(gl_panel_2.createParallelGroup(Alignment.BASELINE)
.addComponent(lblFecha)
.addComponent(comboBox_Dia, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblDe)
.addComponent(comboBox_mes, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblDe_1)
.addComponent(textField_Anio, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(btnX))
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
panel_2.setLayout(gl_panel_2);
JButton button = new JButton("+");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (textField_UbicacionNueva.getText().equals("") || !textField_UbicacionNueva.isEnabled() || !comboBox_Ubicacion.getSelectedItem().equals("Agregar Nueva")){
String message = "Ubicación nueva no disponible";
JOptionPane.showMessageDialog(new JFrame(), message, "Dialog", JOptionPane.ERROR_MESSAGE);
}else{
}
}
});
GroupLayout gl_panel_1 = new GroupLayout(panel_1);
gl_panel_1.setHorizontalGroup(
gl_panel_1.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_1.createSequentialGroup()
.addGap(6)
.addComponent(lblUbicación)
.addGap(5)
.addComponent(comboBox_Ubicacion, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(11)
.addComponent(textField_UbicacionNueva, GroupLayout.PREFERRED_SIZE, 91, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(button)
.addContainerGap())
);
gl_panel_1.setVerticalGroup(
gl_panel_1.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_1.createSequentialGroup()
.addGap(9)
.addComponent(lblUbicación))
.addGroup(gl_panel_1.createSequentialGroup()
.addGap(5)
.addGroup(gl_panel_1.createParallelGroup(Alignment.BASELINE)
.addComponent(comboBox_Ubicacion, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textField_UbicacionNueva, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(button)))
);
panel_1.setLayout(gl_panel_1);
setLayout(groupLayout);
}
public Cargador getCargador(){
return new Cargador (this.getRuta(),this.getUbicacion(),this.getFecha(),this.getUsuario());
}
public String getFecha (){
return this.getAnio()+"-"+this.getMes()+"-"+this.getDia().toString()+" 00:00:00.000";
}
public String getUsuario (){
return this.usuario;
}
public String getRuta (){
return this.textField_Ruta.getText();
}
public String getAnio(){
return this.textField_Anio.getText();
}
public String getMes(){
String mes = null;
if (this.comboBox_mes.getSelectedItem().toString().equals("enero")){
mes = "01";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("febrero")){
mes = "02";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("marzo")){
mes = "03";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("abril")){
mes = "04";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("mayo")){
mes = "05";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("junio")){
mes = "06";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("julio")){
mes = "07";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("agosto")){
mes = "08";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("septiembre")){
mes = "09";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("octubre")){
mes = "10";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("noviembre")){
mes = "11";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("diciembre")){
mes = "12";
}
return mes;
}
public String getDia(){
return this.comboBox_Dia.getSelectedItem().toString();
}
public String getUbicacion(){
if (this.comboBox_Ubicacion.getSelectedItem().toString().equals("Agregar Nueva")){
if (this.textField_UbicacionNueva.getText().equals("")){
return null;
}else {
return this.textField_UbicacionNueva.getText();
}
}else if (this.comboBox_Ubicacion.getSelectedItem().toString().equals("")){
return null;
}else {
return this.comboBox_Ubicacion.getSelectedItem().toString();
}
}
}
提前致谢
最佳答案
我不确定是否有最佳方法可以做到这一点,但我看到了两种可能的方法:
一种方法是允许外部类通过为该类提供一个公共方法来将ActionListener添加到DatosArchivo中保存的btnX中。就像是:
public void addbtnXActionListener(ActionListener listener) {
btnX.addActionListener(listener);
}
然后,外部类可以根据需要从其显示中删除该JPanel。这样做的好处是DatosArchivo不需要知道持有它的GUI。当我这样做时,我还为DatosArchivo提供了一个公共的getBtnX()方法来返回btnX JButton。这样一来,我就可以匹配从ActionListener的actionPerformed方法的getSource方法获得的JButton,从而能够确定要放置的DatosArchivo对象。
例如:
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提供了一个公开的removeDatosArchivo,DatosArchivo方法将调用该方法,并将自身作为参数传递:
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);
}
}
关于java - 动态 child 交流,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5913841/