JTable i KeyListener

0

Moja tabela ma 2 kolumny. Jak zrobić, żeby do pierwszej użytkownik mógł wpisać tylko 5 cyfr (0 albo 1), a do drugiej tylko 2 cyfry (0,1 albo '?' )?

Domyślam się, że będzie trzeba skorzystać z KeyListenera, dlatego napisałem takie coś:

tab.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent e){
                char c = e.getKeyChar();
                System.out.print(c);
            } 
        });

Lecz niestety w konsoli nic mi się nie pojawia :-(

0

U mnie się pojawia, ale i tak bym to zrobił tak:

public class Frame extends JFrame {

    private JTable table;
    private TableModel model;

    public Frame() {
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        //robisz sobie własny model
        model = new DefaultTableModel(new String[] { "1" , "2"}, 10) {

            //sam w nim zapisujesz wartosci ktore wprowadzasz
            @Override
            public void setValueAt(Object value, int row, int column) {
                if(column == 0) setValueAtFirstColumn(value, row, column);
                else if(column == 1) setValueAtSecoundColumn(value, row, column);
                else super.setValueAt(value, row, column);
            }

            //przed zapisaniem sprawdzasz czy mozesz zapisac (dla pierwszej kolumny)
            private void setValueAtFirstColumn(Object value, int row, int column) {
                int max = 5;
                int count = 0;
                for(int i = 0; i < getRowCount(); i++) {
                    String v = (String) getValueAt(i, column);
                    if("0".equals(v) || "1".equals(v)) count ++;
                }
                if(("0".equals(value) || "1".equals(value)) && count >= max) return;
                super.setValueAt(value, row, column);
            }

            //(dla drugiej)
            private void setValueAtSecoundColumn(Object value, int row, int column) {
                int max = 2;
                int count = 0;
                for(int i = 0; i < getRowCount(); i++) {
                    String v = (String) getValueAt(i, column);
                    if("0".equals(v) || "1".equals(v) || "?".equals(v)) count ++;
                }
                if(("0".equals(value) || "1".equals(value) || "?".equals(value)) && count >= max) return;
                super.setValueAt(value, row, column);
            }
        };
        table = new JTable(model);
        add(table);
        pack();
    }
}
0

dzięki za odpowiedź! Przetestowałem Twój przykład i niestety nadal mogę do tabeli wpisać co chcę i ile chcę :-(.

0

Zmień na to:

private void setValueAtFirstColumn(Object value, int row, int column) {
    if("".equals(value)) super.setValueAt(value, row, column);
    if(!"0".equals(value) && !"1".equals(value)) return;
    int max = 5;
    int count = 0;
    for(int i = 0; i < getRowCount(); i++) {
        String v = (String) getValueAt(i, column);
        if(i != row && ("0".equals(v) || "1".equals(v))) count ++;
    }
    if(count >= max) return;
    super.setValueAt(value, row, column);
}

i analogicznie zapisywanie do 2 kolumny.

To wcześniej pozwala wpisać co się chce, ale więcej niż 5 cyfr 0 albo 1 zabroni.

0

Ja bym zrobił to na zasadzie edytora:

package test;

import java.awt.BorderLayout;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import javax.swing.text.PlainDocument;

/**
 * Klasa testująca tabele. 
 *
 * @author jacobus2k
 * @version 0.1.0
 */
public final class TableTester extends JFrame {
    /**
     * serialVersionUID.
     */
    private static final long serialVersionUID = 2177419577626910109L;

    /**
     * Tabela.
     */
    private JTable table;

    /**
     * Konstruktor.
     */
    public TableTester() {
        super("Test");
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setSize(300, 400);
        this.initComponents();
        this.createLayout();
    }

    /**
     * Inicjuje komponenty.
     */
    private final void initComponents() {
        this.table = new JTable(5, 2);
        // tworze edytor pierwszej kolumny
        final DefaultCellEditor column1Editor = new DefaultCellEditor(
                new JTextField());
        // wyciągam komponent edytora (rzutuje do tekst komponentu i ustawiam
        // formatowany dokumen
        ((JTextComponent) column1Editor.getComponent()).setDocument(
                new FormattedDocument("[^01]", false, 5));
        this.table.getColumnModel().getColumn(0).setCellEditor(column1Editor);
        // tworze edytor drugiej kolumny
        final DefaultCellEditor column2Editor = new DefaultCellEditor(
                new JTextField());
        // wyciągam komponent edytora (rzutuje do tekst komponentu i ustawiam
        // formatowany dokument
        ((JTextComponent) column2Editor.getComponent()).setDocument(
                new FormattedDocument("[^01?]", false, 2));
        this.table.getColumnModel().getColumn(1).setCellEditor(column2Editor);

    }

    /**
     * Tworzy layout.
     */
    private final void createLayout() {
        this.getContentPane().setLayout(new BorderLayout());
        this.getContentPane().add(new JScrollPane(this.table), 
                BorderLayout.CENTER);
    }

    /**
     * Main.
     * 
     * @param args
     */
    public static final void main(final String[] args) {
        final TableTester tester = new TableTester();
        tester.setVisible(true);
    }
}

class FormattedDocument extends PlainDocument {

    /**
     * serialVersionUID.
     */
    private static final long serialVersionUID = 2911052591988857807L;

    /**
     * Wyrażenie regularne.
     */
    private String regex = null;

    /**
     * Określa czy wpisany tekst ma pasować do wyrażania regularnego.
     */
    private boolean match = false;

    /**
     * Maksymalna długość tekstu.
     */
    private int maxLength = Integer.MAX_VALUE;

    /**
     * Konstruktor.
     */
    public FormattedDocument() {
        super();
    }

    /**
     * Konstruktor.
     *
     * @param expr wyrażenie regularne
     * @param m true - jeżeli tekst ma pasować do wyrażenia regularnego, false
     *  w przeciwnym wypadku
     * @param max maksymalna dozwolona długość tekstu
     */
    public FormattedDocument(final String expr, final boolean m, final int max) {
        super();
        this.regex = expr;
        this.match = m;
        this.maxLength = max;
    }

    /**
     * Konstruktor.
     *
     * @param max maksymalna dozwolona długość tekstu
     */
    public FormattedDocument(final int max) {
        this(null, false, max);
    }

    /**
     * Konstruktor.
     *
     * @param expr wyrażenie regularne
     * @param m true - jeżeli tekst ma pasować do wyrażenia regularnego, false
     *  w przeciwnym wypadku
     */
    public FormattedDocument(final String expr, final boolean m) {
        this(expr, m, Integer.MAX_VALUE);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void insertString(final int offs, final String str, 
            final AttributeSet a)  throws BadLocationException {
        if (str == null) {
            return;
        }
        if (this.regex == null) {
            // jeżeli nie podano wyrażenia regularnego sprawdzam długość
            if (this.getLength() + str.length() <= this.maxLength) {
                super.insertString(offs, str, a);
            }
        } else {
            final Matcher m = Pattern.compile(this.regex).matcher(str);
            if ((m.find() == !match) || this.getLength() + str.length() > 
                this.maxLength) {
                return;
            }
            super.insertString(offs, str, a);
        }
    }

}

Formatowanie można by bardziej rozbudować, w zależności od potrzeb.

0

dzięki za odpowiedzi!
Abe: niestety nadal mogę wpisywać co chcę :( niby kod wygląda jasno i logicznie, a jednak nie działa;
jacobus2k: zrobiłem tak jak napisałeś, tabelka wreszcie działa tak jak chciałem, szkoda tylko, że jest to tak skomplikowane :)

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