001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2009-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.guitools.controlpanel.ui;
028
029import static org.opends.messages.AdminToolMessages.*;
030import static org.opends.server.util.CollectionUtils.*;
031
032import java.awt.Component;
033import java.awt.Dimension;
034import java.awt.GridBagConstraints;
035import java.awt.GridBagLayout;
036import java.awt.Insets;
037import java.awt.event.ActionEvent;
038import java.awt.event.ActionListener;
039import java.util.Collection;
040import java.util.LinkedHashSet;
041
042import javax.swing.Box;
043import javax.swing.JButton;
044import javax.swing.JCheckBox;
045import javax.swing.JPanel;
046import javax.swing.JScrollPane;
047
048import org.opends.guitools.controlpanel.datamodel.MonitoringAttributes;
049import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
050import org.opends.guitools.controlpanel.event.ScrollPaneBorderListener;
051import org.opends.guitools.controlpanel.util.Utilities;
052import org.forgerock.i18n.LocalizableMessage;
053
054/**
055* The panel that allows the user to select which attributes must be displayed
056* in the traffic monitoring tables.
057*
058* @param <T> the type of the objects that this panel manages.  For now it only
059* manages String and MonitoringAttribute objects.
060*/
061public class MonitoringAttributesViewPanel<T> extends StatusGenericPanel
062{
063 private static final long serialVersionUID = 6462932163745559L;
064
065 private LinkedHashSet<T> selectedAttributes = new LinkedHashSet<>();
066 private LinkedHashSet<T> monitoringAttributes;
067 private boolean isCanceled = true;
068
069 /**
070  * Note: the order of the checkboxes and the elements in the Attributes
071  * enumeration will be the same.
072  */
073 private JCheckBox[] checkboxes = {};
074
075 private JButton selectAll;
076 private JButton selectNone;
077
078 /**
079  * Creates an instance of this panel that uses String as attributes.
080  * @param attributes the list of possible attributes.
081  * @return an instance of this panel that uses String as attributes.
082  */
083 public static MonitoringAttributesViewPanel<String> createStringInstance(LinkedHashSet<String> attributes)
084 {
085   return new MonitoringAttributesViewPanel<>(attributes);
086 }
087
088 /**
089  * Creates an instance of this panel that uses MonitoringAttributes as
090  * attributes.
091  * @param attributes the list of possible attributes.
092  * @return an instance of this panel that uses MonitoringAttributes as
093  * attributes.
094  */
095 public static MonitoringAttributesViewPanel<MonitoringAttributes>
096 createMonitoringAttributesInstance(LinkedHashSet<MonitoringAttributes> attributes)
097 {
098   return new MonitoringAttributesViewPanel<>(attributes);
099 }
100
101 /**
102  * Creates an instance of this panel that uses LocalizableMessage as
103  * attributes.
104  * @param attributes the list of possible attributes.
105  * @return an instance of this panel that uses LocalizableMessage as attributes.
106  */
107 public static MonitoringAttributesViewPanel<LocalizableMessage>
108 createMessageInstance(LinkedHashSet<LocalizableMessage> attributes)
109 {
110   return new MonitoringAttributesViewPanel<>(attributes);
111 }
112
113 /** {@inheritDoc} */
114 @Override
115 public boolean requiresScroll()
116 {
117   return false;
118 }
119
120 /**
121  * Default constructor.
122  * @param attributes the attributes that will be proposed to the user.
123  *
124  */
125 protected MonitoringAttributesViewPanel(LinkedHashSet<T> attributes)
126 {
127   monitoringAttributes = new LinkedHashSet<>(attributes);
128   createLayout();
129 }
130
131 /**
132  * Sets the attributes that must be selected in this dialog.
133  * @param selectedAttributes the selected attributes.
134  */
135 public void setSelectedAttributes(
136     Collection<T> selectedAttributes)
137 {
138   int i = 0;
139   for (T attribute : monitoringAttributes)
140   {
141     checkboxes[i].setSelected(selectedAttributes.contains(attribute));
142     i++;
143   }
144 }
145
146 /**
147  * Creates the layout of the panel (but the contents are not populated here).
148  */
149 private void createLayout()
150 {
151   GridBagConstraints gbc = new GridBagConstraints();
152   gbc.fill = GridBagConstraints.HORIZONTAL;
153   gbc.gridy = 0;
154
155   gbc.gridwidth = 2;
156   gbc.gridx = 0;
157   add(Utilities.createPrimaryLabel(INFO_CTRL_PANEL_OPERATION_VIEW_LABEL.get()), gbc);
158   gbc.gridy ++;
159   gbc.gridwidth = 1;
160   gbc.insets.top = 10;
161
162   JPanel checkBoxPanel = new JPanel(new GridBagLayout());
163   checkBoxPanel.setOpaque(false);
164   JScrollPane scroll = Utilities.createBorderLessScrollBar(checkBoxPanel);
165   ScrollPaneBorderListener.createFullBorderListener(scroll);
166
167   checkboxes = new JCheckBox[monitoringAttributes.size()];
168
169   int i = 0;
170   for (T attribute : monitoringAttributes)
171   {
172     LocalizableMessage m = getMessage(attribute);
173     checkboxes[i] = Utilities.createCheckBox(m);
174     i++;
175   }
176   selectAll = Utilities.createButton(INFO_CTRL_PANEL_SELECT_ALL_BUTTON.get());
177   selectAll.addActionListener(new ActionListener()
178   {
179     public void actionPerformed(ActionEvent ev)
180     {
181       for (JCheckBox cb : checkboxes)
182       {
183         cb.setSelected(true);
184       }
185     }
186   });
187
188   selectNone = Utilities.createButton(INFO_CTRL_PANEL_CLEAR_SELECTION_BUTTON.get());
189   selectNone.addActionListener(new ActionListener()
190   {
191     public void actionPerformed(ActionEvent ev)
192     {
193       for (JCheckBox cb : checkboxes)
194       {
195         cb.setSelected(false);
196       }
197     }
198   });
199
200   gbc.weightx = 1.0;
201   gbc.weighty = 1.0;
202   gbc.gridheight = 3;
203   gbc.fill = GridBagConstraints.BOTH;
204   add(scroll, gbc);
205
206   gbc.gridx = 1;
207   gbc.weightx = 0.0;
208   gbc.weighty = 0.0;
209   gbc.insets.left = 10;
210   gbc.gridheight = 1;
211   add(selectAll, gbc);
212   gbc.gridy ++;
213   gbc.insets.top = 10;
214   add(selectNone, gbc);
215   gbc.gridy ++;
216   gbc.weighty = 1.0;
217   add(Box.createVerticalGlue(), gbc);
218
219   gbc = new GridBagConstraints();
220   gbc.gridy = 0;
221   gbc.gridwidth = 1;
222   int preferredViewHeight = -1;
223   for (JCheckBox cb : checkboxes)
224   {
225     gbc.gridx = 0;
226     gbc.weightx = 0.0;
227     gbc.anchor = GridBagConstraints.WEST;
228     gbc.fill = GridBagConstraints.NONE;
229     checkBoxPanel.add(cb, gbc);
230     gbc.gridx = 1;
231     gbc.weightx = 1.0;
232     gbc.fill = GridBagConstraints.HORIZONTAL;
233     checkBoxPanel.add(Box.createHorizontalGlue(), gbc);
234     gbc.insets.top = 10;
235     gbc.gridy ++;
236     if (gbc.gridy == 15)
237     {
238       preferredViewHeight = checkBoxPanel.getPreferredSize().height;
239     }
240   }
241   if (preferredViewHeight < 0)
242   {
243     preferredViewHeight = checkBoxPanel.getPreferredSize().height;
244   }
245   gbc.insets = new Insets(0, 0, 0, 0);
246   gbc.gridx = 0;
247   gbc.gridwidth = 2;
248   gbc.fill = GridBagConstraints.VERTICAL;
249   gbc.weighty = 1.0;
250   checkBoxPanel.add(Box.createVerticalGlue(), gbc);
251   scroll.getViewport().setPreferredSize(
252       new Dimension(checkBoxPanel.getPreferredSize().width + 15, preferredViewHeight));
253 }
254
255 /** {@inheritDoc} */
256 public LocalizableMessage getTitle()
257 {
258   return INFO_CTRL_PANEL_ATTRIBUTE_VIEW_OPTIONS_TITLE.get();
259 }
260
261 /** {@inheritDoc} */
262 public void configurationChanged(ConfigurationChangeEvent ev)
263 {
264 }
265
266 /** {@inheritDoc} */
267 public Component getPreferredFocusComponent()
268 {
269   return checkboxes[0];
270 }
271
272 /** {@inheritDoc} */
273 public void toBeDisplayed(boolean visible)
274 {
275   if (visible)
276   {
277     isCanceled = true;
278   }
279 }
280
281 /** {@inheritDoc} */
282 public void okClicked()
283 {
284   // Check that at least one checkbox is selected.
285   selectedAttributes.clear();
286   int i = 0;
287   for (T attribute : monitoringAttributes)
288   {
289     if (checkboxes[i].isSelected())
290     {
291       selectedAttributes.add(attribute);
292     }
293     i++;
294   }
295   if (selectedAttributes.isEmpty())
296   {
297     super.displayErrorDialog(newArrayList(INFO_CTRL_PANEL_NO_OPERATION_SELECTED.get()));
298   }
299   else
300   {
301     isCanceled = false;
302     super.closeClicked();
303   }
304 }
305
306 /** {@inheritDoc} */
307 public GenericDialog.ButtonType getButtonType()
308 {
309   return GenericDialog.ButtonType.OK_CANCEL;
310 }
311
312 /**
313  * Returns <CODE>true</CODE> if the user closed the dialog by cancelling it
314  * and <CODE>false</CODE> otherwise.
315  * @return <CODE>true</CODE> if the user closed the dialog by cancelling it
316  * and <CODE>false</CODE> otherwise.
317  */
318 public boolean isCanceled()
319 {
320   return isCanceled;
321 }
322
323 /**
324  * Returns the list of attributes that the user selected.
325  * @return the list of attributes that the user selected.
326  */
327 public LinkedHashSet<T> getAttributes()
328 {
329   return selectedAttributes;
330 }
331
332 /**
333  * Returns the message for the provided attribute.
334  * @param attribute the attribute.
335  * @return the message for the provided attribute.
336  */
337 protected LocalizableMessage getMessage(T attribute)
338 {
339   LocalizableMessage m;
340   if (attribute instanceof MonitoringAttributes)
341   {
342     m = ((MonitoringAttributes)attribute).getMessage();
343   }
344   else if (attribute instanceof LocalizableMessage)
345   {
346     m = (LocalizableMessage)attribute;
347   }
348   else
349   {
350     m = LocalizableMessage.raw(attribute.toString());
351   }
352   return m;
353 }
354}