JTable-Update ist langsam

Hallo,

ich nähere mich der 1000. gefahr

Ich hab eine JTable für das TicTacToe-Spiel. Schien mir am naheliegendsten und Best Practice. Die JTable hat ein eigenes Model und einen eigenen Renderer:


    private static final JTable jt = new JTable(new AbstractTableModel() {
        @Override
        public int getColumnCount() {
            return spiel.length;
        }

        @Override
        public int getRowCount() {
            return spiel[0].length;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return spiel[rowIndex][columnIndex];
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            spiel[rowIndex][columnIndex] = (int) aValue;
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return false;
        }
    });

        jt.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
            JLabel jl = new JLabel();

            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                jl.setOpaque(true);
                switch (spiel[row][column]) {
                    case 0:
                        jl.setBackground(Color.white);
                        break;
                    case +1:
                        jl.setBackground(Color.green);
                        break;
                    case -1:
                        jl.setBackground(Color.red);
                        break;
                    default:
                        throw new AssertionError();
                }
                return jl;
            }
        });
        jt.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                JTable target = (JTable) e.getSource();
                int row = target.getSelectedRow();
                int column = target.getSelectedColumn();
                if (spiel[row][column] != 0) {
                    return;
                }
                // tue was mit row und column ...
            }
        });
        jf.add(jt, BorderLayout.CENTER);```

Bis hierhin wahrscheinlich easy going.

Die Daten von Spiel ändere ich so z. B.:

```spiel[1][1] = +1;```

und dann rufe ich Update auf, entweder:

```((AbstractTableModel) jt.getModel()).fireTableDataChanged();``` (gracefully)

oder:

```jt.repaint();```

****[U]Problem:[/U]****

Das Aktualisieren der Zellen ist langsam oder Zellen werden gar nicht aktualisiert (Aktualisierung findet nicht für den Benutzer merklich statt).

Workaround: Alle Aktualisierungen innerhalb des EDTs. Nächstes Problem: EDT läuft über / Overflow.

Was sollte ich also tun, um `int[][] spiel = new int[3][3];` (mit vielen Änderungen) korrekt darzustellen?

Grüße an alle

Da Swing selbst intern ja auch so ein wenig MVC ist mal ins Blaue geraten: Das update des Models haut nicht hin. Oder du änderst Daten einer zweiten Model-Instanz weil irgendwo statt get ein new steht.
Auch musst du gucken wie die einzelnen Bereich miteinander verschränkt sind: Ich z.B. fahre über den Controller ein Update des Model und informiere View das es ein Update gab. View fragt dann beim Controller nach den Daten vom Model. Wie das intern bei JTable abgeht hängt auch von deinen Listenern ab wann was in welchem Thread läuft.

Args, ich hab einen “Kardinalfehler”, hab nicht gemerkt, dass die Aktualisierungen im EDT stattfinden. Die Game logik steht wird im EDT gestartet. Bei vielen Aktualisierungen updatet die GUI nicht. Bei einem Thread.sleep() friert die GUI ein. Ähnlich ist es hier beschrieben: java - JFrame not updating before thread.sleep() - Stack Overflow . Lösung: Game logik im eigenen Thread, invokeAndWait aufrufen.

Mit dem anderen Thread: https://forum.byte-welt.net/java-forum/allgemeine-themen/20005-minimax-algorithmus.html , ist das Spiel nun fertig. Wenn ihr testen möchtet, wie schnell ein CPU kern bei euch ist, und das Spiel auch mal starten wollt: [Minimum Java 1.6 wird benötigt.] Ist eine .exe datei. Bitte entpacken und starten, bitte nicht Rückübersetzen.

Exe?

Ist eine gepackte und in eine .exe-Datei gewrappte .jar, u. A. der Benutzerfreundlichkeit wegen.[li] Und hier ist Version 2: (flüssiger, der Benutzer muss nicht so lange warten).
[/li]
[li] Außerdem soll das nicht sofort Zurückübersetzt werden. :smiley:
[/li]
Wie findest du es, Marco?

Ich werde mit Sicherheit keine ominös-abstruse EXE-Datei starten. Eine ausführbare JAR vielleicht (die kann auch viel Mist machen, aber nicht ganz so fiesen…), aber auch nur, wenn mich das interessiert, was ich da dann vielleicht sehen würde.

Richtig fies. … Aber bitte: . Schau’s dir an, vielleicht lernst du ein neues Spiel - oder bist begeistert. :wink: