Znowu problem z JTable - refresh

0

Witam,
Widziałem na forum podobne przykłady, jednak odbiegały one w pewnym stopniu, od mojego sposobu pisania kodu :), tzn są dla mnie nie do końca jasne :). W związku z tym mam pytanie, co należy dodać (prawdopodobnie fireTableDataChanged()), ale właśnie w jaki sposób należy zaimplementować tą metodę w stosunku do poniższego kodu? Co należy zrobić, aby uzyskać "odświeżanie" tabeli po dodaniu do niej rekordu (rowniez po operacji szukania, usuwania,itd) - dokladnie po nacisnieciu przycisku? Liczę na wyrozumiałość i pomoc z Waszej strony, gdyż nie za bardzo się w tym łapie :(

klasa RybyModel

public class RybyModel extends AbstractTableModel{

private String [] nazwyKolumn = {"id","gatunek","waga","długość","przyn_rodz",
            "przyn_opis","łowiska","data"};

private Vector<Ryba> dane;

	public void setDane(Vector<Ryba> dane){
		this.dane=dane;
	}
	
	public int getColumnCount() {
		return nazwyKolumn.length;
	}

	public int getRowCount() {
		return dane.size();
	}
	public String getColumnName(int kolumna){
		return nazwyKolumn[kolumna];
		
	}
	public Object getValueAt(int wiersz, int kolumna) {
		Ryba r = dane.get(wiersz);
		
		switch(kolumna){
		case 0:
			return r.id;
		case 1:
			return r.gatunek;
		case 2:
			return r.waga;
		case 3:
			return r.dlugosc;
		case 4:
			return r.przyn_rodz;
		case 5:
			return r.przyn_opis;
		case 6:
			return r.lowisko;
		case 7:
			return r.data;
			
		}
		return null;
	}

} 

W klasie Ryba dwie najważniejsze dla tego problemu metody:

static void GUI(){

             SelectData();
	JFrame mainWindow = new JFrame("Database");
	JTable table = new JTable(model);
	
	JScrollPane scrollPane = new JScrollPane(table);

	JPanel panel = new JPanel();
	panel.setLayout(null);
	for(int i=0;i<polatekstowe.length;i++){
		panel.add(polatekstowe[i] = new JTextField(i));
	}
	polatekstowe[0].setBounds(50,430,100,20);
             .....
	guziki[0].setBounds(150,250,100,50);
	.......		
	labelki[0].setBounds(100,400,50,20);
	........	
	mainWindow.getContentPane().add(panel);
	mainWindow.setResizable(false);
	mainWindow.getContentPane().add(BorderLayout.NORTH,table);
	mainWindow.setSize(1280, 770);
	mainWindow.setVisible(true);
	mainWindow.setDefaultCloseOperation(EXIT_ON_CLOSE);
	
}

oraz

static void SelectData(){
	
	String select = "SELECT * FROM spinning";
	
	try{
		stmt = conn.createStatement();
		ResultSet result = stmt.executeQuery(select);
		while(result.next()){
			value1 = result.getString("id");
			value2 = result.getString("gatunek");
			value3 = result.getString("waga");
			value4 = result.getString("dlugosc");
			value5 = result.getString("przyneta_rod");
			value6 = result.getString("przyneta_opis");
			value7 = result.getString("lowiski");
			value8 = result.getString("data");
			
			rybki.add(new Ryba(value1,value2,value3,value4,value5,value6,value7,value8));
			model.setDane(rybki);
		}
	}catch(Exception e){
		System.err.print("Pobranie danych z bazy nie powiodło się.");
	}
	
		}
0

jak dla mnie jest OK. jesli chcesz odświeżać tabele, wystarczy uaktualniać model po kazdej operacji na danych i repaint().

czyli na w actionListenerze buttona usuwasz/dodajesz rekord z bazy, i potem update modelu i juz

0

A w jaki sposób wykonać update tabeli? [???] . Po nacisnieciu buttona odpala mi sie metoda InsertData(), a potem powinno nastąpić update modelu, mógłbyś mi napisać w jaki sposób powinno to być wykonane na podstawie powyższego kodu? :-) . Trzeba zainicjować ponownie klasę RybyModel, a nastepnie odpalić metodę SelectData(), czy jak? Wybaczcie mi,ale nie mogę tego sam obejść. Byłbym wdzięczny, jakby mógł mi to ktoś zobrazować bardziej szczegółowo :)

0

Czy w ogóle jest konieczne użycie fireTableDataChange()? Czy wystarczy wykonać remove(tabela), repaint(), a pozniej storzyc nowa instancje dla Ryby nowymodel = new RybyModel(), a nastepnie getContentPane() - bo szczegolnie to ostatnie nie chce mi dzialac:(, chyba,ze robie cos zle ???

0

klikasz guzik odśwież, masz do niego podpiete:

guzik.addActionListener(new ActionListener(){

public voiactionPerformed(ActionEvent ev){

tabela.getModel().setDane(selectData());
repaint();
}
});

i zmieniasz metode selectData tak aby zwracała Ci Vector/Listę Rybek

i w selectData() masz add(new Rybka(....)), co jest złym rozwiazaniem , bo powiela ci dane z bazy, tzn, ze jak 2 razy wywolasz ta metode to bedziesz mial podwojna zawartosc tabeli, proponuje albo czyscic liste rybek, albo tworzyc nowa przy wywolaniu selectData()

0

Dzięki. Sprawdzę po południu, bo teraz nie mam takiej możliwości. W razie problemów będę pisał (oby nie :)).
Pozdr

0

Jednak się nie udało. Metoda InsertData() umieszcza dane w bazie poprawnie. Robię w klasie Ryba, tak jak mówiłeś. Zmieniłem zwracany wynik metody SelectData()...

static Vector<Ryba> SelectData(){
	
	String select = "SELECT * FROM spinning";
	
	try{
		//rybki.removeAll(rybki);
		stmt = conn.createStatement();
		ResultSet result = stmt.executeQuery(select);
		while(result.next()){
			value1 = result.getString("id");
			value2 = result.getString("gatunek");
			value3 = result.getString("waga");
			value4 = result.getString("dlugosc");
			value5 = result.getString("przyneta_rod");
			value6 = result.getString("przyneta_opis");
			value7 = result.getString("lowiski");
			value8 = result.getString("data");
			
			//rybki = new Vector<Ryba>();
			rybki.add(new Ryba(value1,value2,value3,value4,value5,value6,value7,value8));
			model.setDane(rybki);
			//System.out.print(value2+"\n");
		}
	}catch(Exception e){
		System.err.print("Pobranie danych z bazy nie powiodło się.");
	}
	return rybki;
	
		}

A poźniej w razie naciśnięcia buttona robię tak:

InsertData();
mainWindow.remove(table);
table.getModel().setDane(SelectData());//w tym miejscu mam komunikat, że: "The method setDane(Vector<Ryba>) is undefined for the type TableModel"
mainWindow.getContentPane().add(table);
mainWindow.repaint();			
			

Mógłbyś mi podpowiedzieć co robię, źle, że pojawia się ten komunikat? Nie mam już pomysłu :(

0

Udało mi się doprowadzić do momentu, że jak ustawiam nowa tabele jako ContentPane(), to działa. Jednak ja chcę dodać ten komponent, a nie ustawić go jako jedyną zawartość JFrame() i w takim przypadku nie działa. A gdy ustawiam, żeby wstawiło tabelę "na miejsce" poprzedniej, to tylko czyści mi to pole i nowa tabela się nie pojawia. Możecie mi pomóc?

public void actionPerformed(ActionEvent arg0) {

			InsertData();
			mainWindow.getContentPane().remove(table);
			RybyModel modello = new RybyModel();
			tableNew = new JTable(modello);
			((RybyModel) tableNew.getModel()).setDane(SelectData());
			mainWindow.getContentPane().add(BorderLayout.NORTH,tableNew);
			mainWindow.repaint();
			
			
			}
	
0

No niestety:

((IPDTableModel)this.ipdTable.getModel()).setRows(controller.getIPDRows());
this.ipdTable.repaint();

nie odświeżyło Tabeli.

0

Po każdej zmianie modelu (dopisanie, skreślenie, edycja) wywołaj

model.fireTableDataChanged();

repaint() jest zbyteczne

0

potwierdzam model.fireTableDataChanged() działa bezblędnie, ja zawartość tabeli generuję osobnym zadaniem i zawsze miałem problem z odświeżaniem widoku. Okazuje się że widok cały czas sprawdza czy model jest aktualny wysłanie tego komunikatu do modelu nie ważne z jakiego zadania,powoduje aktomatyczne przerysowanie widoku tabeli gdy jest on widoczny.

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