001package jmri.swing;
002
003import javax.annotation.Nonnull;
004import javax.swing.JTable;
005
006/**
007 * Manager for ensuring that {@link javax.swing.JTable} user interface state is
008 * persisted.
009 * <p>
010 * JTable user interface state that can be persisted includes:
011 * <ul>
012 * <li>row sort order (if the table has a non-null
013 * {@link javax.swing.RowSorter})</li>
014 * <li>column order</li>
015 * <li>column visibility</li>
016 * <li>column width</li>
017 * </ul>
018 * <p>
019 * Row sort order is only persisted for JTables that implement the
020 * {@link javax.swing.RowSorter} for sorting. If the RowSorter is null, the row
021 * sorting will not be persisted.
022 * <p>
023 * Column attributes (order, visibility, and width) are persisted by listening
024 * to changes in the {@link javax.swing.table.TableColumnModel} of the table.
025 * Column visibility is persisted only if the TableColumnModel is assignable
026 * from {@link jmri.util.swing.XTableColumnModel}. Columns will be saved using
027 * the String representation of either
028 * {@link javax.swing.table.TableColumn#getIdentifier()} or
029 * {@link javax.swing.table.TableColumn#getHeaderValue()}.
030 * <p>
031 * Tables against which {@link #persist(javax.swing.JTable)} is called without
032 * first calling {@link #resetState(javax.swing.JTable)} will not have state
033 * retained across application restarts.
034 * <p>
035 * <strong>Note:</strong> A JTable with UI state being persisted must have a
036 * unique non-null name; columns in the table must also have unique non-null
037 * identifiers or header text.
038 *
039 * @author Randall Wood Copyright (C) 2016
040 */
041public interface JTablePersistenceManager {
042
043    /**
044     * Persist the user interface state for a table. The name returned by
045     * {@link javax.swing.JComponent#getName()} is used to persist the table, so
046     * ensure the name is set such that it can be retrieved by the same name in
047     * a later JMRI execution.
048     * <p>
049     * Note that the current state of the table, if not already persisted, at
050     * the time of this call is retained as the table state. Using this method
051     * is the same as calling {@link #persist(javax.swing.JTable, boolean)} with
052     * false for the second argument.
053     *
054     * @param table the table to persist
055     * @throws IllegalArgumentException if another table instance is already
056     *                                  persisted by the same name
057     * @throws NullPointerException     if the table name is null
058     */
059    default void persist(@Nonnull JTable table) throws IllegalArgumentException, NullPointerException {
060        this.persist(table, false);
061    }
062
063    /**
064     * Persist the user interface state for a table. The name returned by
065     * {@link javax.swing.JComponent#getName()} is used to persist the table, so
066     * ensure the name is set such that it can be retrieved by the same name in
067     * a later JMRI execution.
068     * <p>
069     * Note that the current state of the table, if not already persisted, at
070     * the time of this call is retained as the table state unless
071     * {@code resetState} is true.
072     * <p>
073     * Using this method with {@code resetState} set to true is the same as
074     * {@link #resetState(javax.swing.JTable)} immediately prior to calling
075     * {@link #persist(javax.swing.JTable)}.
076     *
077     * @param table      the table to persist
078     * @param resetState reset the table to the stored state if true; retain the
079     *                   current state if false
080     * @throws IllegalArgumentException if another table instance is already
081     *                                  persisted by the same name
082     * @throws NullPointerException     if the table name is null
083     */
084    void persist(@Nonnull JTable table, boolean resetState) throws IllegalArgumentException, NullPointerException;
085
086    /**
087     * Stop persisting the table. This does not clear the persistence state, but
088     * merely causes the JTablePersistenceManager to stop listening to the
089     * table. No error is thrown if the table state was not being persisted.
090     *
091     * @param table the table to stop persisting
092     * @throws NullPointerException if the table name is null
093     */
094    void stopPersisting(@Nonnull JTable table) throws NullPointerException;
095
096    /**
097     * Remove the persistent state for a table from the cache. This does not
098     * cause the JTablePersistanceManager to stop persisting the table.
099     *
100     * @param table the table to clear
101     * @throws NullPointerException if the table name is null
102     */
103    void clearState(@Nonnull JTable table) throws NullPointerException;
104
105    /**
106     * Add the current state for a table to the cache. This does not cause the
107     * JTablePersistanceManager to start persisting the table.
108     *
109     * @param table the table to cache
110     * @throws NullPointerException if the table name is null
111     */
112    void cacheState(@Nonnull JTable table) throws NullPointerException;
113
114    /**
115     * Reset the table state to the cached state. This does not cause the
116     * JTablePersistanceManager to start persisting the table.
117     *
118     * @param table the table to reset
119     * @throws NullPointerException if the table name is null
120     */
121    void resetState(@Nonnull JTable table) throws NullPointerException;
122
123    /**
124     * Pause saving persistence data to storage. If setting paused to false,
125     * pending persistence data is written immediately.
126     *
127     * @param paused true if saving persistence data should be paused; false
128     *               otherwise.
129     */
130    void setPaused(boolean paused);
131
132    /**
133     * Determine if saving persistence data is paused.
134     *
135     * @return true if saving persistence data is paused; false otherwise.
136     */
137    boolean isPaused();
138
139    /**
140     * Determine if a table is being persisted.
141     *
142     * @param table the table to check against
143     * @return true if the table is being persisted; false otherwise
144     */
145    boolean isPersisting(@Nonnull JTable table);
146
147    /**
148     * Determine if a table is being persisted by name.
149     *
150     * @param name the name of the table to check against
151     * @return true if the table is being persisted; false otherwise
152     */
153    boolean isPersisting(@Nonnull String name);
154
155    /**
156     * Determine if persistence data is being held for a table.
157     *
158     * @param table the table to check against
159     * @return true if the table has persistence data; false otherwise
160     */
161    boolean isPersistenceDataRetained(@Nonnull JTable table);
162
163    /**
164     * Determine if persistence data is being held for a table.
165     *
166     * @param name the name of the table to check against
167     * @return true if the table has persistence data; false otherwise
168     */
169    boolean isPersistenceDataRetained(@Nonnull String name);
170}