Spaltenbreite festlegen - Fehlermeldung

Leyja

Mitglied
Hallo,
Ich bastel derzeit an einem Programm, in dem Daten eingelesen und anschließend in einer Tabelle dargestellt werden sollen. Jetzt wollte ich gerne die Tabellenbreiten festlegen. Da ich zu Beginn noch nicht weiß, wie viele Spalten ich habe, dachte ich mir, ich bastel mir eine Schleife und packe die mit in meinen ActionListener für das Dateiöffnen, die Schleife sieht folgendermaßen aus:
Code:
for (int i = 0; i < ptmtest.getColumnCount(); i++) {
                            tblSpalte = pTabelle.getColumnModel().getColumn(i);
                            tblSpalte.setWidth(150);
                            tblSpalte.setPreferredWidth(150); 
                            tblSpalte.setResizable(false);
                        }
Ich hole mir also die Spaltenanzahl mit getColumnCount, was auch funktioniert. Wenn ich mein Programm dann starte, funktioniert das ganze auch, jedoch nur für die erste Spalte, also für i=0. Beim zweiten Durchlauf stoppt das ganze dann mit folgender Fehlermeldung:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 1
Und danach eben auch noch ein ganzer Haufen anderer Fehlermeldungen.
Ich hab auch schon geguckt, ob es mit ner festen Zahl (also zum Beispeil Spalte 2 oder so) funktioniert, ohne Schleife, aber das will auch nicht, dann kommt die gleiche Fehlermeldung (nur eben mit der jeweiligen Zahl >= 1).

Woran kann das liegen? Ich hab mir vor und während der Schleife auch die ColumnCount ausgeben lassen, die liegt bei meiner Testdatei bei 5 und daran ändert sich auch nichts.

Gibt es eine andere Möglichkeit, die Spaltenbreite irgendwie festzulegen? Bzw. einen anderen Ort? Da zu Beginn meines Programms ja noch gar keine Spalten vorhanden sind, kann ich das ja erst während/ nach dem Öffnen einer Datei machen oder?
 
Hallo,

nur mal so zurückgefragt, in deiner Schleife steht :

for (int i = 0; i < ptmtest.getColumnCount(); i++) {

in der nächsten Zeile arbeitest du mit :

tblSpalte = pTabelle.getColumnModel().getColumn(i);

ist das korrekt so ? Wie sind beide Variablen initialisiert ?

Gruß JAdix
 
Hallo,

also das ganze ist so aufgebaut:
Ich habe eine Klasse, die eine Methode "createGUI" hat, in der ich meine Gui aufbaue. Dort wird pTabelle als JTable erzeugt, das außerdem noch eine Instanz eines tablemodel mitgegeben bekommt. (also eben JTable pTabelle = new JTable(), das TableModel wird dann über eine Methode übergeben). Die Klasse des Tablemodels hab ich selbst geschrieben und befindet sich als Innere Klasse in dem ganzen Konstrukt.

Dann hab ich eine weitere Innere Klasse für meine ActionListener und in einem dieser Actionlistener ist eben diese Schleife, wie ich sie gepostet habe.
Da ich dort auf einige Inhalte aus der anderen InnerenKlasse, also meinem TableModel zugreifen musste, hab ich mir dort folgendermaßen eine Instanz erzeugt: MyTableModel ptmtest = new Programmansicht().new MyTableModel();
Diese Instanz ptmtest hab ich vorher schon vorher dafür benutzt, um Attribute aus dem TableModel zu überschreiben, das hat soweit ganz gut geklappt.

Liegt da irgendwo mein Fehler? Ich bin noch nicht so erfahren, was das Zusammenspiel zwischen Inneren Klassen angeht ^^" Ich hab auch schon versucht, dieses
ptmtest.getColumnCount() vorher einer normalen Integer-Variablen zuzuweisen und die in der Schleife zu benutzen, so dass ich dann eigentlich nur immer auf meine JTable-Instanz zugreifen muss, aber auch da kommt der gleiche Fehler.

Gruß, Leyja
 
Hallo,

hab Deine Beschreibung so zwei bis dreimal durchgelesen,
mal sehen ob ichs Verstanden habe :

Du hast ein eigenes TableModel mit Daten um es nach instanziierung der JTable
über eine Methode ( setModel(TableModel dataModel) )zu übergeben.

Ist das die selbe Instanz deines Models welches in der ptmtest-Variable steckt ?

Hört sich so an als ob du zwei Modelle instanziierst erst für die JTable, später dann im
ActionListener nochmal ! Oder habe ich das falsch herausgelesen ?

Wie kommen die Daten in dein Model ( in die Modelle ) ?

Gruß JAdix
 
Ich poste einfach mal den (etwas abgespeckten - unwichtige bzw. unfertige Sachen hab ich rausgenommen) Code.
Ist vielleicht einfacher. Ich hab das mit der Schleife dann nochmal in eine Methode (spaltenbreite heißt die jetzt) gepackt, was aber am Problem nix verändert hat. Aufgerufen wird die dann im Actionlistener.

Wahrscheinlich bin ich das völlig falsch angegangen oder so, ich hab vor allem mit diesen Inneren Klassen immer noch so meine Probleme, vor allem wenn ich von einer inneren Klasse auf eine andere zugreifen will/soll. Falls ich da generell irgendwas beachten soll oder so, wärs super, wenn mir da noch ein paar Tips gegeben würden ^^

Vielen Dank schonmal im Voraus :)

Code:
public class Tabellenansicht {
    /**
     * MenuItem öffnen.
     */
    private JMenuItem oeffnen = new JMenuItem("Öffnen...");

    /**
     * MenuItem speichern.
     */
    private JMenuItem speichern = new JMenuItem("Speichern");

    /**
     * MenuItem speichern unter.
     */
    private JMenuItem speichernUnter = new JMenuItem("Speichern unter");

    /**
     * MenuItem beenden.
     */
    private JMenuItem beenden = new JMenuItem("Beenden");

    /**
     * JTable, in der die Produkte ausgegeben werden.
     */
    private JTable produktTabelle;

    /**
     * Dateiname zum Datei Öffnen und Speichern.
     */
    private String dateiname;

    /**
     * Konstruktor.
     * @param sichtbarkeit jlk
     */
    public Tabellenansicht(Boolean sichtbarkeit) {
        this.erzeugeFenster(sichtbarkeit);
    }

    /**
     * Methode zum Erzeugen des Fensters.
     * @param sichtbarkeit
     */
    public void erzeugeFenster(Boolean sichtbarkeit) {
        JFrame matrix = new JFrame("Matrixansicht");
        matrix.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container cont = matrix.getContentPane();
        cont.setLayout(new BorderLayout());
        // Menu
        JMenuBar menue = new JMenuBar();
        matrix.setJMenuBar(menue);
        JMenu datei = new JMenu("Datei");
        oeffnen.setAccelerator(KeyStroke.getKeyStroke('O',
            InputEvent.CTRL_DOWN_MASK));
        oeffnen.addActionListener(new Listener());
        datei.add(oeffnen);
        speichern.setAccelerator(KeyStroke.getKeyStroke('S',
            InputEvent.CTRL_DOWN_MASK));
        speichern.addActionListener(new Listener());
        datei.add(speichern);
        speichernUnter.addActionListener(new Listener());
        datei.add(speichernUnter);
        datei.add(new JSeparator());
        beenden.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,
            InputEvent.ALT_DOWN_MASK));
        beenden.addActionListener(new Listener());
        datei.add(beenden);
        menue.add(datei);
        produktTabelle = erstelleTabelle();
        produktTabelle.getTableHeader().setReorderingAllowed(false);
        produktTabelle.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        cont.add(new JScrollPane(produktTabelle), BorderLayout.NORTH);
        matrix.pack();
        matrix.setLocation(
            (Toolkit.getDefaultToolkit().getScreenSize().width - matrix
            .getSize().width) / 2, (Toolkit.getDefaultToolkit()
            .getScreenSize().height - matrix.getSize().height) / 2);
        matrix.setVisible(sichtbarkeit);
        aktualisiereMatrix();
    }

    /**
     * Methode zum Aktualisieren der Matrix, greift auf die gleichnamige Methode
     * zu, die das TableModel erzeugt.
     */
    public void aktualisiereMatrix() {
        aktualisiereMatrix(false);
    }

    /**
     * Methode zum Aktualisieren der Matrix, die je nachdem ein Table Model
     * setzt oder nicht.
     * 
     * @param init
     *            überprüft, ob schon ein TableModel initialisiert wurde.
     * @return produkttablemodel gibt das tablemodel zurück.
     */
    private ProduktTableModel aktualisiereMatrix(boolean init) {
        ProduktTableModel produkttablemodel = new ProduktTableModel();
        if (!init) {
            produktTabelle.setModel(produkttablemodel);
        }
        return produkttablemodel;
    }

    /**
     * Erstellt eine Tabelle mit den Daten aus den Dokumenten.
     * 
     * @return die Tabelle
     */
    private JTable erstelleTabelle() {
        return new JTable(aktualisiereMatrix(true));
    }

    /**
     * TableModel für die Produkttabelle.
     * 
     */
    private class ProduktTableModel extends AbstractTableModel {

        /**
         * Serialisierungsid.
         */
        private static final long serialVersionUID = -3042987409161204297L;

        /**
         * Inhalt für die Tabellen: Arrayliste der Produkte.
         */
        private ArrayList<Produkt> produktdaten = Einlesen.getProdukte();

        /**
         * Inhalt für die Tabellen: Arrayliste der Bewertungskriterien.
         */
        private ArrayList<String> bewertungskriterien =
            Einlesen.getAttributnamen();

        /**
         * Getter für die Produktdaten.
         * @return produktdaten 
         */
        public ArrayList<Produkt> getProduktdaten() {
            return produktdaten;
        }

        /**
         * Methode für die Spaltenbreite.
         * @param produktTabelle
         * @return produktTabelle blubb
         */
        public JTable spaltenbreite(JTable produktTabelle) {
            int spaltenzahl = getColumnCount();
            for (int i = 0; i <= spaltenzahl; i++) {
                produktTabelle.getColumnModel().getColumn(i).setPreferredWidth(
                    100);
            }
            return produktTabelle;
        }

        /**
         * Gibt die Zeilenanzahl zurueck.
         * @return Zeilenanzahl
         */
        public int getRowCount() {
            int zeilenanzahl;
            if (bewertungskriterien == null) {
                zeilenanzahl = 0;
            } else {
                zeilenanzahl = bewertungskriterien.size();
            }
            return zeilenanzahl;
        }

        /**
         * Gibt die Spaltenanzahl zurueck.
         * @return spaltenanzahl
         */
        public int getColumnCount() {
            int spaltenanzahl;
            if (produktdaten == null) {
                spaltenanzahl = 0;
            } else {
                spaltenanzahl = produktdaten.size() + 1;
            }
            return spaltenanzahl;
        }

        /**
         * Die Spaltenueberschriften.
         * 
         * @param column
         *            Spalte
         * @return ergebnis - Name der Spalte
         */
        public String getColumnName(int column) {
            String ergebnis = "";
            if (column == 0) {
                ergebnis = "";
            } else {
                ergebnis = produktdaten.get(column - 1).getProduktname();
            }
            return ergebnis;
        }

        /**
         * Gibt den Inhalt der Zelle zurueck.
         * 
         * @param row
         *            Zeile
         * @param column
         *            Spalte
         * @return n Object
         */
        public Object getValueAt(int row, int column) {
            Object rueckgabe = null;
            if (column == 0) {
                for (int i = 0; i <= row; i++) {
                    rueckgabe = bewertungskriterien.get(i);
                }
            } else {
                ArrayList<Eigenschaften> temp =
                    produktdaten.get(column - 1).getPAttribute();
                for (int j = 0; j <= row; j++) {
                    rueckgabe = temp.get(j).getInhalt();
                }
            }
            return rueckgabe;
        }

    }

    /**
     * Listener.
     * 
     * @author 
     * 
     */
    private class Listener implements ActionListener {
        /**
         * Verwaltet die Ereignisse.
         * 
         * @param event
         *            zu verarbeitendes Event
         */
        public void actionPerformed(ActionEvent event) {
            if (event.getSource() == beenden) {
                System.exit(0);
            } else if (event.getSource() == oeffnen) {
                String fensterTyp = "dateiOeffnen";
                Dateieinlesen dateioeffnen = new Dateieinlesen(fensterTyp);
                dateiname = dateioeffnen.getPfad();
                ProduktTableModel ptmtest =
                    new Matrixansicht(false).new ProduktTableModel();
                Einlesen.produkteLesen(dateiname);
                ptmtest.bewertungskriterien = Einlesen.getAttributnamen();
                ptmtest.produktdaten = Einlesen.getProdukte();
                // ptmtest.spaltenbreite(produktTabelle);
                aktualisiereMatrix();
            } else if (event.getSource() == speichern) {
                Einlesen.produkteSchreiben(dateiname);
                JOptionPane.showMessageDialog(null,
                    "Die Datei wurde erfolgreich gespeichert.",
                    "Speichern erfolgreich", JOptionPane.INFORMATION_MESSAGE);
            } else if (event.getSource() == speichernUnter) {
                String fensterTyp = "dateiSpeichern";
                Dateieinlesen dateispeichern = new Dateieinlesen(fensterTyp);
                String pfad = dateispeichern.getPfad();
                Einlesen.produkteSchreiben(pfad);
            } 
        }
    }
}

edit: Dateieinlesen ist die Klasse, die den JFileChooser erzeugt, in der Klasse Einlesen befinden sich die Methoden zum Lesen und Schreiben.
 
Zuletzt bearbeitet:
Hallo,

soweit Ich das beurteilen kann liegt dein Problem hier :

Code:
/**
     * Methode zum Aktualisieren der Matrix, die je nachdem ein Table Model
     * setzt oder nicht.
     * 
     * @param init
     *            überprüft, ob schon ein TableModel initialisiert wurde.
     * @return produkttablemodel gibt das tablemodel zurück.
     */
    private ProduktTableModel aktualisiereMatrix(boolean init) {
        ProduktTableModel produkttablemodel = new ProduktTableModel();
        if (!init) {
            produktTabelle.setModel(produkttablemodel);
        }
        return produkttablemodel;
    }

Selbst wenn du mit true aufrufst, bekommst du ein anderes TableModel als
Rückgabewert geliefert als jenes welches du beim aufruf mit false Erzeugt hast um
deine JTable damit zu bestücken.

Ich würde produkttablemodel als Instanzfeld der Klasse Tabellenansicht definieren
und das new ProduktTableModel(); mit in die if-Abfrage nehmen !

Gruß JAdix
 
Hm, funktioniert leider auch nicht :-/ Dann wirft er mir die gleiche Exception nur mit 0 >= 0.
Dann kann ich nicht mal mehr das Dateiöffnen-Fenster aufrufen.

Naja, zur Not muss ichs ganz weglassen :-/
 
Zurück