uso usar una tabla pasar objetos mostrar llenar insertar guardar datos con como clase arreglo java swing file jtable repaint

java - usar - pasar datos de un vector a un jtable



¿Cómo buscar subcarpetas y volver a pintar una jTable con nuevos datos en Java? (1)

Estoy teniendo un par de problemas con mi programa. Quería que jTable mostrara varios puntos de datos agregados a TableModel, pero parece que no puedo obtener la tabla para actualizar con los nuevos datos.

Además, parece que mi búsqueda de imágenes png dentro de un directorio no ha logrado buscar realmente todas las imágenes png en el directorio y solo se detiene en los contenidos de la primera carpeta.

He colocado todos los puntos de datos en ArrayLists apropiados para sus tipos de datos y los he convertido en matrices de objetos antes de colocarlos en el modelo de tabla de mi jable. No funcionó, y no he podido resolver estos problemas con mi propio conocimiento.

Cierto código:

private void btnPatchSelActionPerformed(java.awt.event.ActionEvent evt) { fchsFolderChooser.showOpenDialog(null); File selFile = fchsFolderChooser.getSelectedFile(); fldPatchSel.setText(selFile.getPath()); File pngs[] = selFile.listFiles(IMAGE_FILTER); for (File png : pngs) { try {BufferedImage img = ImageIO.read(png); patchWs.add(img.getWidth()); patchHs.add(img.getHeight()); patchDims.add(img.getWidth() + "x" + img.getHeight()); patchImgs.add(img); patchImgPaths.add(png.getPath()); sels.add(false); System.out.println("Found " + png.getPath()); } catch (IOException e) { System.out.println("Bad image: " + png); e.printStackTrace(); } } if(!(fldPatchSel.getText().endsWith("...")||fldModSel.getText().endsWith("..."))) {BuildTable();} }

La contraparte de la selección de activos mod es análoga, pero sin configurar los sels ArrayList.

private void BuildTable(){ DefaultTableModel model = (DefaultTableModel) tblImgList.getModel(); Object[] boolSels = sels.toArray(); Object[] stringPatchPaths = patchImgPaths.toArray(); Object[] stringPatchImgDims = patchDims.toArray(); model.addColumn("", boolSels); model.addColumn("Patch Image", stringPatchPaths); model.addColumn("W x H", stringPatchImgDims); tblImgList.repaint(); }

¿Cómo resolverías mis dos problemas? El programa no busca subcarpetas y no puede mostrar datos nuevos en la tabla.


Primero, suelte el DefaultTableModel , su modelo de datos se está volviendo complejo. Comience con un POJO (Objeto simple de Java antiguo) que envuelve el contexto de lo que desea mostrar ...

public class ImageProperty { private File source; private Dimension size; private boolean selected; public ImageProperty(File source, Dimension size, boolean selected) { this.source = source; this.size = size; this.selected = selected; } public Dimension getSize() { return size; } public File getSource() { return source; } public boolean isSelected() { return selected; } }

Esto contiene toda la información para un único archivo de imagen y se usará para representar el contenido de una fila en la tabla.

Segundo, crea un TableModel personalizado. Esto es algo personal, pero con DefaultTableModel , pasas más tiempo pirateando el proceso intentando que haga lo que quieras, lo cual se resolvería mejor usando tu propio ...

public class ImageTableModel extends AbstractTableModel { private List<ImageProperty> images; public ImageTableModel() { images = new ArrayList<ImageProperty>(25); } @Override public int getRowCount() { return images.size(); } @Override public int getColumnCount() { return 4; } @Override public String getColumnName(int column) { String name = ""; switch (column) { case 1: name = "Path"; break; case 2: name = "Name"; break; case 3: name = "Size"; break; } return name; } @Override public Class<?> getColumnClass(int columnIndex) { return columnIndex == 0 ? Boolean.class : String.class; } @Override public Object getValueAt(int rowIndex, int columnIndex) { ImageProperty row = images.get(rowIndex); Object value = null; switch (columnIndex) { case 0: value = row.isSelected(); break; case 1: value = row.getSource().getParent(); break; case 2: value = row.getSource().getName(); break; case 3: value = row.getSize().width + "x" + row.getSize().height; break; } return value; } public void addImage(ImageProperty image) { images.add(image); fireTableRowsInserted(images.size() - 1, images.size() - 1); } public void addImages(List<ImageProperty> newImages) { int firstRow = images.size(); int lastRow = firstRow + newImages.size() - 1; images.addAll(newImages); fireTableRowsInserted(firstRow, lastRow); } public void clear() { int lastRow = images.size() -1; images.clear(); fireTableRowsDeleted(0, lastRow); } }

En tercer lugar, no intente escanear el directorio en el hilo de envío del evento, esto causará que la IU "pause" hasta que se complete el escaneo, y dependiendo del tamaño de sus imágenes y el número de subdirectorios, podría tomar unos minutos. completar.

Vea Concurrencia en Swing para más detalles ...

Hay muchas formas de superar esto, pero SwingWorker es probablemente el más simple, ya que proporciona la funcionalidad para proporcionar actualizaciones de EDT de forma segura, por lo que puede actualizar la interfaz de usuario sin causar más problemas ...

public class ScanWorker extends SwingWorker<Object, ImageProperty> { private File source; private ImageTableModel model; public ScanWorker(File source, ImageTableModel model) { this.source = source; this.model = model; } @Override protected void process(List<ImageProperty> chunks) { model.addImages(chunks); } @Override protected Object doInBackground() throws Exception { scan(source); return null; } protected void scan(File dir) { firePropertyChange("directory", dir.getParent(), dir); File pngs[] = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.getName().toLowerCase().endsWith(".png"); } }); for (File png : pngs) { try { BufferedImage img = ImageIO.read(png); publish(new ImageProperty(png, new Dimension(img.getWidth(), img.getHeight()), false)); } catch (IOException e) { System.out.println("Bad image: " + png); e.printStackTrace(); } } File dirs[] = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isDirectory(); } }); if (dirs != null && dirs.length > 0) { for (File subDir : dirs) { scan(subDir); } } } }

Este trabajador usa una llamada a método recursivo para escanear subdirectorios ...

Y, finalmente, el pegamento ...

Este fragmento desactiva el botón "escanear", borra el modelo de tabla actual, crea el SwingWorker y registra un PropertyChangeListener y finalmente inicia el trabajador ...

model.clear(); scan.setEnabled(false); ScanWorker worker = new ScanWorker(new File("..."), model); worker.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if ("state".equalsIgnoreCase(evt.getPropertyName())) { SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue(); scan.setEnabled(state == SwingWorker.StateValue.DONE); scan.setText("Scan"); } else if ("directory".equalsIgnoreCase(evt.getPropertyName())) { scan.setText(text); } } }); worker.execute();

PropertyChangeListener supervisa los cambios en el estado del trabajador y restablece el botón a habilitado cuando finaliza. También monitorea los cambios en el directorio de escaneo y actualiza el texto del botón para reflejar el directorio actual procesado ... nice

El fragmento de código anterior es activado por el ActionListener adjunto al botón "escanear"

Y un buen ejemplo ejecutable ...

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingWorker; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.table.AbstractTableModel; public class ShowImages { public static void main(String[] args) { new ShowImages(); } public ShowImages() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } final ImageTableModel model = new ImageTableModel(); JTable table = new JTable(model); final JButton scan = new JButton("Scan"); scan.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { model.clear(); scan.setEnabled(false); ScanWorker worker = new ScanWorker(new File("C://Users//shane//Dropbox//MegaTokyo"), model); worker.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if ("state".equalsIgnoreCase(evt.getPropertyName())) { SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue(); scan.setEnabled(state == SwingWorker.StateValue.DONE); scan.setText("Scan"); } else if ("directory".equalsIgnoreCase(evt.getPropertyName())) { String text = ((File)evt.getNewValue()).getPath().replaceAll("shane", "..."); text = text.replaceAll("C:////", "..."); text = text.replaceAll("Dropbox", "..."); scan.setText(text); } } }); worker.execute(); } }); JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new JScrollPane(table)); frame.add(scan, BorderLayout.SOUTH); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class ImageProperty { private File source; private Dimension size; private boolean selected; public ImageProperty(File source, Dimension size, boolean selected) { this.source = source; this.size = size; this.selected = selected; } public Dimension getSize() { return size; } public File getSource() { return source; } public boolean isSelected() { return selected; } } public class ImageTableModel extends AbstractTableModel { private List<ImageProperty> images; public ImageTableModel() { images = new ArrayList<ImageProperty>(25); } @Override public int getRowCount() { return images.size(); } @Override public int getColumnCount() { return 4; } @Override public String getColumnName(int column) { String name = ""; switch (column) { case 1: name = "Path"; break; case 2: name = "Name"; break; case 3: name = "Size"; break; } return name; } @Override public Class<?> getColumnClass(int columnIndex) { return columnIndex == 0 ? Boolean.class : String.class; } @Override public Object getValueAt(int rowIndex, int columnIndex) { ImageProperty row = images.get(rowIndex); Object value = null; switch (columnIndex) { case 0: value = row.isSelected(); break; case 1: value = row.getSource().getParent(); break; case 2: value = row.getSource().getName(); break; case 3: value = row.getSize().width + "x" + row.getSize().height; break; } return value; } public void addImage(ImageProperty image) { images.add(image); fireTableRowsInserted(images.size() - 1, images.size() - 1); } public void addImages(List<ImageProperty> newImages) { int firstRow = images.size(); int lastRow = firstRow + newImages.size() - 1; images.addAll(newImages); fireTableRowsInserted(firstRow, lastRow); } public void clear() { int lastRow = images.size() -1; images.clear(); fireTableRowsDeleted(0, lastRow); } } public class ScanWorker extends SwingWorker<Object, ImageProperty> { private File source; private ImageTableModel model; public ScanWorker(File source, ImageTableModel model) { this.source = source; this.model = model; } @Override protected void process(List<ImageProperty> chunks) { model.addImages(chunks); } @Override protected Object doInBackground() throws Exception { scan(source); return null; } protected void scan(File dir) { firePropertyChange("directory", dir.getParent(), dir); File pngs[] = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.getName().toLowerCase().endsWith(".png"); } }); for (File png : pngs) { try { BufferedImage img = ImageIO.read(png); publish(new ImageProperty(png, new Dimension(img.getWidth(), img.getHeight()), false)); } catch (IOException e) { System.out.println("Bad image: " + png); e.printStackTrace(); } } File dirs[] = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isDirectory(); } }); if (dirs != null && dirs.length > 0) { for (File subDir : dirs) { scan(subDir); } } } } }

Eche un vistazo a Worker Threads y SwingWorker para más detalles