studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones java swing scala jtable jprogressbar

java - programacion - JProgressBar en JTable no está actualizando



manual de programacion android pdf (3)

No estoy seguro acerca de Scala, pero en Swing el componente devuelto por el TableRenderer solo se usa para crear un ''sello''. Por lo tanto, el componente real no está contenido en la JTable , solo un sello. Lo que significa que si actualiza el componente posteriormente, esto no se refleja en `JTable.

La principal ventaja es que puede reutilizar su componente en el renderizador. Por ejemplo, para representar String , solo necesitaría una instancia de JLabel en la que actualice el texto y permita que el procesador lo devuelva.

La sección de renderizadores en el tutorial de la tabla Swing explica esto con más detalle

¿Por qué no se actualizan las barras de progreso en el siguiente código y cómo las obtendré?

import java.awt.event.{ActionListener, ActionEvent} import javax.swing.table.{TableCellRenderer, AbstractTableModel} import javax.swing.{Timer, JTable, JProgressBar, JFrame} object TestProgressBar { val frame = new JFrame() val model = new TestModel() val table = new JTable(model) class TestModel extends AbstractTableModel { def getColumnCount = 4 def getRowCount = 4 def getValueAt(y: Int, x: Int) = "%d,%d".format(x, y) override def setValueAt(value: Any, row: Int, col: Int) { if (col == 0) { model.fireTableCellUpdated(row, col); } } } class TestCellRenderer extends TableCellRenderer with ActionListener { val progressBar = new JProgressBar() val timer = new Timer(100, this) progressBar.setIndeterminate(true) timer.start() override def getTableCellRendererComponent(tbl: JTable, value: AnyRef, isSelected: Boolean, hasFocus: Boolean, row: Int, column: Int) = { progressBar } override def actionPerformed(e: ActionEvent) { val model = table.getModel for (row <- 0 to model.getRowCount) { model.setValueAt(0, row, 0) } } } def main(args: Array[String]) { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) table.getColumnModel.getColumn(0).setCellRenderer(new TestCellRenderer()) frame.add(table) frame.pack() frame.setVisible(true) } }


Parece que he resuelto el problema anulando los métodos isDisplayable y repaint de JProgressBar.

import javax.swing.table.{TableCellRenderer, AbstractTableModel} import javax.swing.{JTable, JProgressBar, JFrame} object TestProgressBar { val frame = new JFrame() val model = new TestModel() val table = new JTable(model) class TestModel extends AbstractTableModel { def getColumnCount = 4 def getRowCount = 4 def getValueAt(y: Int, x: Int) = "%d,%d".format(x, y) } class TestCellRenderer extends TableCellRenderer { val progressBar = new JProgressBar() { override def isDisplayable = true override def repaint() { table.repaint() } } progressBar.setIndeterminate(true) override def getTableCellRendererComponent(tbl: JTable, value: AnyRef, isSelected: Boolean, hasFocus: Boolean, row: Int, column: Int) = { progressBar } } def main(args: Array[String]) { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) table.getColumnModel.getColumn(0).setCellRenderer(new TestCellRenderer()) frame.add(table) frame.pack() frame.setVisible(true) } }


Como señala @Robin, el renderizador solo se evoca cuando se actualiza el modelo. Necesita cambiar periódicamente el valor en la (s) fila (s) deseada (s). Este ejemplo usa javax.swing.Timer .

private class TestCellRenderer implements TableCellRenderer, ActionListener { JProgressBar bar = new JProgressBar(); Timer timer = new Timer(100, this); public TestCellRenderer() { bar.setIndeterminate(true); timer.start(); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { return bar; } @Override public void actionPerformed(ActionEvent e) { TableModel model = table.getModel(); for (int row = 0; row < model.getRowCount(); row++) { table.getModel().setValueAt(0, row, 0); } } }

Es posible que también desee implementar setValueAt() , ya que la implementación de AbstractTableModel está vacía:

@Override public void setValueAt(Object aValue, int row, int col) { if (col == 1) { // update your internal model and notify listeners this.fireTableCellUpdated(row, col); } }

Adición: como referencia, aquí hay una implementación de Java correspondiente para complementar Scala.

Código:

import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.Timer; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableModel; /** * @see http://.com/a/10491290/230513 */ public class TestProgressBar extends JPanel { private JTable table = new JTable(new TestModel()); public TestProgressBar() { table.getColumnModel().getColumn(0).setCellRenderer(new TestCellRenderer()); table.setPreferredScrollableViewportSize(new Dimension(320, 120)); this.add(new JScrollPane(table)); } private class TestModel extends AbstractTableModel { @Override public int getRowCount() { return 4; } @Override public int getColumnCount() { return 4; } @Override public Object getValueAt(int row, int col) { return String.valueOf(row) + ", " + String.valueOf(col); } @Override public void setValueAt(Object aValue, int row, int col) { // update internal model and notify listeners fireTableCellUpdated(row, col); } } private class TestCellRenderer implements TableCellRenderer, ActionListener { JProgressBar bar = new JProgressBar(); Timer timer = new Timer(100, this); public TestCellRenderer() { bar.setIndeterminate(true); timer.start(); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { return bar; } @Override public void actionPerformed(ActionEvent e) { TableModel model = table.getModel(); for (int row = 0; row < model.getRowCount(); row++) { table.getModel().setValueAt(0, row, 0); } } } private void display() { JFrame f = new JFrame("TestProgressBar"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(this); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new TestProgressBar().display(); } }); } }