001package arcommon.ui.component;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.beans.PropertyChangeListenerProxy;
006
007import javax.swing.JTable;
008import javax.swing.SwingUtilities;
009import javax.swing.event.ChangeEvent;
010import javax.swing.event.ListSelectionEvent;
011import javax.swing.event.TableColumnModelEvent;
012import javax.swing.event.TableColumnModelListener;
013import javax.swing.event.TableModelEvent;
014import javax.swing.event.TableModelListener;
015import javax.swing.table.TableModel;
016
017import arcommon.Util;
018import arcommon.persistens.AbstractSettingWithFrameDialogAndTableSettings;
019import arcommon.persistens.ISettings;
020import arcommon.persistens.MyJTableSettings;
021import arcommon.persistens.SettingsUtil;
022
023/**
024 * A {@link MyJTable} that can save and load column rearrangement.
025 */
026public class MyJTableWithSettings extends MyJTable {
027    
028    private MyJTableSettings tableSettings;
029    private String tableSettingsId;
030    private PropertyChangeListener propertyChangeListener;
031    private TableColumnModelListener tableColumnModelListener;
032    private TableModelListener tableModelListener;
033    private boolean updateInProgress;
034    
035    public MyJTableWithSettings(String ptableSettingsId) {
036        init(ptableSettingsId, null);
037    }
038    
039    public MyJTableWithSettings(String ptableSettingsId, TableModel tableModel) {
040        super(tableModel);
041        init(ptableSettingsId, null);
042    }
043    
044    public MyJTableWithSettings(String ptableSettingsId, TableModel tableModel, MyJTableSettings defaultSettings) {
045        super(tableModel);
046        init(ptableSettingsId, defaultSettings);
047    }
048    
049    public MyJTableWithSettings(String ptableSettingsId, MyJTableSettings defaultSettings) {
050        init(ptableSettingsId, defaultSettings);
051    }
052
053    private void init(String ptableSettingsId, MyJTableSettings defaultSettings) {
054        tableSettingsId = ptableSettingsId;
055        
056        setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
057
058        ISettings psettings = SettingsUtil.load();
059        AbstractSettingWithFrameDialogAndTableSettings abstractSettingWithFrameDialogAndTableSettings = (AbstractSettingWithFrameDialogAndTableSettings)psettings;
060        tableSettings = abstractSettingWithFrameDialogAndTableSettings.getTableSettings(ptableSettingsId, false, defaultSettings);
061    }
062    
063    public void setModel(TableModel pdataModel) {
064        removeAllListeners();
065        
066        super.setModel(pdataModel);
067        
068        if (!SwingUtilities.isEventDispatchThread()) {
069            Util.printMessageWithSourceLine("!SwingUtilities.isEventDispatchThread() => Table settings might not work");
070        }
071        
072        Runnable runnable = new Runnable() {
073            public void run() {
074                removeAllListeners();
075                updateAndAddAllListeners();
076            }
077        };
078        SwingUtilities.invokeLater(runnable);
079    }
080    
081    private void removeAllListeners() {
082        if (getColumnModel() != null) {
083            if (propertyChangeListener != null) {
084                for (int i = 0; i < getColumnModel().getColumnCount(); i++) {
085                    getColumnModel().getColumn(i).removePropertyChangeListener(propertyChangeListener);
086                }
087            }
088            if (tableColumnModelListener != null) {
089                getColumnModel().removeColumnModelListener(tableColumnModelListener);
090            }
091        }
092
093        if (tableModelListener != null) {
094            getModel().removeTableModelListener(tableModelListener);
095        }
096    }
097
098    private void updateAndAddAllListeners() {
099        loadTableSettings();
100
101        if (tableModelListener == null) {
102            tableModelListener = new TableModelListener() {
103                public void tableChanged(TableModelEvent e) {
104                    if (e.getFirstRow() != TableModelEvent.HEADER_ROW || e.getLastRow() != TableModelEvent.HEADER_ROW) {
105                        return ;
106                    }
107                    
108                    updateInProgress = true;
109                    Runnable runnable = new Runnable() {
110                        public void run() {
111                            updateInProgress = false;
112                            loadTableSettings();
113                        }
114                    };
115                    SwingUtilities.invokeLater(runnable);
116                }
117            };
118        }
119        getModel().addTableModelListener(tableModelListener);
120
121        if (propertyChangeListener == null) {
122            propertyChangeListener = new PropertyChangeListenerProxy("preferredWidth", new PropertyChangeListener() {
123                public void propertyChange(PropertyChangeEvent event) {
124                    saveTableSettings();
125                }
126            });
127        }
128        for (int i = 0; i < getColumnModel().getColumnCount(); i++) {
129            getColumnModel().getColumn(i).addPropertyChangeListener(propertyChangeListener);
130        }
131
132        if (tableColumnModelListener == null) {
133            tableColumnModelListener = new TableColumnModelListener() {
134                public void columnMarginChanged(ChangeEvent e) {
135                    saveTableSettings();
136                }
137
138                public void columnSelectionChanged(ListSelectionEvent e) {
139                    ;
140                }
141
142                public void columnAdded(TableColumnModelEvent e) {
143                    saveTableSettings();
144                }
145
146                public void columnMoved(TableColumnModelEvent e) {
147                    saveTableSettings();
148                }
149
150                public void columnRemoved(TableColumnModelEvent e) {
151                    saveTableSettings();
152                }
153            };
154        }
155        getColumnModel().addColumnModelListener(tableColumnModelListener);
156    }
157    
158    private void loadTableSettings() {
159        if (tableSettings == null) {
160            return ;
161        }
162        
163        updateInProgress = true;
164        tableSettings.loadTableSettings(this);
165        updateInProgress = false;
166    }
167
168    private void saveTableSettings() {
169        if (updateInProgress) {
170            return ;
171        }
172        if (tableSettings == null) {
173            ISettings psettings = SettingsUtil.load();
174            AbstractSettingWithFrameDialogAndTableSettings abstractSettingWithFrameDialogAndTableSettings = (AbstractSettingWithFrameDialogAndTableSettings)psettings;
175            tableSettings = abstractSettingWithFrameDialogAndTableSettings.getTableSettings(tableSettingsId, true, null);
176        }
177        tableSettings.saveTableSettings(this);
178    }
179    
180    public void setTableSettings(MyJTableSettings ptableSettings) {
181        tableSettings = ptableSettings;
182    }
183
184    public MyJTableSettings getTableSettings() {
185        return tableSettings;
186    }
187
188    private static final long serialVersionUID = -4304709979649528556L;
189}