001package ball.swing.table;
002/*-
003 * ##########################################################################
004 * Utilities
005 * %%
006 * Copyright (C) 2008 - 2022 Allen D. Ball
007 * %%
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *      http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 * ##########################################################################
020 */
021import java.util.Arrays;
022import javax.swing.event.TableModelEvent;
023import javax.swing.event.TableModelListener;
024import javax.swing.table.AbstractTableModel;
025import lombok.ToString;
026
027/**
028 * {@link AbstractTableModel} implementation.
029 *
030 * {@bean.info}
031 *
032 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
033 */
034@ToString
035public abstract class AbstractTableModelImpl extends AbstractTableModel implements TableModelListener {
036    private static final long serialVersionUID = -4459832803497493630L;
037
038    /** @serial */ private String[] names = new String[] { };
039    /** @serial */ private Class<?>[] types = new Class<?>[] { };
040
041    /**
042     * Construct a {@link javax.swing.table.TableModel} with the specified
043     * column names.
044     *
045     * @param   names           The column names.
046     */
047    protected AbstractTableModelImpl(String... names) {
048        super();
049
050        if (names.length > 0) {
051            this.names = Arrays.copyOf(names, names.length);
052            this.types = Arrays.copyOf(types, names.length);
053        } else {
054            throw new IllegalArgumentException("names=" + Arrays.asList(names));
055        }
056
057        addTableModelListener(this);
058    }
059
060    /**
061     * Construct a {@link javax.swing.table.TableModel} with the specified
062     * number of columns.
063     *
064     * @param   columns         The number of columns.
065     */
066    protected AbstractTableModelImpl(int columns) {
067        this(new String[columns]);
068    }
069
070    /**
071     * Convenience method to get the column names as an array.
072     *
073     * @return  The array of column names.
074     */
075    protected String[] header() {
076        String[] header = new String[getColumnCount()];
077
078        for (int x = 0; x < header.length; x += 1) {
079            header[x] = getColumnName(x);
080        }
081
082        return header;
083    }
084
085    /**
086     * Convenience method to get a column's values as an array.
087     *
088     * @param   x               The column index.
089     *
090     * @return  The array of column values.
091     */
092    protected Object[] column(int x) {
093        Object[] column = new Object[getRowCount()];
094
095        for (int y = 0; y < column.length; y += 1) {
096            column[y] = getColumnClass(x).cast(getValueAt(y, x));
097        }
098
099        return column;
100    }
101
102    /**
103     * Convenience method to get a row's values as an array.
104     *
105     * @param   y               The row index.
106     *
107     * @return  The array of row values.
108     */
109    protected Object[] row(int y) {
110        Object[] row = new Object[getColumnCount()];
111
112        for (int x = 0; x < row.length; x += 1) {
113            row[x] = getColumnClass(x).cast(getValueAt(y, x));
114        }
115
116        return row;
117    }
118
119    public int getColumnCount() { return names.length; }
120
121    @Override
122    public Class<?> getColumnClass(int x) {
123        return (types[x] != null) ? types[x] : super.getColumnClass(x);
124    }
125
126    public void setColumnClass(int x, Class<?> type) { types[x] = type; }
127
128    @Override
129    public String getColumnName(int x) { return names[x]; }
130
131    public void setColumnName(int x, String name) { names[x] = name; }
132
133    @Override
134    public abstract int getRowCount();
135
136    @Override
137    public boolean isCellEditable(int y, int x) { return false; }
138
139    @Override
140    public abstract Object getValueAt(int y, int x);
141
142    @Override
143    public void setValueAt(Object value, int y, int x) {
144        throw new UnsupportedOperationException("setValueAt(Object,int,int)");
145    }
146
147    @Override
148    public void tableChanged(TableModelEvent event) { }
149}