View Javadoc
1   package fr.ifremer.quadrige2.ui.swing.common.table;
2   
3   /*
4    * #%L
5    * Reef DB :: UI
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2014 - 2015 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.quadrige2.core.config.Quadrige2CoreConfiguration;
27  import fr.ifremer.quadrige2.ui.swing.common.table.action.AdditionalTableAction;
28  import org.apache.commons.lang3.ObjectUtils;
29  import org.jdesktop.swingx.JXTable;
30  import org.jdesktop.swingx.action.AbstractActionExt;
31  import org.jdesktop.swingx.action.ActionContainerFactory;
32  import org.jdesktop.swingx.table.ColumnControlPopup.ActionGrouper;
33  import org.jdesktop.swingx.table.TableColumnExt;
34  
35  import javax.swing.Action;
36  import javax.swing.JMenuItem;
37  import javax.swing.table.TableColumn;
38  import java.awt.Color;
39  import java.awt.event.ActionEvent;
40  import java.awt.event.MouseAdapter;
41  import java.awt.event.MouseEvent;
42  import java.util.ArrayList;
43  import java.util.List;
44  
45  import static org.nuiton.i18n.I18n.t;
46  
47  /**
48   * Override version of ColumnControlButton for a JXTable/JXTreeTable. All non hideable columns are not displayed in the popup
49   *
50   * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro>
51   */
52  public class ColumnControlButton extends org.jdesktop.swingx.table.ColumnControlButton {
53  
54      private Quadrige2CoreConfiguration configuration;
55  
56      /**
57       * <p>Constructor for ColumnControlButton.</p>
58       *
59       * @param table a {@link JXTable} object.
60       */
61      public ColumnControlButton(JXTable table) {
62          super(table);
63  
64          configuration = Quadrige2CoreConfiguration.getInstance();
65  
66          AbstractActionExt showAllColumnAction = new AbstractActionExt(t("quadrige2.table.showAllColumn")) {
67  
68              @Override
69              public void actionPerformed(ActionEvent e) {
70  
71                  for (ColumnVisibilityAction action : getColumnVisibilityActions()) {
72                      action.setSelected(true);
73                  }
74  
75              }
76          };
77  
78          showAllColumnAction.putValue(GroupKeyActionGrouper.GROUP_KEY, 0);
79          table.getActionMap().put(ColumnControlButton.COLUMN_CONTROL_MARKER + "showAllColumn", showAllColumnAction);
80  
81          // Add all other AdditionalTableActions
82          // For now, use only 1 AdditionalTableAction TODO: be able to add multiple AdditionalTableActions
83          Action additionalAction = table.getActionMap().get(AdditionalTableAction.ACTION_NAME);
84          if (additionalAction instanceof AdditionalTableAction) {
85              additionalAction.putValue(GroupKeyActionGrouper.GROUP_KEY, 1);
86              // add the additional action with another key
87              table.getActionMap().put(ColumnControlButton.COLUMN_CONTROL_MARKER + "z_additionalAction", additionalAction);
88          }
89  
90          setActionGrouper(new GroupKeyActionGrouper());
91      }
92  
93      /**
94       * {@inheritDoc}
95       */
96      @Override
97      protected ColumnVisibilityAction createColumnVisibilityAction(TableColumn column) {
98          if (column instanceof TableColumnExt && !((TableColumnExt) column).isHideable()) {
99              return null;
100         }
101         return super.createColumnVisibilityAction(column);
102     }
103 
104     /**
105      * {@inheritDoc}
106      */
107     @Override
108     protected void addVisibilityActionItems() {
109         final List<ColumnVisibilityAction> actions = new ArrayList<>(getColumnVisibilityActions());
110 
111         // Sort actions by name (= column label)
112         actions.sort((o1, o2) -> ObjectUtils.compare(o1.getName(), o2.getName()));
113         getColumnControlPopup().addVisibilityActionItems(actions);
114     }
115 
116     @Override
117     protected org.jdesktop.swingx.table.ColumnControlPopup createColumnControlPopup() {
118         return new ColumnControlPopup();
119     }
120 
121     public static class GroupKeyActionGrouper implements ActionGrouper {
122 
123         //Marker to support custom grouping of additional actions. (Issue #swingx-968)
124         static final String GROUP_KEY = "customActionGroup";
125 
126         @Override
127         public <A extends Action> List<List<A>> group(List<A> actions) {
128             List<List<A>> result = new ArrayList<>();
129             List<Object> keys = new ArrayList<>();
130             List<A> noKey = new ArrayList<>();
131             for (A action : actions) {
132                 Object groupKey = action.getValue(GROUP_KEY);
133                 if (groupKey != null) {
134                     int index = keys.indexOf(groupKey);
135                     if (index < 0) {
136                         keys.add(groupKey);
137                         index = keys.size() - 1;
138                         result.add(new ArrayList<>());
139                     }
140                     result.get(index).add(action);
141                 } else {
142                     noKey.add(action);
143                 }
144 
145             }
146             result.add(0, noKey);
147             return result;
148         }
149     }
150 
151     class ColumnControlPopup extends DefaultColumnControlPopup {
152 
153         @Override
154         protected void addItems(List<? extends Action> actions) {
155             ActionContainerFactory factory = new ActionContainerFactory(null);
156             for (Action action : actions) {
157 
158                 JMenuItem menuItem = factory.createMenuItem(action);
159 
160                 // fix text foreground
161                 // TODO use computeForeground with the color of selected element in configuration
162                 menuItem.addMouseListener(new MouseAdapter() {
163                     @Override
164                     public void mouseEntered(MouseEvent e) {
165                         if (menuItem.isEnabled()) menuItem.setForeground(Color.WHITE);
166                     }
167 
168                     @Override
169                     public void mouseExited(MouseEvent e) {
170                         if (menuItem.isEnabled()) menuItem.setForeground(Color.BLACK);
171                     }
172 
173                     @Override
174                     public void mouseClicked(MouseEvent e) {
175                         menuItem.setForeground(Color.BLACK);
176                     }
177                 });
178                 addItem(menuItem);
179             }
180         }
181     }
182 }