Formatowanie JTable

0

Witam serdecznie! Mam pytań kilka: mam tabelę JTable plansza. Rozmiar 9x9:

  1. Jak obramować bądź wyróżnić innym tłem każdy kwadrat w tabeli rozmiaru 3x3 w tabeli 9x9?
  2. jak sprawić by w momencie wpisywania danych do komórki tabeli nie klikać potem na inną komórkę, żeby wpisywane dane "weszły" do tabeli (wpisuję jakąś liczbę do komórki tabeli i jeśli kursor miga w tej komórce i kliknę na przycisk wylicz - ta wprowadzana wartość nie zostaje uwzzględniona w tabeli - nie ma jej)

Szukałem odpowiedzi na te bolączki i nie znalazłem zadowalającego rezultatu. Może, a raczej wiem, że Wy pomożecie. Dziękuję i pozdrawiam. Mój kod:

 private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        plansza = new javax.swing.JTable();
        btn_poprawnosc = new javax.swing.JButton();
        btn_rozwiaz = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        plansza.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        plansza.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        plansza.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null, null}
            },
            new String [] {
                "", "", "", "", "", "", "", "", ""
            }
        ));
        plansza.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        plansza.setRowHeight(35);
        jScrollPane1.setViewportView(plansza);

        btn_poprawnosc.setText("Sprawdź poprawność");
        btn_poprawnosc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_poprawnoscActionPerformed(evt);
            }
        });

        btn_rozwiaz.setText("Rozwiąż");
        btn_rozwiaz.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_rozwiazActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 338, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 54, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(btn_rozwiaz, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btn_poprawnosc, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(42, 42, 42))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btn_poprawnosc)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(btn_rozwiaz))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 318, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>      
0

Cześć.
Kiedyś coś podobnego robiłem - wpisywanie do tabeli wartości i zatwierdzanie.
Dokładnie nie pamietam, ale jest cos takiego, jak TableCellEditor - Poszukaj na sieci.
To jest edytor komórek JTable.

W jakis sposób, nie pamietam jak dodaje się tam listenera dla tego pola, aby np. reagował na naciśnięcie ENTER wywołując metodę stopCellEditing().

Pod ręką nie mam niestety eclipse'a z żadnym z moich programów, więc nie mam nawet jak Ci tutaj rzucić kawałka kodu.
Spróbuj poszukac na sieci TableCellEditor i DefaultTableCellEditor.
Jeśli nic nie znajdziesz pomocnego, to daj znać, wieczorem będę w domu, to zapuszczę swojego eclipse'a i poszukam przykładowego kodu.

Pozdro.

0
Black007 napisał(a)

Cześć.
Kiedyś coś podobnego robiłem - wpisywanie do tabeli wartości i zatwierdzanie.
Dokładnie nie pamietam, ale jest cos takiego, jak TableCellEditor - Poszukaj na sieci.
To jest edytor komórek JTable.

W jakis sposób, nie pamietam jak dodaje się tam listenera dla tego pola, aby np. reagował na naciśnięcie ENTER wywołując metodę stopCellEditing().

Pod ręką nie mam niestety eclipse'a z żadnym z moich programów, więc nie mam nawet jak Ci tutaj rzucić kawałka kodu.
Spróbuj poszukac na sieci TableCellEditor i DefaultTableCellEditor.
Jeśli nic nie znajdziesz pomocnego, to daj znać, wieczorem będę w domu, to zapuszczę swojego eclipse'a i poszukam przykładowego kodu.

Pozdro.

Hej! Jakbyś mógł zarzucić kodem, byłbym bardzo wdzięczny... Pozdro!

0

Witam.
Wiesz co, domyślne ustawienie jest chyba takie, e powinien działać enter, żeby zatwierdzić wpisaną wartość.
Przynajmniej u mnie tak działa.
A bardzo prosty przykład, który nic nie robi specjalnego, jest np. taki:

        jTable1.setCellEditor(new TableCellEditor() {

            private JTextField field = new JTextField();

            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
                return field;
            }

            public Object getCellEditorValue() {
                return field.getText();
            }

            public boolean isCellEditable(EventObject anEvent) {
                return true;
            }

            public boolean shouldSelectCell(EventObject anEvent) {
                return true;
            }

            /**
             * Tutaj można zapisać dane.
             */
            public boolean stopCellEditing() {
                return true;
            }

            public void cancelCellEditing() {

            }

            public void addCellEditorListener(CellEditorListener l) {

            }

            public void removeCellEditorListener(CellEditorListener l) {

            }
        });

A jeśli chodzi o listener dla komórki w tabeli:

        JTextField text = new JTextField();
        text.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                //dodawanie do dokumentu, czyli wpisywanie
            }

            public void removeUpdate(DocumentEvent e) {
                //usuwanie z dokumentu czyli usuwanie textu
            }

            public void changedUpdate(DocumentEvent e) {
                //jakakolwiek zmiana w dokumencie.
            }
        });

Czyli tak tworzymy obiekt Celleditora, w jego środku jako zmienna egzemplarza ładujemy Jtextfield - on będzie naszym komponentem renderującym.
Z JText pobieramy Document i dodajemy do niego documentListener i viola. :)

Jakbyś jeszcze miał kłopoty to się odezwij.
Ostrzegam, ze zabawy z tym nie są łatwe (znaczy może są, ale ja robiłem celleditor, który robił wszystko łącznie z parzeniem kawy i przewijaniem dzieci...).

Pozdro.

0

Czy można jakoś prościej? W momencie wpisywania danych do JTable muszę np. kliknąć ENTER, aby te dane "weszły do tabeli"... Moje pytanie: jaki kod odpowiada za to, aby wpisane lecz nie zatwierdzone dane automatycznie byly zatwierdzane za pomocą actionListenera? Pozdrawiam

0

Hej.

Spróbuj może tak:
Opcja 1) Jak klikasz w przycisk, to tabel traci focus, mógłbyś dodać listener do zdarzenia focusLost, żeby na wystąpienie tego zdarzenia tabela zapisywała do modelu wartości z widoku.

Opcja 2) w listenerze kliknięcia przycisku robisz tak, że aktualizujesz model tabeli tym, co jest wpisane w widoku.

Niestety nie mam w tej chwili czasu, żeby przetestować jakiś kod. Pokombinuj, poczytaj o JTable o jego listenerach itp. itd.

Pozdrawiam.

0
Black007 napisał(a)

Hej.

Spróbuj może tak:
Opcja 1) Jak klikasz w przycisk, to tabel traci focus, mógłbyś dodać listener do zdarzenia focusLost, żeby na wystąpienie tego zdarzenia tabela zapisywała do modelu wartości z widoku.

Opcja 2) w listenerze kliknięcia przycisku robisz tak, że aktualizujesz model tabeli tym, co jest wpisane w widoku.

Niestety nie mam w tej chwili czasu, żeby przetestować jakiś kod. Pokombinuj, poczytaj o JTable o jego listenerach itp. itd.

Pozdrawiam.

A można bardziej szczegółowo? Dalej nie znam komendy potwierdzającej "częściowo wpisane dane" (niezatwierdzone enterem) za pomocą listenera... Po prostu nie chcę naciskać ENTER po każdym wpisaniu danych do komórki, tylko chcę, aby to było robione automatycznie... Pozdrawiam i dziękuję za wszelką pomoc

0

Ok.
Zrób tak:
Dodaj klasę implementującą TableCellEditor.
Do niej dodaj w środku obiekt JtextField.
Zaimplementuj Żeby edytor zwracał przez getTableCellEditorComponent tego textfielda.

Do JTextFielda dodaj KeyListenera. W tym listenerze przeładuj metodę keyReleased.
keyReleased - działa gdy użytownik puszcza klawisz. PRzeładują ją tak, aby pobiarała z texfielda wartość i zapisywała ją do modelu tabeli.

Dzięki temu uzyskasz efekt jaki potrzebujesz.
Nie musisz naciskać entera a dane beda sie w modelu zapisywac przy kazdym wpisaniu/usunieciu czegokolwiek.

Pozdrawiam.

0

Przecież użytkownik musi jakoś zasygnalizować, że skończył edycję, np. naciskając klawisz Enter. Wystarczy aktualizować model tylko po zwolnieniu tego klawisza.

0
bo napisał(a)

Przecież użytkownik musi jakoś zasygnalizować, że skończył edycję, np. naciskając klawisz Enter. Wystarczy aktualizować model tylko po zwolnieniu tego klawisza.

Ale autorowi chodzi o to, żeby nie musieć naciskać entera.
Więc musi nakazać, żeby model odświeżał swoją zawartość po każdym naciśnięciu klawisza.

0

Skąd wziąłeś tę informację?

W momencie wpisywania danych do JTable muszę np. kliknąć ENTER
Chodzi chyba o kliknięcie przycisku z napisem ENTER.
Pomysł by aktualizować model po każdym naciśniętym klawiszu ("a",backspace,"a",backspace,....) wydaje mi się absurdalny.

0
bo napisał(a)

Skąd wziąłeś tę informację?

Z postu autora:

Mateluta napisał(a)

jak sprawić by w momencie wpisywania danych do komórki tabeli nie klikać potem na inną komórkę, żeby wpisywane dane "weszły" do tabeli (wpisuję jakąś liczbę do komórki tabeli i jeśli kursor miga w tej komórce i kliknę na przycisk wylicz - ta wprowadzana wartość nie zostaje uwzzględniona w tabeli - nie ma jej)

bo napisał(a)

Pomysł by aktualizować model po każdym naciśniętym klawiszu ("a",backspace,"a",backspace,....) wydaje mi się absurdalny.

Dlaczego?

0

Bo użytkownik nie ma powrotu do sytuacji startowej, nie może zrezygnować z wprowadzonych zmian. W tym programie nie ma to pewnie znaczenia, domyślam się że chodzi o Sudoku zatem dane w komórkach to liczby jednocyfrowe łatwo więc spamiętać co było przed edycją i wpisać to ponownie (w razie rezygnacji).

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