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>
084 createStringInstance(LinkedHashSet<String> attributes)
085 {
086   return new MonitoringAttributesViewPanel<>(attributes);
087 }
088
089 /**
090  * Creates an instance of this panel that uses MonitoringAttributes as
091  * attributes.
092  * @param attributes the list of possible attributes.
093  * @return an instance of this panel that uses MonitoringAttributes as
094  * attributes.
095  */
096 public static MonitoringAttributesViewPanel<MonitoringAttributes>
097 createMonitoringAttributesInstance(
098     LinkedHashSet<MonitoringAttributes> attributes)
099 {
100   return new MonitoringAttributesViewPanel<>(attributes);
101 }
102
103 /**
104  * Creates an instance of this panel that uses LocalizableMessage as
105  * attributes.
106  * @param attributes the list of possible attributes.
107  * @return an instance of this panel that uses LocalizableMessage as attributes.
108  */
109 public static MonitoringAttributesViewPanel<LocalizableMessage>
110 createMessageInstance(LinkedHashSet<LocalizableMessage> attributes)
111 {
112   return new MonitoringAttributesViewPanel<>(attributes);
113 }
114
115 /** {@inheritDoc} */
116 @Override
117 public boolean requiresScroll()
118 {
119   return false;
120 }
121
122 /**
123  * Default constructor.
124  * @param attributes the attributes that will be proposed to the user.
125  *
126  */
127 protected MonitoringAttributesViewPanel(LinkedHashSet<T> attributes)
128 {
129   monitoringAttributes = new LinkedHashSet<>(attributes);
130   createLayout();
131 }
132
133 /**
134  * Sets the attributes that must be selected in this dialog.
135  * @param selectedAttributes the selected attributes.
136  */
137 public void setSelectedAttributes(
138     Collection<T> selectedAttributes)
139 {
140   int i = 0;
141   for (T attribute : monitoringAttributes)
142   {
143     checkboxes[i].setSelected(selectedAttributes.contains(attribute));
144     i++;
145   }
146 }
147
148 /**
149  * Creates the layout of the panel (but the contents are not populated here).
150  */
151 private void createLayout()
152 {
153   GridBagConstraints gbc = new GridBagConstraints();
154   gbc.fill = GridBagConstraints.HORIZONTAL;
155   gbc.gridy = 0;
156
157   gbc.gridwidth = 2;
158   gbc.gridx = 0;
159   add(Utilities.createPrimaryLabel(
160       INFO_CTRL_PANEL_OPERATION_VIEW_LABEL.get()), gbc);
161   gbc.gridy ++;
162   gbc.gridwidth = 1;
163   gbc.insets.top = 10;
164
165   JPanel checkBoxPanel = new JPanel(new GridBagLayout());
166   checkBoxPanel.setOpaque(false);
167   JScrollPane scroll = Utilities.createBorderLessScrollBar(checkBoxPanel);
168   ScrollPaneBorderListener.createFullBorderListener(scroll);
169
170   checkboxes = new JCheckBox[monitoringAttributes.size()];
171
172   int i = 0;
173   for (T attribute : monitoringAttributes)
174   {
175     LocalizableMessage m = getMessage(attribute);
176     checkboxes[i] = Utilities.createCheckBox(m);
177     i++;
178   }
179   selectAll = Utilities.createButton(INFO_CTRL_PANEL_SELECT_ALL_BUTTON.get());
180   selectAll.addActionListener(new ActionListener()
181   {
182     public void actionPerformed(ActionEvent ev)
183     {
184       for (JCheckBox cb : checkboxes)
185       {
186         cb.setSelected(true);
187       }
188     }
189   });
190
191   selectNone = Utilities.createButton(
192       INFO_CTRL_PANEL_CLEAR_SELECTION_BUTTON.get());
193   selectNone.addActionListener(new ActionListener()
194   {
195     public void actionPerformed(ActionEvent ev)
196     {
197       for (JCheckBox cb : checkboxes)
198       {
199         cb.setSelected(false);
200       }
201     }
202   });
203
204   gbc.weightx = 1.0;
205   gbc.weighty = 1.0;
206   gbc.gridheight = 3;
207   gbc.fill = GridBagConstraints.BOTH;
208   add(scroll, gbc);
209
210   gbc.gridx = 1;
211   gbc.weightx = 0.0;
212   gbc.weighty = 0.0;
213   gbc.insets.left = 10;
214   gbc.gridheight = 1;
215   add(selectAll, gbc);
216   gbc.gridy ++;
217   gbc.insets.top = 10;
218   add(selectNone, gbc);
219   gbc.gridy ++;
220   gbc.weighty = 1.0;
221   add(Box.createVerticalGlue(), gbc);
222
223   gbc = new GridBagConstraints();
224   gbc.gridy = 0;
225   gbc.gridwidth = 1;
226   int preferredViewHeight = -1;
227   for (JCheckBox cb : checkboxes)
228   {
229     gbc.gridx = 0;
230     gbc.weightx = 0.0;
231     gbc.anchor = GridBagConstraints.WEST;
232     gbc.fill = GridBagConstraints.NONE;
233     checkBoxPanel.add(cb, gbc);
234     gbc.gridx = 1;
235     gbc.weightx = 1.0;
236     gbc.fill = GridBagConstraints.HORIZONTAL;
237     checkBoxPanel.add(Box.createHorizontalGlue(), gbc);
238     gbc.insets.top = 10;
239     gbc.gridy ++;
240     if (gbc.gridy == 15)
241     {
242       preferredViewHeight = checkBoxPanel.getPreferredSize().height;
243     }
244   }
245   if (preferredViewHeight < 0)
246   {
247     preferredViewHeight = checkBoxPanel.getPreferredSize().height;
248   }
249   gbc.insets = new Insets(0, 0, 0, 0);
250   gbc.gridx = 0;
251   gbc.gridwidth = 2;
252   gbc.fill = GridBagConstraints.VERTICAL;
253   gbc.weighty = 1.0;
254   checkBoxPanel.add(Box.createVerticalGlue(), gbc);
255   scroll.getViewport().setPreferredSize(
256       new Dimension(checkBoxPanel.getPreferredSize().width + 15,
257           preferredViewHeight));
258 }
259
260 /** {@inheritDoc} */
261 public LocalizableMessage getTitle()
262 {
263   return INFO_CTRL_PANEL_ATTRIBUTE_VIEW_OPTIONS_TITLE.get();
264 }
265
266 /** {@inheritDoc} */
267 public void configurationChanged(ConfigurationChangeEvent ev)
268 {
269 }
270
271 /** {@inheritDoc} */
272 public Component getPreferredFocusComponent()
273 {
274   return checkboxes[0];
275 }
276
277 /** {@inheritDoc} */
278 public void toBeDisplayed(boolean visible)
279 {
280   if (visible)
281   {
282     isCanceled = true;
283   }
284 }
285
286 /** {@inheritDoc} */
287 public void okClicked()
288 {
289   // Check that at least one checkbox is selected.
290   selectedAttributes.clear();
291   int i = 0;
292   for (T operation : monitoringAttributes)
293   {
294     if (checkboxes[i].isSelected())
295     {
296       selectedAttributes.add(operation);
297     }
298     i++;
299   }
300   if (selectedAttributes.isEmpty())
301   {
302     super.displayErrorDialog(newArrayList(INFO_CTRL_PANEL_NO_OPERATION_SELECTED.get()));
303   }
304   else
305   {
306     isCanceled = false;
307     super.closeClicked();
308   }
309 }
310
311 /** {@inheritDoc} */
312 public GenericDialog.ButtonType getButtonType()
313 {
314   return GenericDialog.ButtonType.OK_CANCEL;
315 }
316
317 /**
318  * Returns <CODE>true</CODE> if the user closed the dialog by cancelling it
319  * and <CODE>false</CODE> otherwise.
320  * @return <CODE>true</CODE> if the user closed the dialog by cancelling it
321  * and <CODE>false</CODE> otherwise.
322  */
323 public boolean isCanceled()
324 {
325   return isCanceled;
326 }
327
328 /**
329  * Returns the list of attributes that the user selected.
330  * @return the list of attributes that the user selected.
331  */
332 public LinkedHashSet<T> getAttributes()
333 {
334   return selectedAttributes;
335 }
336
337 /**
338  * Returns the message for the provided operation.
339  * @param operation the operation.
340  * @return the message for the provided operation.
341  */
342 protected LocalizableMessage getMessage(T operation)
343 {
344   LocalizableMessage m;
345   if (operation instanceof MonitoringAttributes)
346   {
347     m = ((MonitoringAttributes)operation).getMessage();
348   }
349   else if (operation instanceof LocalizableMessage)
350   {
351     m = (LocalizableMessage)operation;
352   }
353   else
354   {
355     m = LocalizableMessage.raw(operation.toString());
356   }
357   return m;
358 }
359}