Modyfikacja JTable

Odpowiedz Nowy wątek
2006-12-30 15:27
0

Mam taki problem. Wyświetlam dane z bazy danych w JTable. W programie jest opcja dodania rekordu. Jak odświeżyć ta tabele żeby pokazywała tez ten dodany rekord ??

Pozostało 580 znaków

2006-12-31 00:41
0

Korzystasz z AbstractTableModel ?? Powinieneś wykorzystać sprzężenie zwrotne jak to się tak ładnie nazywa :P Użyj fireTableCellUpdated(int row, int col)

Pozostało 580 znaków

2006-12-31 22:01
0

Tak urzywam AbstractTableModel. Ale fireCellUpdated pozawa tylko zmienic zawatrośc istniejącej komorki a ja musze dodać (usunąć) cały wiersz (powiekszyć (zmniejszyć) tabele a nie zmienic to co isnieje już).

Pozostało 580 znaków

2007-01-01 19:28
0

fireTableDataChanged()

Pozostało 580 znaków

2007-09-21 16:35
0

Poniżej zamieszczam kod mojej tabeli. Chce usunąćcały ostatni rząd, jak zostana wprowadzone zmiany w pierwszym rzedzie w pierwszej kolumnie. Cos mi nie idzie.

import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
//wewnetrzna klasa z tabela

public class TabelaGraczy extends AbstractTableModel implements TableModelListener{

    String[] nazwy;
    Object[][] dane;
    Object[] pola;

    JTable tabela;
    JScrollPane suwak;
    DefaultTableModel tabModel;
    int row, column;
    public TabelaGraczy() {
    tabModel = new DefaultTableModel();
    tabela = new JTable(tabModel);
    suwak = new JScrollPane(tabela);
    pola = new String[6];
    nazwy = new String []{"1","2","3","4","5","5"};

    for(int a=0;a<nazwy.length;a++)
        {
            tabModel.addColumn(nazwy[a]);
        }
                for(int a=0;a<3;a++)
                {
                    dodajRekord();
                }

    tabela.getModel().addTableModelListener(this);
    }

    public void dodajRekord()
    {
        tabModel.addRow(new Object[] {"Cos","Cos","Cos","Cos","Cos", "Nie"});
    }

    public void tableChanged(TableModelEvent e) {

        row = e.getFirstRow();
        column = e.getColumn();
        String wartosc = tabela.getValueAt(row,column).toString();
        if(row==0 && column==0)
        {
            System.out.println("zmiana w tabeli rzad" + this.getRowCount() + " kolumna " + this.getColumnCount());
            fireTableRowsDeleted(4,4);

        }
    }

    public int getRowCount() {
        return this.row;
    }

    public int getColumnCount() {
        return this.column;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        return dane[row][column];
    }
}

Probowałem różne opcje fireTable.... i bez skutku;/.


Programista wiesza sie razem ze swoim programem

Pozostało 580 znaków

2007-09-21 17:32
0

Ja zrobiłbym to tak:

package table;

import javax.swing.table.AbstractTableModel;

public class MyTableModel extends AbstractTableModel {
    private Object[][] data;
    private int column;

    public MyTableModel(Object[][] data, int column) throws Exception {
        try {
            Object o=data[0][column-1];
        }catch(IndexOutOfBoundsException e) {
            throw new Exception("Nieprawidłowa ilość kolumn");
        }catch(NullPointerException e) {
            throw new Exception("Brak danych");
        }
        this.data=data;
        this.column=column;
    }

    public int getRowCount() {
        return data.length;
    }
    public int getColumnCount() {
        return column;
    }
    public Object getValueAt(int row, int col) {
        return data[row][col];
    }
    public boolean isCellEditable(int row, int col) {
        return false;
    }
    public void setValueAt(Object value, int row, int col) {
        data[row][col] = value;
        fireTableCellUpdated(row, col);
    }

    public void addRow(Object[] row) throws Exception {
        if(row.length!=getColumnCount()) throw new Exception("Niewłaściwe dane");
        Object[][] newdata=new Object[data.length+1][column];
        for(int i=0; i<data.length; i++)
            for(int j=0; j<column; j++)
                newdata[i][j]=data[i][j];
        for(int i=0; i<column; i++)
            newdata[data.length][i] = row[i];
        this.data=newdata;
        fireTableDataChanged();
    }
    public void delRow(int row) throws IndexOutOfBoundsException {
        if(data.length == 0) return;
        Object[][] newdata=new Object[data.length-1][column];
        for(int i=0; i<row; i++)
            for(int j=0; j<column; j++)
                newdata[i][j]=data[i][j];

        for(int i=row+1; i<data.length; i++)
            for(int j=0; j<column; j++)
                newdata[i-1][j]=data[i][j];
        this.data=newdata;
        fireTableDataChanged();
    }
}
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JOptionPane;
import javax.swing.JLabel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import table.MyTableModel;

public class Main extends JFrame implements ActionListener {
    private JTable table;
    private JTextField rowdata;
    private JButton add;
    private JButton del;

    public Main() {
        this.setSize(400,300);
        this.setResizable(false);
        this.setTitle("JTable Example");
        this.setLayout(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        try {
            initComponents();   
            addNPlaceComponents();
        }catch(Exception e) {
            System.out.println("Blad ladowania komponentów:\n"+e.getMessage());
            System.exit(-1);
        }
        this.show();
    }

    private void initComponents() throws Exception {
        Object[][] example_data = {
            {"Jeden"},
            {"Dwa"},
            {"Trzy"}
        };
        table = new JTable(new MyTableModel(example_data,1));

        rowdata = new JTextField("");
        add=new JButton("Dodaj");
        add.setActionCommand("add");
        add.addActionListener(this);

        del=new JButton("Usuń");
        del.setActionCommand("del");
        del.addActionListener(this);
    }

    private void addNPlaceComponents() {
        JScrollPane sp=new JScrollPane(table);
        JLabel rowdata_lab=new JLabel("Wiersz:");
        this.setLayout(null);

        this.add(sp);
        this.add(rowdata);
        this.add(add);
        this.add(del);
        this.add(rowdata_lab);

        sp.setBounds(5,5,380,200);
        rowdata_lab.setBounds(5,210,rowdata_lab.getPreferredSize().width,20);
        rowdata.setBounds(10+rowdata_lab.getPreferredSize().width,210,100,20);

        add.setBounds(5,235,add.getPreferredSize().width,25);
        del.setBounds(10+add.getPreferredSize().width,235,del.getPreferredSize().width,25);
    }

    public void actionPerformed(ActionEvent e) {
        //---dodaj
        if(e.getActionCommand().equalsIgnoreCase("add")) {
            if(rowdata.getText().equals("")) {
                JOptionPane.showMessageDialog(this,"Wpisz jakąś daną w polu 'wiersz'","Brak danych",JOptionPane.WARNING_MESSAGE);
                return;
            }
            try {
                MyTableModel model=(MyTableModel)table.getModel();
                Object[] row=new Object[1];
                row[0]=rowdata.getText();

                model.addRow(row);
                rowdata.setText("");
            }catch(Exception ex) {
                JOptionPane.showMessageDialog(this,"Nie można dodać wiersza:\n"+ex.getMessage(),"Błąd",JOptionPane.ERROR_MESSAGE);
                return;
            }
        }
        //--usun
        else if(e.getActionCommand().equalsIgnoreCase("del")) {
            int selected = table.getSelectedRow();
            if(selected == -1) return;
            try {
                MyTableModel model=(MyTableModel)table.getModel();
                model.delRow(selected);
            }catch(Exception ex) {
                JOptionPane.showMessageDialog(this,"Nie można usunąć wiersza:\n"+ex.getMessage(),"Błąd",JOptionPane.ERROR_MESSAGE);
                return;
            }
        }
    }

    public static void main(String[] args) {
        new Main();
    }   
}

Najpierw robię, potem zastanawiam się jak to działa.

Pozostało 580 znaków

2007-09-22 01:21
0

jacobus2k no twoj kod działa, ale za zadne skarby niemoge zaimplementowac go do swojej tabeli. I czy nie ma jakiegos "normalnego" sposobu na aktualizacje danych w tabeli? Za termin normalny rozumiem kilkanascie lini kodu, a nie 2 klasy i 200 lini kodu, zeby osiągnąć "odświerzanie" zawartosci tabeli. Dla mnie to trche nielogiczne.


Programista wiesza sie razem ze swoim programem

Pozostało 580 znaków

2007-09-22 12:35
1

Dałem ten przykład, by pokazać ci jak to działa. Z Twojego kodu niewiele mogłem zrozumieć.

Więc zacznijmy od podstaw.

JTable można utworzyć na wiele sposobów (patrz API). Jednym z nich jest konstruktor:

JTable(TableModel dm)

TableModel jest interfejsem, czyli najprościej mówiąc rzutowaniem pewnej klasy, na zestaw metod.
W tym przypadku klasy AbstractTableModel.

AbstactTableModel jak wiesz jest klasą abstrakcyjną, czyli wymaga implementacji. Więc tworzysz sobie TabelaGraczy.
Wewnątrz znajduje się macierz z danymi, u Ciebie było by to:

private Object[][] dane

Te dane, wewnątrz klasy TabelaGraczy, możesz poddawać zmianom. Np.: dodać wiersz. Dodanie wiersza, równa się zwiększeniem długości tablicy o 1, i wypełnieniu , analogicznie usunięcie wiersza zmniejszeniu długości tablicy o 1, i odpowiednim przegrupowaniu danych.
Następnie musisz odświeżyć dane, masz do wyboru szereg metod
patrz API: http://java.sun.com/j2se/1.5.[...]table/AbstractTableModel.html
np:

fireTableDataChanged()
//Notifies all listeners that all cell values in the table's rows may have changed.
fireTableRowsDeleted(int firstRow, int lastRow)
//Notifies all listeners that rows in the range [firstRow, lastRow], inclusive, have been deleted.
fireTableRowsInserted(int firstRow, int lastRow)
//Notifies all listeners that rows in the range [firstRow, lastRow], inclusive, have been inserted.
fireTableRowsUpdated(int firstRow, int lastRow)
//Notifies all listeners that rows in the range [firstRow, lastRow], inclusive, have been updated.

W swoim przykładzie dałem poprostu odświeżenie wszystkich danych;)

Teraz przerobiłem twój kod:

import javax.swing.table.AbstractTableModel;

public class TabelaGraczy extends AbstractTableModel   {

    private final static int COLUMN_LENGTH = 6;

    private Object[][] dane;
    private Object[] pola;

    public TabelaGraczy() {
        this.pola = new String[COLUMN_LENGTH]; //nie wiem po co to jest 
        //teraz niebardzo rozumiem jakie maja byc poczatkowe wartosci danych
        //wiec dam tak:
        this.dane = new Object[0][0];
    }

    public int getRowCount() { //zwraca liczbe wierszy macierzy danych wiec wystarczy;
        return dane.length;
    }
    public int getColumnCount() { //zwaraca ilosc kolumn, a ta jest stała i wynosi 6
        return COLUMN_LENGTH;
    }
    public Object getValueAt(int rowIndex, int columnIndex) { //zwraca obiekt macierzy o wskazanych indeksach
        return dane[rowIndex][columnIndex];
    }

    public void dodajWiersz(Object[] row) throws Exception {
        /* Chcesz dodac nowy wiersz, czyli tablice, ktorej dlugosc
         * rowna jest dlugosci kolumn twojej macierzy danych */

         //sprawdzamy czy ilosc danych wejsciowych *row rowna jest ilosci kolumn macierzy:
         //jezeli nie wyrzucamy wyjatek
         if(row.length!=COLUMN_LENGTH) throw new Exception("Niewłaściwe dane");

            /*Teraz, najprostrzym sposobem, na dodanie wiersza do macierzy jest
             *zwiekszenie jej dlugosci o 1, w tym celu, tworzymy nowa, tymczasowa
             *macierz *newdata */
            Object[][] newdata=new Object[dane.length+1][COLUMN_LENGTH];

            /* Teraz tymczasowa macierz, trzeba wypelnic starymi danymi */
            for(int i=0; i<dane.length; i++)
                    for(int j=0; j<COLUMN_LENGTH; j++)
                            newdata[i][j]=dane[i][j];
            //zostaje nam pusty wiersz ktory zapełniamy danymi wejsciowymi *row
            for(int i=0; i<COLUMN_LENGTH; i++)
                    /*data.length odpowiada poprzedniej dlugosci macierzy,
                     *czyli obecnie dlugosci ostatniego wolnego wiersz nowej macierzy */
                    newdata[dane.length][i] = row[i];
            this.dane=newdata;//teraz zapisujemy nowa macierz w miejsce starej
            fireTableRowsInserted(dane.length-1, dane.length-1);//i odswiezamy tabele, dodaliśmy tylko jeden wierzs
    }
    /*Jezeli nie ma takiego wiersza poprostu wyrzuci IndexOutOfBoundsException
     *nie musiałem nawet tego wymuszać, ale chciałem to podkreślić */
    public void usunWiersz(int row) throws IndexOutOfBoundsException { 
            /* Usuniencie wiersza jest analogicznie, 
             * Najpierw wybieramy który wiersz chcemy usunąc *row */
            if(dane.length == 0) return; //przy zerowej ilosci wierszy nic nie mozemy usunac
            Object[][] newdata=new Object[dane.length-1][COLUMN_LENGTH]; //nowa macierz jest krótrza o 1

            /* Teraz wypełniamy nowa macierz starymi danymi, do wiersza
             * który chcemy usunąć */
            for(int i=0; i<row; i++)
                    for(int j=0; j<COLUMN_LENGTH; j++)
                            newdata[i][j]=dane[i][j];
            /* Kontynuujemy wypełnianie, ale od wiersza o jeden większego
             * niż ten który chcemy usunąć */                            
            for(int i=row+1; i<dane.length; i++)
                    for(int j=0; j<COLUMN_LENGTH; j++)
                            newdata[i-1][j]=dane[i][j]; //uwaga indeks nowej macierzy nie może przeskoczyć o 1 dlatego i-1
            this.dane=newdata;//teraz zapisujemy nowa macierz w miejsce starej
            fireTableRowsDeleted(row, row); //odswiezamy tabele, usunelismy tylko jeden wiersz
    }
}

Teraz by utworzyć swoją tabele wystarczy, że zrobisz tak:

JTable tabela = new JTable(new TabelaGraczy());

Jeżeli będziesz chciał otrzymać dostęp do klasy TabelaGraczy, by np: dodać wiersz wystarczy, że zrobisz tak:

TabelaGraczy gracze = (TabelaGraczy)tabela.getModel();
Object[] wiersz = {"Jeden","Dwa","Trzy","Cztery","Pięć","Sześć"};
//try-catch bo wymuszałem obsługe wyjątku
try {
    gracze.dodajWiersz(wiersz);
}catch(Exception e) {
    System.out.println("Błąd "+e.getMessage());
}

Analogicznie usówanie"

TabelaGraczy gracze = (TabelaGraczy)tabela.getModel();
try {
    gracze.usunWiersz(1);
}catch(IndexOutOfBoundsException e) {
    System.out.println("Błąd "+e.getMessage());
}

Jeżeli chodzi o pole:

Object[] nazwy

w twoim oryginalnym kodzie, zapewne chodziło ci o nagłówki kolumn. Zauważ, że nie ma konstruktora opierającego się o TableModel i umożliwiającego nadanie
nazw kolumnom. Gdyż nie wiadomo jakie dane będą wchodzić w skład tabeli.

Możesz wtedy rozszerzyć klase JTable, tj utworzyć klase dziedzicząćą po JTable np:

public class MojaTabela extends JTable {
}

Wówczas, jeżeli chcesz dodać owe nagłówki, wystarczy, że przeciążysz metode

 String getColumnName(int column)

np:

public String getColumnName(int column) {
    if(column == 0) return "Jeden";
    else if(columnt == 1) return "Dwa";
    //itd
    else return null;
}

Możesz też wyłączyć nagłówki przeciążając metode

JTableHeader getTableHeader()

W sposób następujący:

public JTableHeader getTableHeader() {
    return null;
}

Najpierw robię, potem zastanawiam się jak to działa.

Pozostało 580 znaków

2008-08-10 10:44
tomekkk
0

Witam. Idąc tropem ostatniego posta dziedziczę po klasie JTable i przeciążyłem metodę getName ale nazwy kolumn nie są widoczne. Nagłówki kolumn znajdują się w Arrayliscie w modelu mojej tabeli i są zwracane przez metodę getHeader. Metoda getName wogóle nie jest wywoływana przy tworzeniu tabeli. Z góry dzieki za pomoc i pozdrawiam.

private class MyTable extends JTable 
    { 
        public MyTable (TableModel model) 
        { 
            super(model); 
        } 
        public String getColumnName(int column) 
        { 
            System.out.println(((MyTableModel)getModel()).getHeader(column)); 
            return ((MyTableModel)getModel()).getHeader(column); 
        } 
    } 

Pozostało 580 znaków

2008-12-29 05:13
0

jacobus2k albo ktos inny ktos sie zna na rzeczy:
Dziala mi ( i wlasnie jej teraz uzzywam ) tabela zmodyfikowana przez jacobus2k'a ale mam pytanania:
1)W jednej komorce musze trzymac bardzo dlugi text, mozna zrobic tak zeby kazda komorka posiadala jeszcze jakis komponent ( moze jakis inny pomysl)? ( w tym momencie wyswietla mi tylko pierwsza linijke z calego textu);/
2) Jak zmienic szerokosc kolumn ?
Dzieki za kazde uwagi!

1)
Dodalem Eveb: Mouse pressed i kod:
private void paragraphsTableMouseClicked(java.awt.event.MouseEvent evt) {
int row = paragraphsTable.rowAtPoint( evt.getPoint() );
int column = paragraphsTable.columnAtPoint( evt.getPoint() );
if ( row != -1 && column != -1 )
{
//paragraphsTable.getCellEditor().getTableCellEditorComponent(paragraphsTable, column, isSelected, row, column);
//System.out.println( paragraphsTable.getCellEditor().toString() );
System.out.println(paragraphsTable.getValueAt(row, column).toString() );
}
}
i dziala, ale oczwyscie nadal bede wdzieczny za inne rozwiaznia:)
2)
Wciaz prosze o pomoc

Pozostało 580 znaków

2008-12-29 12:10
0

Ad. 2
Java ma doskonałą dokumentację. http://java.sun.com/javase/6/docs/api/. Po prostu tam zajrzyj, wyszukaj właściwą klasę (w typ przypadku TableColumn) i wszystkiego się dowiesz.
pozdrawiam


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0