Avatar billede heungsu Nybegynder
19. januar 2006 - 17:16 Der er 18 kommentarer og
2 løsninger

Opdatere JTable

Hej Eksperter,

nu har jeg forsøgt i laang tid at få min JTable til at opdatere men uden held.

Jeg har følgende filer:


fill - implement observer
-------------------------
-JTable table = new JTable(new tableModel());
-kører update void på følgende metode i fil2


fil2 - extends observable
-------------------------
-kører en løkke der sætter nye værdier ind i JTable ved brug af setValueAt fra tableModel


tableModel - extends AbstractTableModel
---------------------------------------
indeholder setValueAt som bruger fireTableCellUpdated(row, col) som jeg troede sørgede for at JTable var opdateret.


MEN, den bliver ikke opdateret! Hvad gør jeg galt??
Avatar billede _carsten Nybegynder
19. januar 2006 - 18:21 #1
Prøv i stedet for:  public void fireTableRowsUpdated(int firstRow, int lastRow)

Men du er nok nødt til at køre opdateringen i sin egen tråd.
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 18:38 #2
Hvordan ser din tablemodel ud?
Avatar billede heungsu Nybegynder
19. januar 2006 - 18:51 #3
hey carsten,

hvad mener du med at jeg skal køre opdateringen i sin egen tråd?
Avatar billede heungsu Nybegynder
19. januar 2006 - 18:58 #4
min tableModel ser sådan ud:
-----------------------------------------------------------------------
import javax.swing.table.AbstractTableModel;

public class TableAgentModel extends AbstractTableModel {
    private String [] columnNames = {"blar", "blars", "Bblarn"};
    private String[][] data = {{"blar", "blar/blar", "blar"},
                                        {"blar", "blares", "blarblarurn"},};
   
    public int getColumnCount() {
        return columnNames.length;
    }
   
    public int getRowCount() {
        return data.length;
    }
   
    public String getColumnName(int col) {
        return columnNames[col];
    }
   
    public Object getValueAt(int row, int col) {
      return data[row][col];
    }
   
   
    public void setValueAt(String value, int row, int col) {
        data[row][col] = value;
        fireTableCellUpdated(row, col);
    }
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 18:59 #5
Det er ikke nødvendigt at køre opdateringen i egen tråd.
Fordelen ved at køre det i egen tråd er hvis du har en meget stor opdatering, så låser gui'en ikke.
Avatar billede _carsten Nybegynder
19. januar 2006 - 19:01 #6
Du har sikkert denne opbygning

minGUI{
  JTable tabel

  while( etEllerAndet ){
      tabel.opdater
  }
}

Du starter en ny tråd som sørger for opdatering af din tabel

Eks:


minGUI{
  JTable tabel

  Thread t = new Thread(){
            public void run(){
                while( etEllerAndet ){
                    tabel.opdater
                }
            }
          };

          t.start();
}


Lidt kryptisk men alligevel
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 19:06 #7
Lille hurtigt men køreklart eksempel:

import java.awt.*;
import javax.swing.table.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;

public class JTableTest extends JFrame
{
    private TableAgentModel model = new TableAgentModel();
    private JTable table = new JTable (model);
    private int index = 0;
   
    public JTableTest()
    {
        this.setSize(400, 400);
        this.getContentPane().add(new JScrollPane (table), BorderLayout.CENTER);
       
           
        JButton add = new JButton ("Tilføj");
        add.addActionListener(new ActionListener()
        {
            public void actionPerformed (ActionEvent e)
            {
                model.setValueAt("Hej med dig", 0, 0);
            }
        });
       
        this.getContentPane().add(add, BorderLayout.SOUTH);
    }
   
    private class TableAgentModel extends AbstractTableModel
    {
        private String [] columnNames = {"blar", "blars", "Bblarn"};
        private String[][] data = {{"blar", "blar/blar", "blar"},
                                            {"blar", "blares", "blarblarurn"},};
       
        public int getColumnCount() {
            return columnNames.length;
        }
       
        public int getRowCount() {
            return data.length;
        }
       
        public String getColumnName(int col) {
            return columnNames[col];
        }
       
        public Object getValueAt(int row, int col) {
          return data[row][col];
        }
       
       
        public void setValueAt(String value, int row, int col) {
            data[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    }
   
    public static void main (String[] args)
    {
        new JTableTest().setVisible(true);
    }
}
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 19:07 #8
Der bruger jeg din TableModel. Så fejlen må være i den kode hvor du laver selve opdateringen.
Avatar billede _carsten Nybegynder
19. januar 2006 - 19:08 #9
>mikkelbm

-kører en løkke der sætter nye værdier ind i JTable ved brug af setValueAt fra tableModel

Din kode kører IKKE i en løkke, derfor er en tråd nødvendig.
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 19:11 #10
Skift min ActionListener ud med:

add.addActionListener(new ActionListener()
{
    public void actionPerformed (ActionEvent e)
    {
        for (int i = 0; i<model.getColumnCount(); i++)
            for (int j = 0; j<model.getRowCount(); j++)
                model.setValueAt("Hej med dig", j, i);
    }
});

Så har du din løkke.
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 19:12 #11
Men det er rigtigt, at hvis det er en løkke der hele tiden kører, så kunne man med fordel lave det i en tråd.
Avatar billede heungsu Nybegynder
19. januar 2006 - 19:17 #12
mange tak for hjælpen, jeg prøve lige at sætte det sammen for at se om det virker. men smid lige et svar mikkelbm så du kan få nogle points.

carsen hvis du også smider et svar får du også nogle points som tak.
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 19:20 #13
Bare iorden...
Avatar billede _carsten Nybegynder
19. januar 2006 - 19:23 #14
Det er jo lige netop en løkke som kører hele tiden, og derfor kan man ikke MED fordel lave en tråd, den ENESTE løsning ER en tråd.

Prøv selv:

for (int i = 0; i<1000000; i++)
  model.setValueAt("Hej med dig " +  i,0,1);

Cellen bliver IKKE løbende opdateret !
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 19:27 #15
Slap da af, Carsten!

Og jeg tror muligvis også at jeg har fundet fejlen på hvorfor den ikke bliver opdateret.

Det er at du har følgende metode:

public void setValueAt(String value, int row, int col)
{
            data[row][col] = value;
            fireTableCellUpdated(row, col);
}

Som nok skal være:

public void setValueAt(Object value, int row, int col)
{
            data[row][col] = value;
            fireTableCellUpdated(row, col);
}


Hvis du smider noget andet i end Strings, så vil det ikke blive vist.
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 19:28 #16
Og så har jeg ændret mit eksempel, så det kører i en tråd:

import java.awt.*;
import javax.swing.table.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;

public class JTableTest extends JFrame
{
    private TableAgentModel model = new TableAgentModel();
    private JTable table = new JTable (model);
    private int index = 0;
   
    public JTableTest()
    {
        this.setSize(400, 400);
        this.getContentPane().add(new JScrollPane (table), BorderLayout.CENTER);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
        Thread thread = new Thread()
        {
            public void run()
            {
                try
                {
                    while (true)
                    {
                        sleep (1000);
                        for (int i = 0; i<model.getColumnCount(); i++)
                            for (int j = 0; j<model.getRowCount(); j++)
                                model.setValueAt(new java.util.Date(), j, i);
                    }

                }
                catch (Exception ex)
                {
                    System.out.println (ex.toString());
                }
            }
        };
        thread.start();
    }
   
    private class TableAgentModel extends AbstractTableModel
    {
        private String [] columnNames = {"blar", "blars", "Bblarn"};
        private Object[][] data = {{"blar", "blar/blar", "blar"},
                                            {"blar", "blares", "blarblarurn"},};
       
        public int getColumnCount() {
            return columnNames.length;
        }
       
        public int getRowCount() {
            return data.length;
        }
       
        public String getColumnName(int col) {
            return columnNames[col];
        }
       
        public Object getValueAt(int row, int col) {
          return data[row][col];
        }
       
       
        public void setValueAt(Object value, int row, int col) {
            data[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    }
   
    public static void main (String[] args)
    {
        new JTableTest().setVisible(true);
    }
}
Avatar billede _carsten Nybegynder
19. januar 2006 - 19:37 #17
Sorry - hvis jeg var lidt hård, men den første linie i din kom: 18:59:09 tændte mig vist lidt, og når jeg nu ved du kan - ja så tænkte jeg hvad har han gang i.

Men tilbage til sagen, prøv at ændre løkken, gør det nemmere at se at opdateringen rent faktisk kører løbende.

while (true){
    for (int i = 0; i<1000000; i++)
          model.setValueAt("Hej med dig " +  i,0,1);
}

No bad feelings !
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 19:39 #18
:)
Avatar billede heungsu Nybegynder
19. januar 2006 - 19:40 #19
tak begge to
Avatar billede mikkelbm Nybegynder
19. januar 2006 - 19:40 #20
Jeg overså i første omgang at det kørte i en løkke - min fejl ditto...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester