JTable Problem

MScalli

Erfahrenes Mitglied
Hi Leutz.
Ich hänge jetzt schon ewig an ein und demselben Problem.
Ich hab jetzt ewig gebraucht um alles in 1 Lauffähiges Programm zu bringen.

Also BITTE schaut es euch mal an.

Mein Problem.
Ich muss beim verlassen des Feldes eine Prüfung machen und dann entweder den Inhalt des Feldes ändern oder einfach in diesem Feld bleiben.

Code:
import static java.lang.Math.random;

import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.border.Border;
import java.awt.Dimension;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;


public class TestJTable implements ActionListener{

  // Desktop
  Container desktop;

  static JFrame frame;
  static int frameWidth = 850;
  static int frameHeight = 620;

  public TestJTable() {

    frame = new JFrame();
    frame.setSize(new Dimension(frameWidth,frameHeight));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// ******************************************************************************************************************************

    // Tabelle erstellen und adden
    CreateTableWithColumn table_panel = new CreateTableWithColumn(
                                    getColumnNames(),
                                    getData(),
                                    getWidthArray(),
                                    getLengthArray(),
                                    getArrayDecimalPlaces()
    );
    frame.add(table_panel);

// ******************************************************************************************************************************

    frame.setResizable(false);
    frame.setVisible(true);
  }

public static void main(String[] args){
  new TestJTable();
}

// Länge der einzelnen Felder (also Inhalt in Zeichen)
private static int[] getLengthArray() {
  int[] length = {4, 60};
  return length;
}

// breite der einzelnen Felder
private static int[] getWidthArray() {
  int[] width_array = {100, 695};
  return width_array;
}

// bezeichnung der einzelnen Felder
private static String[] getColumnNames() {
  String[] column_names  = {  "Schl.",
                              "Bezeichnung"};

  return column_names;
}

// art der einzelnen Felder
private static Object[][] getArrayDecimalPlaces() {
  Object[][] data = {
      {"I"},
      {"C"}
      };

  return data;
}

// inhalt der einzelnen Felder
private static Object[][] getData() {
  Object[][] data = {
      {"12", "23",},
      {"34", "45",}
      };

  return data;
}

@Override
public void actionPerformed(ActionEvent ae) {
  String cmd = ae.getActionCommand();
  System.out.println(cmd);
}

}// ENDE



class CreateTableWithColumn extends JPanel implements ActionListener{

  private static final long serialVersionUID = -2306289506379055756L;

  String[] column_names;
  Object[][] data;
  TableModel MyTableModel;
  int width = 800;
  int height = 500;
  

    public CreateTableWithColumn(String[] _column_names, Object[][] _data, int[] _width_array, int[] _char_length, Object[][] _arr_decimal_place) {
        super(new BorderLayout());

        column_names = _column_names;
        data = _data;

        final DefaultTableModel model = new DefaultTableModel(data, column_names);

        final JTable table = new JTable(model);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        // Panel Kopf(hier werden die Buttons geaddet
        JPanel kopf = new JPanel();
        kopf.setPreferredSize(new Dimension(800,40));
        kopf.setLayout(null);
        add(kopf, BorderLayout.NORTH);

        // Panel erzeugen auf dem alles liegen soll
        JPanel panel = new JPanel();

        //ScrollPane erzeugen und JTable adden
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setPreferredSize(new Dimension(width,height));

        //grösse der Zellen setzten
        initColumn(table, _width_array, _char_length, _arr_decimal_place);

        //JPanel und JScrollPane hinzufügen.
        add(panel);
        panel.add(scrollPane);

    }

  private void initColumn(final JTable table, int[] _width_array, int[] _char_length, Object[][] _arr_decimal_places) {
        TableColumn column = null;

        // hier wird setDocument() aufgerufen (notwendig wegen der Prüfungen während der Eingabe
        for (int i = 0; i < _width_array.length; i++) {

            final JFormattedTextField tf = new JFormattedTextField();
            if(_arr_decimal_places[i][0].toString().equals("C")){
              tf.setDocument(new LimitedCharDocument(_char_length[i]));
            }
            if(_arr_decimal_places[i][0].toString().equals("I")){
              tf.setDocument(new LimitedDecimalDocument(_char_length[i]));
            }

        tf.addFocusListener(new FocusListener(){
          public void focusGained(FocusEvent arg0) {
            tf.setBackground(Color.YELLOW);
                tf.setSelectionStart(0);
                tf.setSelectionEnd(tf.getText().length());
          }
          public void focusLost(FocusEvent arg0) {
            tf.setBackground(Color.WHITE);
            System.out.println("Jetzt verlasse ich das TextFeld. ");
            // Hier soll eine Prüfung des Feldes erfolgen. Falls false einfach in Feld bleiben
            // Prüfung usw. ist nicht das Problem, aber wie kann ich das Feld ändern bzw. darauf zugreifen
            // besser wenn ich weiter bei setValueAt() bleiben könnte. Aber seit ich das Textfeld benutze
            // komme ich nicht mehr in diese Methoden

          }
        });

            column = table.getColumnModel().getColumn(i);
            column.setCellEditor(new DefaultCellEditor(tf));
            column.setPreferredWidth(_width_array[i]);
        }
  }

    class MyTableModel extends AbstractTableModel {

    private static final long serialVersionUID = -2764611210789334359L;

    public int getColumnCount() {
           System.out.println("getColumnCount");
            return column_names.length;
        }

        public int getRowCount() {
          System.out.println("gerRowCount");
            return data.length;
        }

        public String getColumnName(int col) {
          System.out.println("getColumnName");
            return column_names[col];
        }

        public Object getValueAt(int row, int col) {
          System.out.println("getValueAt");
          System.out.println(data[row][col]);
            return data[row][col];
        }

        public void setValueAt(Object val, int row, int col) {
          // Das hier passiert ja nicht mehr.. Sonst wärs kein Problem!
          System.out.println("In setValueAt() --> verlassen einer Zelle der Tabelle");
          System.out.println("value = " + val);
            data[row][col] = val;
            fireTableCellUpdated(row, col);

        }

        /*
         * JTable benutzt diese Methode um den Default Renderer zu beenden
         * sonst würde z.B. statt CheckBoxen nur (true/false) drin stehen
         */
        @SuppressWarnings("unchecked")
    public Class getColumnClass(int c) {

            return getValueAt(0, c).getClass();
        }

        /*
         * Hier kann man bestimmte Zellen editierbar machen
         * Beispiel Zelle 0 nicht editierbar machen
         * if (col == 0) {
         *     return false;
         * }
         */
        public boolean isCellEditable(int row, int col) {

                return true;
        }
    }

  @Override
  public void actionPerformed(ActionEvent ae) {
    String cmd = ae.getActionCommand();
    System.out.println(cmd);
  }
}

class LimitedCharDocument extends javax.swing.text.PlainDocument {
    /**
   *
   */
  private static final long serialVersionUID = -8098512724885725859L;
  private int maxLen = -1;

    public LimitedCharDocument() {

    }

    public LimitedCharDocument(int maxLen) {
      this.maxLen = maxLen;
    }

    public void insertString(int param, String str, javax.swing.text.AttributeSet attributeSet) throws javax.swing.text.BadLocationException {

        if (str != null && maxLen > 0 && this.getLength() + str.length() > maxLen) {

            java.awt.Toolkit.getDefaultToolkit().beep();
            return;
        }

        super.insertString(param, str, attributeSet);
    }
}

/**
 * Diese Klasse ist ein Dokument für Textfelder, welches...
 *
 * 1. Eingabe auf x Zeichen begrenzt.
 * 2. Nur die Zeichen zulässt die in der Variable valid stehen
 * 3. Nur 1 Komma bzw. Minus zulässt // folgt noch !!
 *
 * Die Zuweisung geschieht über
 * JTextfield.setDocumenT(new Validation(int anzahl));
 */
class LimitedDecimalDocument extends PlainDocument{

  private static final long serialVersionUID = 5032290234368360350L;

  private int maxLen = -1;
  String merk = "";

  static int places_befor_decimal_point = 0;
  static int places_after_decimal_point = 0;

    /**
     * Konstruktor für das Validationdokument
     * @param int limit: maximale Anzahl der einzugebenen Zeichen
     */
    public LimitedDecimalDocument(int maxLen) {
      this.maxLen = maxLen;
    }

    /**
     * Funktion überschreibt die Methode insertString von PlaintDocument
     * @param int offset: Position
     * @param String str: der String
     * @param AttributeSet attr: Attributset
     */
    public void insertString (int offset, String str, AttributeSet attr) throws BadLocationException {

        //Zeichenkette mit den gültigen Zeichen
        String valid = "-,0123456789 ";

      if (str != null && maxLen > 0 && this.getLength() + str.length() > maxLen) {

          java.awt.Toolkit.getDefaultToolkit().beep();
          return;
      }
      for (int i=0; i<str.length();i++) {
          if (valid.indexOf(str.charAt(i)) == -1) {
            // wenn man hier rein kommt ist das eingegebene Zeichen ungültig!!
              return;
          }
      }

        System.out.println(getText(0, offset) + str);

        //Wichtig Aufruf der übergeordneten Methode
        super.insertString(offset, str, attr);
      }
}
 

Neue Beiträge

Zurück