Wątek przeniesiony 2014-05-29 07:00 z Java przez bogdans.

Wstawianie elementów do obiektu

0

Nie mogę się uporać z wstawianiem danych do JTable. Odkryłem, że działa to poprawnie gdy wstawiam dane tak:

(...)
public static String[] kolumnyTab = {"Imie", "Nazwisko", "Nr indeksu", "Wydział", "Semestr", "Stopien", "Sprawa"};
private Object[][] dane = {{Jan, Kowalski, 666, Chemiczny, Semestr V, I stopien, Podanie}, {Jan, Kowalski, 666, Chemiczny, Semestr V, I stopien, Podanie}};
(...)
table = new JTable(dane, kolumnyTab);
	JScrollPane scPane = new JScrollPane (table);
(...)

Dlatego postanowiłem, że po zapisaniu wartości do vectora będę je rozdzielał i wpisywał do zmiennej dane:

public static String[] kolumnyTab = {"Imie", "Nazwisko", "Nr indeksu", "Wydział", "Semestr", "Stopien", "Sprawa"};
private Object[][] dane = {{}};
(...)
wiersz.add(new Istopien (imie, nazwisko, nrIndeksu, wydzial, semestr)+", "+sprawa);
for (int i = 0; i<wiersz.capacity(); i++){
				st = new StringTokenizer((String)wiersz.elementAt(i), ",");
				int j = 0;
			 	while (st.hasMoreElements()){
			 		dane[i][j] = st.nextElement();
			 		j++;
			 	}
			}

Pomysł może trochę dziwny, ale tylko to mi przyszło do głowy. Samo rozdzielanie na Stringi działa, bo testowałem to tak:

st = new StringTokenizer((String)wiersz.elementAt(0), ",");
				 	while (st.hasMoreElements()){
				 		System.out.println(st.nextElement()); 
				 	}

i wszystko działało bez problemu (wypisywane były wszystkie elementy w osobnych liniach).

Gdy kompiluję i uruchamiam, po wpisaniu danych i kliknięcia na przycisk wywołujący wpisanie danych do obiektu dane pojawia się błąd "java.lang.ArrayIndexOutOfBoundsException" w lini:

dane[i][j] = st.nextElement();

czyli wyjście poza zakres tablicy, ale nie wiem czemu. Jakieś pomysły czemu tak się dzieje? Albo jak to można rozwiązać w lepszy sposób?

0

A jaki rozmiar ma Twoim zdaniem ta tablica?

private Object[][] dane = {{}};

Ty chyba czytasz dane z bazy danych, nie powinieneś zatem używać tablicy jako modelu w JTable - nie wiesz ile wierszy musi mieć tablica. Zamiast tablicy użyj kolekcji Vector<String[]>. A jeszcze lepiej stworzyć klasę (chyba Sprawa) i dane przechowywać w kolekcji Vector<Sprawa>.

0

To tak, mam klasę Student, i klasy Istopien i IIstopien, które dziedziczą po Student (trochę to bez sensu, ale takie miałem wymagania, żeby tak to zrobić). Gdy w aplikacji zostaną dodane wszystkie dane i klika się na przycisk zapisujący te dane to wygląda to tak:

(...)
	public Vector<String> wiersz = new Vector<String>();
	private Object[][] dane = {{}};
	private Vector<Istopien> sI = new Vector<Istopien>();
	private Vector<IIstopien> sII = new Vector<IIstopien>();
(...)
if (e.getSource() == generate){
			imie = nameField.getText();
			nazwisko = surnameField.getText();
			nrIndeksu = Integer.parseInt(idField.getText());
			
			if (stopien.equals("I stopień")){
				wiersz.add(new Istopien (imie, nazwisko, nrIndeksu, wydzial, semestr)+", "+sprawa);
			}
			
			else {
				wiersz.add(new IIstopien (imie, nazwisko, nrIndeksu, wydzial, semestr)+", "+sprawa);
			}
			for (int i = 0; i<wiersz.capacity(); i++){
				st = new StringTokenizer((String)wiersz.elementAt(i), ",");
				int j = 0;
			 	while (st.hasMoreElements()){
			 		dane[i][j] = st.nextElement();
			 		j++;
			 	}
			}
		}

Dowiedziałem się, że JTable jako modelu dobrze jest jak używa vector, ale jak próbowałem dodawać vector do JTable to do pojedynczej komórki trafiał cały vector w takim stylu: Jan, Kowalski, 666, Chemiczny, Semestr V, I stopien, Podanie , a ja chciałbym aby każdy pojedynczy string trafiał do osobnych komórek, stąd mój problem.

0

Co jest wyświetlane w komórce zależy od metody getValueAt(...) w modelu. Moim zdaniem, dużo wygodniej programuje się wyświetlanie JTable jeżeli jawnie stworzy się klasę modelu. Przeanalizuj ten przykład:

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

public class Planets extends JFrame
{
    //------------------------
    public static void main(String[] args)
    {
        new Planets();
    }
    //------------------------
    public Planets()
    {
        super("Planety");
        TableModel model = new PlanetsModel();
        JTable table = new JTable(model);      
        table.setAutoCreateRowSorter(true);
        add(new JScrollPane(table),BorderLayout.CENTER);

        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }  
}
//----------------------------
class Planet
{
    private static int howMany = 0;
    public String name;
    public int nr;
    public double radius;
    public int moons;
    public boolean gaseous;
    //--------------------
    public Planet(String name,double radius,int moons,boolean gaseous)
    {
        this.name = name;
        this.radius = radius;
        this.moons = moons;
        this.gaseous = gaseous;
        howMany++;
        nr = howMany;
    }
}  

//----------------------------
class PlanetsModel extends AbstractTableModel
{
    private String[] columnNames = {"Nazwa","Numer","Promień","Księżyce","Gazowa"};
    private Class[] columnClasses = {String.class,Integer.class,Double.class,Integer.class,Boolean.class};
    private ArrayList<Planet> planets = new ArrayList<Planet>();
    //------------------------
    public PlanetsModel()
    {
        planets.add(new Planet("Merkury",2440.0,0,false));
        planets.add(new Planet("Wenus",6052.0,0,false));
        planets.add(new Planet("Ziemia",6378.0,1,false));
        planets.add(new Planet("Mars",3397.0,2,false));
        planets.add(new Planet("Jowisz",71492.0,16,true));
        planets.add(new Planet("Saturn",60268.0,18,true));
        planets.add(new Planet("Uran",25559.0,17,true));
        planets.add(new Planet("Neptun",24766.0,8,true));
    }
    //------------------------
    public int getColumnCount()
    {
        return columnNames.length;
    }
    //------------------------
    public int getRowCount()
    {
        return planets.size();
    }
    //------------------------
    public Object getValueAt(int row,int col)
    {
        Planet p = planets.get(row);
        switch(col)
        {
            case 0:
                 return p.name;
            case 1:
                 return p.nr;
            case 2:
                 return p.radius;
            case 3:
                 return p.moons;
            case 4:
                 return p.gaseous;
        }
        return null;
    }  
    //------------------------
    public Class getColumnClass(int col)
    {
    	return columnClasses[col];
    }
    //------------------------
    public String getColumnName(int col)
    {
    	return columnNames[col];
    }
}
0

Dzięki bogdans za odpowiedź, ale to była ostatnia rzecz jaką chciałem zaimplementować i nie chciałbym już dodawać nowych klas, także nie skorzystałem z Twojego pomysłu. Udało mi się to rozwiązać tak:

(...)
private String[][] dane = {{}};
	DefaultTableModel tbm;
(...)
tbm = new DefaultTableModel(dane, kolumnyTab);
		table = new JTable(tbm);
(...)
if (e.getSource() == generate){
			imie = nameField.getText();
			nazwisko = surnameField.getText();
			nrIndeksu = Integer.parseInt(idField.getText());
			
			if (stopien.equals("I stopień")){
				wiersz.add(new Istopien (imie, nazwisko, nrIndeksu, wydzial, semestr)+", "+sprawa);
			}
			
			else {
				wiersz.add(new IIstopien (imie, nazwisko, nrIndeksu, wydzial, semestr)+", "+sprawa);
			}
			st = new StringTokenizer((String)wiersz.elementAt(klikniecia), ",");
			Vector<String> row = new Vector<String>();
			while (st.hasMoreElements()){
				row.add((String) st.nextElement());
			}
			tbm.insertRow(klikniecia, row);
			klikniecia++;
		}

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