Problemas atualizando JTable [RESOLVIDO]

12 respostas
W

Olá, pessoal. Dei uma olhada pelo fórum e percebi que meu problema é bem simples: estou usando DefaultTableModel… Na verdade, meu problema é que mesmo alterando o conteúdo da tabela (inserindo linhas, no caso), o view da tabela não é atualizado. Tentei repaint, update, pack do frame, mas nãoi funcionou. Declarei explicitamente fireTableUpdate() entre outra chamadas. Ok. Estou disposta a mudar de model, criando o meu próprio, extendendo o AbstractTableModel.
A questão então é a seguinte, eis o código:

package table;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;

import java.awt.Dimension;
import java.awt.GridLayout;


public class Demo4 extends JPanel {

    private static JTable table;
    private static JFrame frame = new JFrame("TableSelectionDemo");
    private static DefaultTableModel model;
    private static Demo4 newContentPane = new Demo4();
	    
    public Demo4() {
        super(new GridLayout(1,1));
        
        //creating the model and table
        model = new DefaultTableModel();
        table = new JTable(model);
        
        //the creation of the columns
        model.addColumn("Edge Label");
        model.addColumn("Source");
        model.addColumn("Destination");
        model.addColumn("Bandwith");
        
        //adjusting the size of the window
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true); 
        table.setCellSelectionEnabled(true); //permite que seja selecionada uma célula por vez
	        
        //create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //add the scroll pane to this panel.
        add(scrollPane);
        
        model.addRow(new Object[]{"edge1", "123.456.789.101", "234.567.891.011", 50});
	                
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     * @throws InterruptedException 
     */
    private static void createAndShowGUI() {
        //Disable boldface controls.
        UIManager.put("swing.boldMetal", Boolean.FALSE); 

        //Create and set up the window.
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);

    }
    
    /**
     * tableSetValueAt is a public method to be able to insert a new value in a single cell
     * of the created table.
     * @param valor -> value to be inserted
     * @param linha -> row of the cell to be modified
     * @param coluna -> column of the cell to be modified
     */
	public void tableSetValueAt(int valor, int linha, int coluna){
    	table.setValueAt(valor, linha, coluna);
    }
	
	/**
	 * tableAddRow is a public method to be able to insert new rows in the created table.
	 * As you can see, it's not the table itself that is modified, but the model. 
	 * @param rowData -> the row of data to be inserted. Pay attention, because this row
	 * should contain the exact amount data as the number of columns in the table
	 */
	public void tableAddRow(Object[] rowData){
		model.addRow(rowData);
	}
	
    public void createView() {
    	//creating and showing this application's GUI.
       javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
				createAndShowGUI();
            }
       });
    }

Agora a classe de teste:

import table.Demo4;

public class Demo41 {
	
	public static Demo4 tent = new Demo4();
	
	public static void main (String args[]) throws InterruptedException{
		
		int r=0, c=0, v = 0;
		
		Object[] row1 = new Object[]{"edge1", "123.456.789.101", "234.567.891.011", 50};
		Object[] row2 = new Object[]{"edge2", "123.456.789.101", "234.567.891.021", 50};
		Object[] row3 = new Object[]{"edge3", "234.567.891.011", "234.567.891.021", 50};
		
		tent.createView();
		
		tent.tableAddRow(row1);
                tent.tableAddRow(row2);
                tent.tableAddRow(row3);
				
		Thread.sleep(2000);
		
		for(int n=0; n < 5; n++){
			if (n%2 == 0){
				v++;
				tent.tableSetValueAt(v, c, r);
				c++;
				r++;
				Thread.sleep(1000);
			}
		}
	}
	
}

Esclarecendo algumas coisas do código: esse for com Thread.sleep(1000) é para simplesmente dar tempo do view ser renderizado corretamente e simular um ambiente em que os dados são atualizados em tempo real (é asism que a classe será utilizada).
Para que eu implemente esse novo model, além dos gets que devem ser implementados, os dois métodos de modificação de tabelas seriam:

public void setValueAt(Object data, int row, int column){
     table.setValueAt(data, row, column);
     model.fireTableCellUpdated(row, column);
}

e este outro:

public void addRow(Object[] rowData){
     model.addRow(rowData);
     model.fireRowsInserted(0, table.getRowCount());
}

ou algo mais seria necessário para resolver meu problema de atualizar o view da JTable? Espero que tenha ficado tudo bem claro…

Abraços!

Ps.: seria possível utilizar o model que o mark/viniGodoy utilizam para resolver meu problema também?

12 Respostas

V
Engraçado, o DefaultTableModel é ruim, mas ele não tem problemas de update. A view deveria estar sendo atualizada. Algumas causas comuns para o problema:

a) Você acidentalmente atribuiu a tabela um model, criou outro sob a mesma referência. Portanto, o model que a table enxerga não é o mesmo que você atualiza;

b) Você está sobrecarregando a thread do Swing. Tipicamente, quando seu processamento pesado está nessa thread (nesse caso, geralmente todo formulário parece meio congelado);

c) A table está atualizando, mas não tem scrolling.
W

O mais engraçado é que ele funciona esporadicamente! Tem vezes que atualiza corretamente, mas tem vezes que não: é imprevisível… Mas se eu crio as linhas anteriormente, eu consigo modificar seus valores (das células), e os mesmos são atualizados corretamente. Realmente o problema é só com a atualização das linhas (já utilizei o debug e os dados estão realmente lá).

  1. Quanto ao scrolling, ele está adicionado aqui, não?
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true); 
        table.setCellSelectionEnabled(true); //permite que seja selecionada uma célula por vez
	        
        //create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //add the scroll pane to this panel.
        add(scrollPane);
...
  1. Quanto ao processamento pesado, tentei colocar o Thread.sleep() em outras partes do código, mais especificamente entre a inserção de novas linhas, mas não deu certo (não sei se isso resolveria a sobrecarga, mas…)

  2. Se der uma olhada no código postado, só criei um model mesmo, não tem nenhum outro criado, mas seria um bom ponto de partida.

Por fim, gostaria de saber se o modelo que você e o mark indicam ajudariam no caso. Enquanto isso, escrevo o meu próprio. Acabando posto aqui o resultado.

Abraços!

V

O modelo que eu postei no exemplo do AutoFiltro deve ajudar sim.
Provavelmente o do Mark também, mas ele é mais indicado para dizer isso que eu.

W

Ok, o código que cheguei foi esse:

public class Line{
    	private String edgeName;
    	private String source;
    	private String destination;
    	private Integer band;
    	
    	public String getLineEdgeName(){
    		return edgeName;
    	}
    	public String getLineSource(){
    		return source;
    	}
    	public String getLineDestination(){
    		return destination;
    	}
    	public Integer getLineBand(){
    		return band;
    	}
    	public void setLineEdgeName(String edgeName){
    		this.edgeName = edgeName;
    	}
    	public void setLineSource(String source){
    		this.source = source;
    	}
    	public void setLineDestination(String destination){
    		this.destination = destination;
    	}
    	public void setLineBand(Integer band){
    		this.band = band;
    	}
    }

Esse primeiro código é uma clase para a criação das linhas, pra ficar organizado. Tem os parâmetros que eu preciso, e se for necessário adicionar mais, é só mudar pouca coisa… No meu programa não vai ser necessário adicionar colunas.
Agora, finalmente vem o novo Model:

public class NewTableModel extends AbstractTableModel{
    	
    	private ArrayList datalist = new ArrayList();
    	private String[] columns = {"Edge Name", "Source", 
    	                "Destination", "Bandwith Used"};

    	public NewTableModel(){
    		
    	}

    	public NewTableModel(List l) {
    		datalist.addAll(l);
    	}

    	public Line getLineAt(int row) {
 		    return (Line)datalist.get(row);
    	}

    	public Line removeLineAt(int row) {
    		return (Line)datalist.remove(row);
    	}

    	public void addLine(Line l) {
    		datalist.add(l);
    		fireTableDataChanged();
    	}

    	public void addLineList(List l) {
    		datalist.addAll(l);
    		fireTableDataChanged();
    	}
    	
		@Override
		public int getColumnCount() {
			return columns.length;
		}

		@Override
		public int getRowCount() {
			return datalist.size();
		}
		
		public String getColumnName(int column){
			return columns[column];
		}

		@Override
		public Object getValueAt(int row, int col) {
			Line line = (Line) datalist.get(row);
			switch (col) {
				case 0:
					return line.getLineEdgeName();
			    case 1:
			    	return line.getLineSource();
			    case 2:
			    	return line.getLineDestination();
			    case 3:
			    	return new Integer (line.getLineBand());
			    default:
			    	return null;
			   }
		}

		
		public void setValueAt(Object value, int row, int col) {
			Line l = (Line)datalist.get(row);
			switch (col) {
				case 0: //EdgeName
					l.setLineEdgeName(value.toString());
					break;
				case 1: //Source
					l.setLineSource(value.toString());
					break;
			    case 2: //Destination
			    	l.setLineDestination(value.toString());
			    	break;
			    case 3: //Bandwith
			    	Integer _band = (Integer)value;
			    	l.setLineBand(_band.intValue());
			    	break;
			}
			fireTableCellUpdated(row, col);
		}
    	
    }

Na verdade, me inspirei nesses dois artigos passados pelo vini em um outro tópico que já tinha procurado.
http://www.informit.com/articles/article.aspx?p=333472
http://www.informit.com/articles/article.aspx?p=332278

Bem explicativos, bem detalhados. Espero que esse model funcione, já volto pra postar o resultado.

V

Por que vc não cria um List<Line> e remove todos esses casts? Ou está no Java 1.4?

V

Ah, não esqueça também de dar um fireTableLinesRemoved depois de chamar o remove.

E, no lugar do fireTableDataChanged no add, prefira usar o fireTableLinesInserted. Caso contrário, vc pode ter um efeito desagradável da Table piscando.

W

Você quer dizer assim?

public class NewTableModel extends AbstractTableModel{
    	
    	private ArrayList&lt;Line&gt; datalist = new ArrayList&lt;Line&gt;();
    	private String[] columns = {"Edge Name", "Source", 
    	                "Destination", "Bandwith Used"};
    	...

        public NewTableModel(List&lt;Line&gt; l) {
    		        datalist.addAll(l);
    	}
       ...

       public void addLineList(List&lt;Line&gt; l) {
    		datalist.addAll(l);
    		fireTableRowsInserted(0, table.getRowCount());
    	}
        ...
        public Object getValueAt(int row, int col) {
			Line line = datalist.get(row);
			switch (col) {
				case 0:
					return line.getLineEdgeName();
			    case 1:
			    	return line.getLineSource();
			    case 2:
			    	return line.getLineDestination();
			    case 3:
			    	return new Integer (line.getLineBand());
			    default:
			    	return null;
			   }
		}

		
		public void setValueAt(Object value, int row, int col) {
			Line l = datalist.get(row);
			switch (col) {
				case 0: //EdgeName
					l.setLineEdgeName(value.toString());
					break;
				case 1: //Source
					l.setLineSource(value.toString());
					break;
			    case 2: //Destination
			    	l.setLineDestination(value.toString());
			    	break;
			    case 3: //Bandwith
			    	Integer _band = (Integer)value;
			    	l.setLineBand(_band.intValue());
			    	break;
			}
			fireTableCellUpdated(row, col);
		}

Acho que é isso… demorei, porque, sabe como é, hora do almoço… Vou voltar aos testes e a modificação do resto da classe

Abraços

W

Ok, terminei o código e ficou assim:

Classe de criação da tabela:

package table;


import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.AbstractTableModel;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;

import table.Line;


public class Demo4 extends JPanel {

    private static JTable table;
    private static JFrame frame = new JFrame("TableSelectionDemo");
    private static NewTableModel model;
    private static Demo4 newContentPane = new Demo4();
	    
    public Demo4() {
        super(new GridLayout(1,1));
        
        //creating the model and table
        model = new NewTableModel();
        table = new JTable(model);
        
        //the creation of the columns
                
        //adjusting the size of the window
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true); 
        table.setCellSelectionEnabled(true); //permite que seja selecionada uma célula por vez
	        
        //create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //add the scroll pane to this panel.
        add(scrollPane);
        
        Line linha = new Line();
        linha.setLineEdgeName("edge0");
        linha.setLineSource("123.456.789.101");
        linha.setLineDestination("234.567.891.011");
        linha.setLineBand(50);
        
        model.addLine(linha);
	                
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     * @throws InterruptedException 
     */
    private static void createAndShowGUI() {
        //Disable boldface controls.
        UIManager.put("swing.boldMetal", Boolean.FALSE); 

        //Create and set up the window.
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);

    }
    
    /**
     * tableSetValueAt is a public method to be able to insert a new value in a single cell
     * of the created table.
     * @param valor -> value to be inserted
     * @param linha -> row of the cell to be modified
     * @param coluna -> column of the cell to be modified
     */
	public void tableSetValueAt(int valor, int linha, int coluna){
    	table.setValueAt(valor, linha, coluna);
    }
	
	/**
	 * tableAddRow is a public method to be able to insert new rows in the created table.
	 * As you can see, it's not the table itself that is modified, but the model. 
	 * @param rowData -> the row of data to be inserted. Pay attention, because this row
	 * should contain the exact amount data as the number of columns in the table
	 */
	public void tableAddRow(Line rowData){  
		model.addLine(rowData);
	}
	
    public void createView() {
    	//creating and showing this application's GUI.
       javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
				createAndShowGUI();
            }
       });
    }
    
    public void printTable(){
    	for(int i = 0; i<table.getRowCount(); i++){
        	System.out.println(table.getValueAt(i, 0));    		
    	}
    }
    
    public class NewTableModel extends AbstractTableModel{
    	
    	private ArrayList<Line> datalist = new ArrayList<Line>();
    	private String[] columns = {"Edge Name", "Source", 
    	                "Destination", "Bandwith Used"};
    	
    	public NewTableModel(){
    		
    	}
    	
    	public NewTableModel(List<Line> l) {
    		datalist.addAll(l);
    	}

    	public Line getLineAt(int row) {
 		    return datalist.get(row);
    	}

    	public Line removeLineAt(int row) {
    		return datalist.remove(row);
    	}

    	public void addLine(Line l) {
    		datalist.add(l);
    		fireTableRowsInserted(0, table.getRowCount());
    	}

    	public void addLineList(List<Line> l) {
    		datalist.addAll(l);
    		fireTableRowsInserted(0, table.getRowCount());
    	}
    	
		@Override
		public int getColumnCount() {
			return columns.length;
		}

		@Override
		public int getRowCount() {
			return datalist.size();
		}
		
		public String getColumnName(int column){
			return columns[column];
		}

		@Override
		public Object getValueAt(int row, int col) {
			Line line = datalist.get(row);
			switch (col) {
				case 0:
					return line.getLineEdgeName();
			    case 1:
			    	return line.getLineSource();
			    case 2:
			    	return line.getLineDestination();
			    case 3:
			    	return new Integer (line.getLineBand());
			    default:
			    	return null;
			   }
		}

		
		public void setValueAt(Object value, int row, int col) {
			Line l = datalist.get(row);
			switch (col) {
				case 0: //EdgeName
					l.setLineEdgeName(value.toString());
					break;
				case 1: //Source
					l.setLineSource(value.toString());
					break;
			    case 2: //Destination
			    	l.setLineDestination(value.toString());
			    	break;
			    case 3: //Bandwith
			    	Integer _band = (Integer)value;
			    	l.setLineBand(_band.intValue());
			    	break;
			}
			fireTableCellUpdated(row, col);
		}
    }
}

Classe Line:

package table;

public class Line{
	private String edgeName;
	private String source;
	private String destination;
	private Integer band;
	
	public String getLineEdgeName(){
		return edgeName;
	}
	public String getLineSource(){
		return source;
	}
	public String getLineDestination(){
		return destination;
	}
	public Integer getLineBand(){
		return band;
	}
	public void setLineEdgeName(String edgeName){
		this.edgeName = edgeName;
	}
	public void setLineSource(String source){
		this.source = source;
	}
	public void setLineDestination(String destination){
		this.destination = destination;
	}
	public void setLineBand(Integer band){
		this.band = band;
	}
}

Por fim, a classe teste:

import table.Demo4;
import table.Line;

public class Demo41 {
	
	public static Demo4 tent = new Demo4();
	
	public static void main (String args[]) throws InterruptedException{
		
		//int r=0, c=0, v = 0;
		
		Line row1 = new Line();
		Line row2 = new Line();
		Line row3 = new Line();
		
		row1.setLineBand(50);
		row1.setLineDestination("123.456.789.111");
		row1.setLineEdgeName("edge1");
		row1.setLineSource("321.654.987.111");
		
		row2.setLineBand(50);
		row2.setLineDestination("123.456.789.121");
		row2.setLineEdgeName("edge2");
		row2.setLineSource("321.654.987.121");
		
		row3.setLineBand(50);
		row3.setLineDestination("123.456.789.131");
		row3.setLineEdgeName("edge3");
		row3.setLineSource("321.654.987.131");
		
		tent.createView();
		
		tent.tableAddRow(row1);
        tent.tableAddRow(row2);
        tent.tableAddRow(row3);
				
		Thread.sleep(2000);
		
		tent.printTable();
	}	
}

Esse tent.printTable() serve só pra me certificar que os elementos estão sendo inseridos corretamente… Bem, em suma, aconteceu a mesma coisa que já acontecia: a tabela fica com uma linha somente, que foi criada em sua inicialização, mas o view da tabela não se atualiza ao adicionar novas linhas…

Então, alguém tem alguma idéia?

Abraços!

Ps.: desculpa os posts imensos…

V

Muito estranho. Infelizmente nenho java aqui na empresa, vou só poder testar em casa, mais tarde.
Mas aparentemente está tudo certo.

W

Então, acho que descobri (meu amigo :P) o problema! Realmente é aquele caso

Se der uma olhada, tem esse seguinte problema:

#  private static void createAndShowGUI() {  
#         //Disable boldface controls.  
#         UIManager.put("swing.boldMetal", Boolean.FALSE);   
#   
#         //Create and set up the window.  
#         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
#   
#         //Create and set up the content pane.  
#         newContentPane.setOpaque(true); //content panes must be opaque  
#         frame.setContentPane(newContentPane);  
#   
#         //Display the window.  
#         frame.pack();  
#         frame.setVisible(true); 
...

e se olhar aqui:

# public class Demo41 {  
#       
#     public static Demo4 tent = new Demo4();  
#       
#     public static void main (String args[]) throws InterruptedException{  
#           
#         int r=0, c=0, v = 0;  
#           
#         Object[] row1 = new Object[]{"edge1", "123.456.789.101", "234.567.891.011", 50};  
#         Object[] row2 = new Object[]{"edge2", "123.456.789.101", "234.567.891.021", 50};  
#         Object[] row3 = new Object[]{"edge3", "234.567.891.011", "234.567.891.021", 50};  
#           
#         tent.createView();  
#           
#         tent.tableAddRow(row1); 
...

Eu criei uma classe Dem4 dentro da outra! então eu realmente alterava um model, mas observava outro! claro que tinha que dar errado :stuck_out_tongue:

Modificando tudo, ficou assim:
Primeiro a nova classe

package table;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import java.awt.Dimension;
import java.awt.GridLayout;


public class DemoDefault extends JPanel {

    protected JTable table;
    protected JFrame frame;
    protected DefaultTableModel model;
	    
    public DemoDefault() {
        super(new GridLayout(1,1));
        
        //creating the model and table
        model = new DefaultTableModel();
        table = new JTable(model);
        
        //the creation of the columns
        model.addColumn("Edge Label");
        model.addColumn("Source");
        model.addColumn("Destination");
        model.addColumn("Bandwith");
        
        //adjusting the size of the window
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true); 
        table.setCellSelectionEnabled(true); //permite que seja selecionada uma célula por vez
	        
        //create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //add the scroll pane to this panel.
        add(scrollPane);
        
        Object[] row1 = new Object[]{"edge0", "321.654.987.111", "123.456.789.111", 59};
        model.addRow(row1);
        
    }
    
    /**
     * tableSetValueAt is a public method to be able to insert a new value in a single cell
     * of the created table.
     * @param valor -> value to be inserted
     * @param linha -> row of the cell to be modified
     * @param coluna -> column of the cell to be modified
     */
	public void tableSetValueAt(int valor, int linha, int coluna){
    	table.setValueAt(valor, linha, coluna);
    }
	
	/**
	 * tableAddRow is a public method to be able to insert new rows in the created table.
	 * As you can see, it's not the table itself that is modified, but the model. 
	 * @param rowData -> the row of data to be inserted. Pay attention, because this row
	 * should contain the exact amount data as the number of columns in the table
	 */
	public void tableAddRow(Object[] rowData){
		model.addRow(rowData);
		model.fireTableRowsInserted(0, table.getRowCount());
	}

}

agora, a nova classe de testes, um pouco maior:

import table.DemoDefault;

import javax.swing.JFrame;

public class Demo51 {
	
	public static void main (String args[]) throws InterruptedException{

	int r=0, c=0, v = 0; 
	DemoDefault tent = new DemoDefault();
            	//Create and set up the window.
                JFrame frame = new JFrame("TableSelectionDemo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                //Create and set up the content pane.
               
        		
        		Object[] row1 = new Object[]{"edge1", "321.654.987.111", "123.456.789.111", 50};  
        		Object[] row2 = new Object[]{"edge2", "321.654.987.111", "123.456.789.111", 50};
        		Object[] row3 = new Object[]{"edge3", "321.654.987.111", "123.456.789.111", 50};
        		
        		tent.tableAddRow(row1);
        		tent.tableAddRow(row2);
                tent.tableAddRow(row3);
        		
        		tent.repaint();
        		
        		try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
        		
        		tent.tableSetValueAt(v, c, r);
                
                //Display the window.
                frame.setContentPane(tent);
        		
        		frame.pack();
                frame.setVisible(true);
		
		for(int n=0; n < 5; n++){
			if (n%2 == 0){
				v++;
				tent.tableSetValueAt(v, c, r);
				c++;
				r++;
				Thread.sleep(1000);
				tent.tableAddRow(row1);
				Thread.sleep(1000);
			}
		}
	}	
}

E funciona direitinho! Como pode ver, ele adiciona linhas e muda valores, mesmo após ter criado o view! Esse foi o teste para o DefaultTableModel, mais tarde posto as modificações para o model novo que criei.

Abraços,

Ps.: me corrija se eu estiver errado!

W

É, realmente era aquilo mesmo. Com o código do novo model, ficou assim:

package table;


import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;

import table.Line;


public class Demo4 extends JPanel {

    private static JTable table;
    public static JFrame frame = new JFrame("TableSelectionDemo");
    private static NewTableModel model;
    private static JScrollPane scrollPane;
	    
    public Demo4() {
        super(new GridLayout(1,1));
        
        //creating the model and table
        model = new NewTableModel();
        table = new JTable(model);
        
        //the creation of the columns
                
        //adjusting the size of the window
        table.setPreferredScrollableViewportSize(new Dimension(600, 100));
        table.setFillsViewportHeight(true); 
        table.setCellSelectionEnabled(true); //permite que seja selecionada uma célula por vez
	        
        //create the scroll pane and add the table to it.
        scrollPane = new JScrollPane(table);

        //add the scroll pane to this panel.
        add(scrollPane);
        
        Line linha = new Line();
        linha.setLineEdgeName("edge0");
        linha.setLineSource("123.456.789.101");
        linha.setLineDestination("234.567.891.011");
        linha.setLineBand(50);
        
        model.addLine(linha);
	                
    } 
    
    /**
     * tableSetValueAt is a public method to be able to insert a new value in a single cell
     * of the created table.
     * @param valor -> value to be inserted
     * @param linha -> row of the cell to be modified
     * @param coluna -> column of the cell to be modified
     */
	public void tableSetValueAt(int valor, int linha, int coluna){
    	table.setValueAt(valor, linha, coluna);
    }
	
	/**
	 * tableAddRow is a public method to be able to insert new rows in the created table.
	 * As you can see, it's not the table itself that is modified, but the model. 
	 * @param rowData -> the row of data to be inserted. Pay attention, because this row
	 * should contain the exact amount data as the number of columns in the table
	 */
	public void tableAddRow(Line rowData){  
		model.addLine(rowData);
	}
    
    public class NewTableModel extends AbstractTableModel{
    	
    	private ArrayList<Line> datalist = new ArrayList<Line>();
    	private String[] columns = {"Edge Name", "Source", 
    	                "Destination", "Bandwith Used"};
    	
    	public NewTableModel(){
    		
    	}
    	
    	public NewTableModel(List<Line> l) {
    		datalist.addAll(l);
    	}

    	public Line getLineAt(int row) {
 		    return datalist.get(row);
    	}

    	public Line removeLineAt(int row) {
    		return datalist.remove(row);
    	}

    	public void addLine(Line l) {
    		datalist.add(l);
    		fireTableRowsInserted(0, table.getRowCount());
    	}

    	public void addLineList(List<Line> l) {
    		datalist.addAll(l);
    		fireTableRowsInserted(0, table.getRowCount());
    	}
    	
		@Override
		public int getColumnCount() {
			return columns.length;
		}

		@Override
		public int getRowCount() {
			return datalist.size();
		}
		
		public String getColumnName(int column){
			return columns[column];
		}

		@Override
		public Object getValueAt(int row, int col) {
			Line line = datalist.get(row);
			switch (col) {
				case 0:
					return line.getLineEdgeName();
			    case 1:
			    	return line.getLineSource();
			    case 2:
			    	return line.getLineDestination();
			    case 3:
			    	return new Integer (line.getLineBand());
			    default:
			    	return null;
			   }
		}

		
		public void setValueAt(Object value, int row, int col) {
			Line l = datalist.get(row);
			switch (col) {
				case 0: //EdgeName
					l.setLineEdgeName(value.toString());
					break;
				case 1: //Source
					l.setLineSource(value.toString());
					break;
			    case 2: //Destination
			    	l.setLineDestination(value.toString());
			    	break;
			    case 3: //Bandwith
			    	Integer _band = (Integer)value;
			    	l.setLineBand(_band.intValue());
			    	break;
			}
			fireTableCellUpdated(row, col);
		}

    }

}

Agora a classe de testes:

import javax.swing.JFrame;
import table.Demo4;
import table.Line;

public class Demo41 {
	
	public static Demo4 tent = new Demo4();
	public static JFrame frame;
	
	public static void main (String args[]) throws InterruptedException{
		
		int r=0, c=0, v=0;
		
		frame = new JFrame("TableSelectionDemo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Line row1 = new Line();
		Line row2 = new Line();
		Line row3 = new Line();
		
		row1.setLineBand(50);
		row1.setLineDestination("123.456.789.111");
		row1.setLineEdgeName("edge1");
		row1.setLineSource("321.654.987.111");
		
		row2.setLineBand(50);
		row2.setLineDestination("123.456.789.121");
		row2.setLineEdgeName("edge2");
		row2.setLineSource("321.654.987.121");
		
		row3.setLineBand(50);
		row3.setLineDestination("123.456.789.131");
		row3.setLineEdgeName("edge3");
		row3.setLineSource("321.654.987.131");
		
		tent.tableAddRow(row1);
		Thread.sleep(2000);
		tent.tableAddRow(row2);
		Thread.sleep(2000);
        tent.tableAddRow(row3);

        frame.setContentPane(tent);

        //Display the window.
        frame.pack();
        frame.setVisible(true);

		
		Thread.sleep(2000);
		
		tent.tableSetValueAt(v, c, r);
		
		for(int n=0; n < 5; n++){
			if (n%2 == 0){
				v++;
				tent.tableSetValueAt(v, c, r);
				c++;
				r++;
				Thread.sleep(1000);
				tent.tableAddRow(row3);
			}
		}
	}
	
}

Funcionou lindamente, quase chorei de emoção! ahuahauha brincadeiras a parte, valeu a ajuda, vini! Qualquer dica extra sobre o código, me avise, mas já vou mudando o tópico para resolvido!

Abraços a todos e até a próxima!

V

ahahahahaha… que beleza…

E não é que as 3 letrinhas funcionam mesmo? Mas não é à toa que eu sei delas… eu já fiz muito disso. :oops:
As vezes, não está a criação de um objeto não está tão na cara assim.

Pelo menos você já se livrou do DefaultTableModel. Vai dizer que esse código aí não ficou bem mais separado e elegante?

Criado 17 de novembro de 2009
Ultima resposta 17 de nov. de 2009
Respostas 12
Participantes 2