View Javadoc
1   package fr.ifremer.quadrige3.ui.swing.table;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 UI Common
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   *
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   *
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import fr.ifremer.quadrige3.ui.swing.action.ActionFactory;
27  import fr.ifremer.quadrige3.ui.swing.table.renderer.NumberCellRenderer;
28  import org.jdesktop.swingx.renderer.DefaultTableRenderer;
29  import org.jdesktop.swingx.renderer.StringValue;
30  import org.jdesktop.swingx.table.TableColumnExt;
31  
32  import javax.swing.JComponent;
33  import javax.swing.JLabel;
34  import javax.swing.JTable;
35  import javax.swing.SwingUtilities;
36  import javax.swing.table.TableColumn;
37  import java.awt.Component;
38  import java.util.concurrent.ThreadPoolExecutor;
39  
40  import static org.nuiton.i18n.I18n.t;
41  
42  /**
43   * <p>RowNumberColumn class.</p>
44   *
45   * @param <R> type of row UI model
46   * @param <T> type of table UI model
47   * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro>
48   */
49  public class RowNumberColumn<R extends AbstractRowUIModel<?, R>, T extends AbstractTableUIModel<?, R, T>>
50      extends TableColumnExt
51      implements FixedColumn {
52  
53      private static final int DEFAULT_COLUMN_WIDTH = 50;
54  
55      private final SwingTable table;
56  
57      /**
58       * <p>Getter for the field <code>table</code>.</p>
59       *
60       * @return a {@link SwingTable} object.
61       */
62      public SwingTable getTable() {
63          return table;
64      }
65  
66      /**
67       * <p>Constructor for CheckTableColumn.</p>
68       *
69       * @param table a {@link SwingTable} object.
70       */
71      public RowNumberColumn(SwingTable table) {
72          super(table.getColumnCount(), DEFAULT_COLUMN_WIDTH);
73          this.table = table;
74          editable = false;
75          hideable = false;
76          sortable = false;
77          setResizable(false);
78  
79          setHeaderValue(" ");
80  
81          setCellRenderer(new RowNumberRenderer());
82  
83          // identifier
84          setIdentifier(new RowNumberColumnIdentifier<>());
85  
86      }
87  
88      /**
89       * {@inheritDoc}
90       */
91  //    @Override
92  //    @SuppressWarnings("unchecked")
93  //    public ColumnIdentifier<R> getIdentifier() {
94  //        return (ColumnIdentifier<R>) super.getIdentifier();
95  //    }
96  
97      @Override
98      public Integer getFixedPosition() {
99          return 0;
100     }
101 
102     public static final class RowNumberColumnIdentifier<R extends AbstractRowUIModel<?, R>> extends ColumnIdentifier<R> {
103 
104         protected RowNumberColumnIdentifier() {
105             super("internal_rowNumber",
106                 null,
107                 null,
108                 Integer.class,
109                 null,
110                 false);
111         }
112 
113         @Override
114         public Object getValue(R entry) {
115             return null;
116         }
117     }
118 
119     private static class RowNumberRenderer extends NumberCellRenderer {
120 
121         private ThreadPoolExecutor tableAdjustExecutor;
122         private int lastColumnWidth = DEFAULT_COLUMN_WIDTH;
123         private int cumulativeTargetWidth;
124 
125         RowNumberRenderer() {
126             super(new DefaultTableRenderer((StringValue) value -> (value instanceof Integer) ? Integer.toString((Integer) value) : "", JLabel.RIGHT));
127 
128             tableAdjustExecutor = ActionFactory.createSingleThreadExecutor(ActionFactory.ExecutionMode.LATEST);
129         }
130 
131         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
132 
133             Component component = super.getTableCellRendererComponent(table, row + 1, isSelected, hasFocus, row, column);
134             if (table == null || table.getTableHeader() == null)
135                 return component;
136 
137             // set header tooltip text in header
138             table.getTableHeader().setToolTipText(t("quadrige3.table.rowCount", table.getRowCount()));
139 
140             // remove tooltip
141             if (component instanceof JComponent) {
142                 ((JComponent) component).setToolTipText(null);
143             }
144 
145             // fixme calculate component width adjustment
146 //            adjustTable(table, table.getColumnModel().getColumn(column), component.getPreferredSize().width);
147 
148             return component;
149         }
150 
151         private void adjustTable(JTable table, TableColumn column, int targetWidth) {
152 
153             cumulativeTargetWidth = Math.max(cumulativeTargetWidth, Math.max(targetWidth + 5, DEFAULT_COLUMN_WIDTH));
154             if (cumulativeTargetWidth != lastColumnWidth) {
155 
156                 tableAdjustExecutor.execute(() -> {
157                     column.setPreferredWidth(cumulativeTargetWidth);
158                     lastColumnWidth = cumulativeTargetWidth;
159                     cumulativeTargetWidth = 0;
160                     table.setPreferredScrollableViewportSize(table.getPreferredSize());
161                     SwingUtilities.invokeLater(table::repaint);
162                 });
163             }
164 
165         }
166     }
167 
168 }