Jak to działa JTable + TableModel z ArrayList

0

Witam,
piszę teraz aplikację na zajęcia i natrafiłem na pewien problem nie rozumie jak działa JTable + ModelTable z ArrayList. Z tego co udało mi się znaleźć w internecie to tutoriale jak to się robi ale zazwyczaj za pomocą tablicy Object[][] albo wektora i większość osób które odpowiadały na to pytanie odsyłała do tutoriali. Poczytałem troszkę i skleciłem coś takiego krótki przykład. Który nie działa ale może chociaż trochę przypomina to jak to powinno być. Bardzo proszę o porady, poprawki tego co skleciłem.

Klasa ModelTabeli:

package Tabelka;

import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

public class ModelTabeli extends AbstractTableModel {

	private String[] columnNames = {"ID","Nazwa","Producent","Ilosc"};
	private ArrayList<List<String>> listy =new ArrayList<List<String>>();
	private static final long serialVersionUID = 1L;
	
	public ModelTabeli(ArrayList<List<String>> listy) {
		this.listy=listy;
	}
	public ModelTabeli(){};

	public void dodajListe(List<String> lista){
		listy.add(lista);
		}
	
	@Override
	public int getColumnCount() {
		// TODO Auto-generated method stub
		return columnNames.length;
	}

	@Override
	public int getRowCount() {
		// TODO Auto-generated method stub
		return this.listy.size();
	}

	@Override
	public Object getValueAt(int wiersz, int kolumna) {
		Object obiekt=null;
		obiekt = listy.get(wiersz).get(kolumna);
		return obiekt;
	}

}

 

Klasa Tabela (okno z komponentem JTable):

 
package Tabelka;

import java.awt.Color;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class Tabela extends JFrame{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1;
	private JTable tabela;
	private JScrollPane suwak;
	ModelTabeli model=new ModelTabeli();
	
	//Object[][] obiekt = {
		//	{"szymon","dupa"},
			//{"karolina","nogi"}
	//};
	
	List<String> lista1 = new ArrayList<String>();
	List<String> lista2 = new ArrayList<String>();
	public void pokazOknoAdmina() throws RemoteException
	{
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(600,600);
		setTitle("Okno administratora");
		setLayout(null);
		setVisible(true);
		
		
		lista1.add("Szymon");
		lista1.add("Fiałkowski");
		
		lista2.add("Karolina");
		lista2.add("Polinska");
		
		model.dodajListe(lista1);
		model.dodajListe(lista2);
		
		suwak = new JScrollPane(tabela);
		suwak.setSize(300, 400);
		suwak.setLocation(230, 50);
		tabela.setBackground(new Color(0,252,255)); tutaj wywala błąd a jak to usunę to błędu nie ma program się odpala ale żadnej tabelki nie wiedać
		suwak.setVisible(true);
		
		add(suwak);
	}
}


I wywala błędy:
Exception in thread "main" java.lang.NullPointerException
at Tabelka.Tabela.pokazOknoAdmina(Tabela.java:50)
at Tabelka.Glowny.main(Glowny.java:9)

I jak się odpala bez błędu to zauważyłem że, chwile po odpaleniu jest gole okno a jak je zminimalizuje i przywrócę z powrotem to pojawia się ramka od tabelki.

0

jeżeli jest to aplikacja dektopowa to brakuje ci metody main w której utworzysz tego frame'a

A nullPointerException wyskakuje ci dlatego że nie stworzyłeś JTable. Masz referencje ale nie masz utworzonego obiektu do tej referencji.

 
        public class Main extends JFrame {

    /**
     *
     */
    private static final long serialVersionUID = 1;
    private JTable tabela;
    private JScrollPane suwak;
    ModelTabeli model = new ModelTabeli();
    //Object[][] obiekt = {
    //        {"szymon","dupa"},
    //{"karolina","nogi"}
    //};
    List<String> lista1 = new ArrayList<String>();
    List<String> lista2 = new ArrayList<String>();

    public Main() {
        
        setTitle("Okno administratora");
        setLayout(null);   

        lista1.add("Szymon");
        lista1.add("Fiałkowski");

        lista2.add("Karolina");
        lista2.add("Polinska");

        model.dodajListe(lista1);
        model.dodajListe(lista2);
        tabela = new JTable(new ModelTabeli());
      //  tabela.
        suwak = new JScrollPane(tabela);
        suwak.setSize(300, 400);
        suwak.setLocation(230, 50);
        tabela.setBackground(new Color(0, 252, 255));
        suwak.setVisible(true);

        add(suwak);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                JFrame fr = new Main();
                fr.setVisible(true);
                fr.setSize(800, 800);
                fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }
}

0

Przekombinowałeś trochę. Po pierwsze bez sensu jest robić 2 listy dla jednej tabeli. Po drugie zrób klasę reprezentującą encje w bazie. Po trzecie dodaj obiekt encji do listy i wybieraj całe obiekty a nie po jednym nie wiadomo czym. Jeszcze jedna sprawa wywala błąd bo to co wywalasz do tabeli jest null'em i pewnie problem to "nullPointException" ale ręki sobie uciąć nie dam. Może starsi bardziej doświadczeni koledzy powiedzą Ci dokładnie w czym rzecz. ^^
Ja bym to zrobił tak:

Klasa encji:

 
package test2;

public class TabelaWBazie {
	
	private long id;
	private String nazwa;
	private String producent;
	private long ilosc;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getNazwa() {
		return nazwa;
	}
	public void setNazwa(String nazwa) {
		this.nazwa = nazwa;
	}
	public String getProducent() {
		return producent;
	}
	public void setProducent(String producent) {
		this.producent = producent;
	}
	public long getIlosc() {
		return ilosc;
	}
	public void setIlosc(long ilosc) {
		this.ilosc = ilosc;
	}

	
	
}

Klasa modelu tabeli:

 
package test2;

import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

import javax.swing.table.AbstractTableModel;

public class TabelaWBazieModel extends AbstractTableModel{
	private String[] colname= {"ID","Nazwa","Producent","Ilosc"};
	private List<TabelaWBazie> data= new LinkedList<TabelaWBazie>();

	public TabelaWBazieModel(){}
	
	public void setData(List<TabelaWBazie> listaDoModelu){
		this.data = listaDoModelu;
	}

	@Override
	public int getColumnCount() {
		return colname.length ;
	}

	@Override
	public int getRowCount() {
		return data.size();
    }
	@Override
	public String getColumnName(int columnIndex){
		return colname[columnIndex].toString();	
	}
	
	
    @Override
    public Object getValueAt(int row, int col) {
    	TabelaWBazie r =(TabelaWBazie) data.get(row);
       switch(col){
       case 0: 
    	   	   return r.getId();
       case 1:
               return r.getNazwa();
       case 2:
               return r.getProducent();
       case 3:
               return r.getIlosc();
       }
       
       return null;

       }
        
  }

Klasa testująca:

 
package test2;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;



public class Test {

	Test(){
	    JFrame ramka = new JFrame();
	    ramka.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    ramka.setSize(600, 600);
	    ramka.setVisible(true);
	    ramka.add(contentPane);
		panel1.setLayout(new GridLayout(1,1));
		panel2.setLayout(new GridLayout(1,1));
		contentPane.setLayout(new FlowLayout());
		
		contentPane.add(panel1);
		contentPane.add(panel2);
		panel1.add(buttonFind);
		table.setModel(km);
	    table.setFillsViewportHeight(true);
	    scrollpane.add(table);
		scrollpane.setViewportView(table);
		scrollpane.setPreferredSize(new Dimension(525,200));
		panel2.add(scrollpane);
		ramka.add(contentPane);
		buttonFind.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				znajdz();
			}
		});
	}
	public static void main(String[] args) {
		Test test = new Test();
	}
	
	public void znajdz(){
		StringBuilder sql = new StringBuilder("SELECT * FROM tabelawbazie");
	try{
		System.out.println("Zapytanie: "+sql);
		Class.forName("com.mysql.jdbc.Driver");
		con = DriverManager.getConnection(url,userName,password);
		PreparedStatement ps = con.prepareStatement(sql.toString());
		
		rs = ps.executeQuery();

		//petla dodaje do listy obiekty w formie encji TabelaWBazie pozyskanych z bazy i przypisanych do parametrów klasy
		while(rs.next()){
			TabelaWBazie r = new TabelaWBazie();
			r.setId(rs.getLong("ID"));
			r.setNazwa(rs.getString("nazwa"));
			r.setProducent(rs.getString("producent"));
			r.setIlosc(rs.getInt("ilosc"));
			listaDoModelu.add(r);
			
		}
		km.setData(listaDoModelu);
		km.fireTableDataChanged();
		rs.close();
		con.close();
	}catch(SQLException e){
		System.out.println("SQL statement is not executed!"+e);
		}catch (ClassNotFoundException e) {
			e.printStackTrace();
			System.out.println("CLASS not found!"+e);
		}
	}
	private JButton buttonFind = new JButton("Znajdz");
        private String userName = "root";
        private String password = "";
        private String url = "jdbc:mysql://localhost:3306/test";
	private TabelaWBazieModel km = new TabelaWBazieModel();
	private JTable table = new JTable(km);
	private JScrollPane scrollpane = new JScrollPane(table);
	private Connection con=null; 
	private PreparedStatement pstmt=null,pstmt1=null;
	private ResultSet rs = null;
	private JPanel contentPane = new JPanel();
	private JPanel panel1 = new JPanel();
	private JPanel panel2 = new JPanel();
	private JPanel panel3 = new JPanel();
	private List<TabelaWBazie> listaDoModelu =new LinkedList<TabelaWBazie>();
	

}

Mi to działa tobie też powinno tylko zmien odpowiednio nazwy list i klas na te których ty używasz. Ja użyłem interfejsu JDBC ale polecam hibernate!
Pozdrawiam! ;]

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