TableLayout

Aus Byte-Welt Wiki
Wechseln zu: Navigation, Suche

TableLayout.jpg

Die unten gezeigte Klasse "TableLayout" ermöglicht das Anordnen von Swing Komponenten in Form einer Tabelle. "TableLayoutDemo" zeigt ein Beispiel, wie sie verwendet werden kann:

import java.awt.*;
import java.util.*;
import javax.swing.*;
 
/**
 * TableLayoutDemo shows you, how to use the "TableLayout" class.
 * 
 * @author André Uhres
 */
public class TableLayoutDemo extends JFrame {
 
    private TableLayout tableLayout;
    private final Random r;
 
    /**
     * Create a TableLayoutDemo.
     */
    public TableLayoutDemo() {
        super("TableLayout Demo");
        r = new Random();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(600, 600);
        setLocationRelativeTo(null);
        //create empty TableLayout:
        tableLayout = new TableLayout();
        //fill the TableLayout:
        for (int row = 0; row < 5; row++) {
            //create a test panel:
            JPanel panel = createTestPanel(row);
            //add to TableLayout:
            tableLayout.addRow(panel);
        }
        getContentPane().add(new JScrollPane(tableLayout), BorderLayout.CENTER);
    }
 
    private JPanel createTestPanel(int row) {
        JPanel panel = new JPanel();
        panel.add(new JLabel("Panel " + row));
        //generate random height for testing only:
        int height = r.nextInt(200);
        if (height < 34) {
            height = 34;
        }
        panel.setPreferredSize(new Dimension(0, height));
        return panel;
    }
 
    /**
     * Method for testing.
     * @param args
     */
    public static void main(final String[] args) {
        EventQueue.invokeLater(new Runnable() {
 
            @Override
            public void run() {
                new TableLayoutDemo().setVisible(true);
            }
        });
 
    }
}
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
 
/**
 * With "TableLayout" we can lay out any Swing components in the form of a table.
 * 
 * @author André Uhres
 */
public class TableLayout extends JTable {
 
    /**
     * Constructs a TableLayout with 0 rows and 0 columns.
     * For adding data see the methods "addColumns" and "addRow".
     * Note that the method "addRow" automatically adds missing columns.
     */
    public TableLayout() {
        super(0, 0);
        setDefaultRenderer(JComponent.class, new TableLayoutRenderer());
        setDefaultEditor(JComponent.class, new TableLayoutEditor());
        setSurrendersFocusOnKeystroke(true);
    }
 
    @Override
    public TableCellRenderer getCellRenderer(final int row, final int column) {
        TableColumn tableColumn = getColumnModel().getColumn(column);
        TableCellRenderer renderer = tableColumn.getCellRenderer();
        if (renderer == null) {
            Class c = getColumnClass(column);
            if (c.equals(Object.class)) {
                Object o = getValueAt(row, column);
                if (o != null) {
                    c = getValueAt(row, column).getClass();
                }
            }
            renderer = getDefaultRenderer(c);
        }
        return renderer;
    }
 
    @Override
    public TableCellEditor getCellEditor(final int row, final int column) {
        TableColumn tableColumn = getColumnModel().getColumn(column);
        TableCellEditor editor = tableColumn.getCellEditor();
        if (editor == null) {
            Class c = getColumnClass(column);
            if (c.equals(Object.class)) {
                Object o = getValueAt(row, column);
                if (o != null) {
                    c = getValueAt(row, column).getClass();
                }
            }
            editor = getDefaultEditor(c);
        }
        return editor;
    }
 
    /**
     *
     * @param columnNames one or more names to be added as columns
     */
    public void addColumns(final String... columnNames) {
        DefaultTableModel model = (DefaultTableModel) getModel();
        for (String name : columnNames) {
            model.addColumn(name);
        }
    }
 
    /**
     *
     * @param objects one or more components to be added as a row
     */
    public void addRow(final Object... objects) {
        DefaultTableModel model = (DefaultTableModel) getModel();
        while (model.getColumnCount() < objects.length) {
            model.addColumn("");
        }
        model.addRow(objects);
        int h = getRowHeight(getRowCount() - 1);
        for (Object obj : objects) {
            JComponent comp = null;
            if (obj instanceof JComponent) {
                comp = (JComponent) obj;
                int h2 = comp.getPreferredSize().height;
                if (h < h2) {
                    h = h2;
                }
            }
        }
        setRowHeight(getRowCount() - 1, h);
    }
 
    /**
     * 
     * @param row the model index of the row
     */
    public void removeRow(int row) {
        if (row > -1) {
            DefaultTableModel model = (DefaultTableModel) getModel();
            TableCellEditor editor = getCellEditor();
            if (editor != null) {
                editor.stopCellEditing();
            }
            model.removeRow(convertRowIndexToModel(row));
        }
 
    }
 
    private class TableLayoutEditor implements TableCellEditor, Serializable {
 
        protected EventListenerList listenerList = new EventListenerList();
        protected transient ChangeEvent changeEvent = null;
        protected JComponent editorComponent = null;
 
        public Component getComponent() {
            return editorComponent;
        }
        /* implement CellEditor:
        getCellEditorValue
        isCellEditable
        shouldSelectCell
        stopCellEditing
        cancelCellEditing
        addCellEditorListener
        removeCellEditorListener
         */
 
        @Override
        public Object getCellEditorValue() {
            return editorComponent;
        }
 
        @Override
        public boolean isCellEditable(final EventObject anEvent) {
            return true;
        }
 
        @Override
        public boolean shouldSelectCell(final EventObject anEvent) {
            if (editorComponent != null && anEvent instanceof MouseEvent
                    && ((MouseEvent) anEvent).getID() == MouseEvent.MOUSE_PRESSED) {
                Component dispatchComponent =
                        SwingUtilities.getDeepestComponentAt(editorComponent, 3, 3);
                MouseEvent e = (MouseEvent) anEvent;
                MouseEvent e2 = new MouseEvent(dispatchComponent,
                        MouseEvent.MOUSE_RELEASED, e.getWhen() + 100000,
                        e.getModifiers(), 3, 3, e.getClickCount(), e.isPopupTrigger());
                dispatchComponent.dispatchEvent(e2);
                e2 = new MouseEvent(dispatchComponent, MouseEvent.MOUSE_CLICKED,
                        e.getWhen() + 100001, e.getModifiers(), 3, 3, 1, e.isPopupTrigger());
                dispatchComponent.dispatchEvent(e2);
            }
            return true;
        }
 
        @Override
        public boolean stopCellEditing() {
            fireEditingStopped();
            return true;
        }
 
        @Override
        public void cancelCellEditing() {
            fireEditingCanceled();
        }
 
        @Override
        public void addCellEditorListener(final CellEditorListener l) {
            listenerList.add(CellEditorListener.class, l);
        }
 
        @Override
        public void removeCellEditorListener(final CellEditorListener l) {
            listenerList.remove(CellEditorListener.class, l);
        }
 
        protected void fireEditingStopped() {//used in stopCellEditing
            Object[] listeners = listenerList.getListenerList();
            // Process the listeners last to first, notifying
            // those that are interested in this event
            for (int i = listeners.length - 2; i >= 0; i -= 2) {
                if (listeners[i] == CellEditorListener.class) {
                    // Lazily create the event:
                    if (changeEvent == null) {
                        changeEvent = new ChangeEvent(this);
                    }
                    ((CellEditorListener) listeners[i + 1]).editingStopped(changeEvent);
                }
            }
        }
 
        protected void fireEditingCanceled() {//used in cancelCellEditing
            // Guaranteed to return a non-null array
            Object[] listeners = listenerList.getListenerList();
            // Process the listeners last to first, notifying
            // those that are interested in this event
            for (int i = listeners.length - 2; i >= 0; i -= 2) {
                if (listeners[i] == CellEditorListener.class) {
                    // Lazily create the event:
                    if (changeEvent == null) {
                        changeEvent = new ChangeEvent(this);
                    }
                    ((CellEditorListener) listeners[i + 1]).editingCanceled(changeEvent);
                }
            }
        }
 
// implement TableCellEditor:
        @Override
        public Component getTableCellEditorComponent(final JTable table,
                final Object value, final boolean isSelected,
                final int row, final int column) {
            editorComponent = (JComponent) value;
            return editorComponent;
        }
    }
 
    private class TableLayoutRenderer implements TableCellRenderer {
 
        @Override
        public Component getTableCellRendererComponent(final JTable table,
                final Object value, final boolean isSelected,
                final boolean hasFocus, final int row, final int column) {
            return (JComponent) value;
        }
    }
}