JTable dynamisch Zeilen hinzufügen und entfernen

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen

Mit folgendem Code kann man, ähnlich wie in Excel Zeilen dynamisch beim Scrollen in die JTable einfügen oder auch leere, nicht benutzte Zeilen wieder löschen.

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.table.*;

public class DynamicRows extends JFrame implements AdjustmentListener {

    private JScrollPane jScrollPane1;
    private JTable jTable1;
    private DefaultTableModel model;
    private int yVisible, yVisibleOld;
    private boolean valueIsAdjusting = false;

    public DynamicRows() {
        super("DynamicRows");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400, 300);
        setLocationRelativeTo(null);
        jScrollPane1 = new JScrollPane();
        jTable1 = new JTable();
        jTable1.setModel(new DefaultTableModel(
                new Object[][]{},
                new String[]{
                    "Title 1", "Title 2", "Title 3", "Title 4"
                }));
        jScrollPane1.setViewportView(jTable1);
        getContentPane().add(jScrollPane1, BorderLayout.CENTER);
        model = (DefaultTableModel) jTable1.getModel();
        for (int i = 0; i < 20; i++) {
            model.addRow(new Object[]{null, null, null, null});

        }

        jScrollPane1.getVerticalScrollBar().addAdjustmentListener(this);
    }

    public void adjustmentValueChanged(final AdjustmentEvent e) {
        if (e.getValueIsAdjusting()) {
            valueIsAdjusting = true;
            return;
        }
        Adjustable a = e.getAdjustable();
        Rectangle rectBottom = jTable1.getCellRect(model.getRowCount() - 1, 0, true);
        int yBottom = rectBottom.y + rectBottom.height;
        Rectangle rectVisible = jTable1.getVisibleRect();
        yVisible = rectVisible.y + rectVisible.height;
        //if we are scrolling upwards:
        if (yVisible != 0 && yVisible < yVisibleOld) {
            //remove all invisible rows if they area empty (from bottom to top):
            boolean remove = true;
            for (int row = jTable1.getRowCount() - 1; row > -1; row--) {
                if (jTable1.getCellRect(row, 0, true).y > yVisible) {//if row is invisible
                    for (int column = 0; column < jTable1.getColumnCount(); column++) {
                        Object value = jTable1.getValueAt(row, column);
                        if (value != null) {//if the row is not empty
                            remove = false;//do not remove any more rows
                        }
                    }
                    if (remove) {
                        model.removeRow(row);
                    }
                }
            }
        } else {
			//here we are scrolling downwards
            //if visible area is at bottom:
            if ((yBottom == yVisible)) {
                if (valueIsAdjusting) {
                    valueIsAdjusting = false;
                    rectVisible.y = rectVisible.y - 2;
                    yVisible = yVisible - 2;
                    jTable1.scrollRectToVisible(rectVisible);
                } else {
                    a.removeAdjustmentListener(this);
                    //add new row and scroll to visible:
                    model.addRow(new Object[]{null, null, null, null});
                    rectBottom = jTable1.getCellRect(model.getRowCount() - 1, 0, true);
                    rectBottom.height = rectBottom.height - 1;
                    jTable1.scrollRectToVisible(rectBottom);
                    a.addAdjustmentListener(this);
                }
            }
        }
        yVisibleOld = yVisible;

    }

    public static void main(final String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new DynamicRows().setVisible(true);
            }
        });
    }
}

(Basierend auf einem Codebeispiel von Marco13)