/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Copyright 2013 The ZAP Development Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.zaproxy.zap.view; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import javax.swing.Action; import javax.swing.Icon; import javax.swing.JToggleButton; /** * A {@code JToggleButton} that allows to set tool tip texts that are shown only when the toggle button is selected, disabled * and when both disabled and selected. * * @see JToggleButton * @see #setSelectedToolTipText(String) * @see #setDisabledToolTipText(String) * @see #setDisabledSelectedToolTipText(String) */ public class ZapToggleButton extends JToggleButton { private static final long serialVersionUID = 1L; /** * If non-{@code null} the tool tip text shown when the toggle button is in normal state or in any other state if there's no * custom tool tip text set (either {@code selectedToolTipText}, {@code disabledToolTipText} and/or * {@code disabledSelectedToolTipText}). * * @see #selectedToolTipText * @see #disabledToolTipText * @see #disabledSelectedToolTipText * @see #setToolTipText(String) */ private String defaultToolTipText; /** * If non-{@code null} the tool tip text shown when the toggle button is selected (but not disabled). * * @see #defaultToolTipText * @see #disabledToolTipText * @see #disabledSelectedToolTipText * @see #toolTipTextUpdaterOnSelectionStateChange * @see #setSelectedToolTipText(String) */ private String selectedToolTipText; /** * If non-{@code null} the tool tip text shown when the toggle button is disabled. * * @see #defaultToolTipText * @see #disabledToolTipText * @see #disabledSelectedToolTipText * @see #setDisabledToolTipText(String) */ private String disabledToolTipText; /** * If non-{@code null} the tool tip text shown when the toggle button is disabled and selected. * * @see #defaultToolTipText * @see #selectedToolTipText * @see #disabledToolTipText * @see #toolTipTextUpdaterOnSelectionStateChange * @see #setDisabledSelectedToolTipText(String) */ private String disabledSelectedToolTipText; /** * The {@code ItemListener} used to update the tool tip text when the selection state of the toggle button changes. * <p> * Might be {@code null} if there's no tool tip text set for selected state, either {@code selectedToolTipText} or * {@code disabledSelectedToolTipText}. * </p> * * @see #selectedToolTipText * @see #disabledSelectedToolTipText * @see #addRemoveToolTipTextUpdaterOnSelectionStateChangeAsNeeded() */ private ToolTipTextUpdaterOnSelectionStateChange toolTipTextUpdaterOnSelectionStateChange; // NOTE: All ZapToggleButton constructors JavaDoc has been copied from the corresponding JToggleButton constructor. /** * Creates an initially unselected toggle button without setting the text or image. */ public ZapToggleButton() { super(null, null, false); } /** * Creates an initially unselected toggle button with the specified image but no text. * * @param icon the image that the button should display */ public ZapToggleButton(Icon icon) { super(null, icon, false); } /** * Creates a toggle button with the specified image and selection state, but no text. * * @param icon the image that the button should display * @param selected if true, the button is initially selected; otherwise, the button is initially unselected */ public ZapToggleButton(Icon icon, boolean selected) { super(null, icon, selected); } /** * Creates an unselected toggle button with the specified text. * * @param text the string displayed on the toggle button */ public ZapToggleButton(String text) { super(text, null, false); } /** * Creates a toggle button with the specified text and selection state. * * @param text the string displayed on the toggle button * @param selected if true, the button is initially selected; otherwise, the button is initially unselected */ public ZapToggleButton(String text, boolean selected) { super(text, null, selected); } /** * Creates a toggle button where properties are taken from the Action supplied. * * @param action the action with the properties */ public ZapToggleButton(Action action) { super(action); } /** * Creates a toggle button that has the specified text and image, and that is initially unselected. * * @param text the string displayed on the button * @param icon the image that the button should display */ public ZapToggleButton(String text, Icon icon) { super(text, icon, false); } /** * Creates a toggle button with the specified text, image, and selection state. * * @param text the text of the toggle button * @param icon the image that the button should display * @param selected if true, the button is initially selected; otherwise, the button is initially unselected */ public ZapToggleButton(String text, Icon icon, boolean selected) { super(text, icon, selected); } @Override public void setEnabled(boolean b) { super.setEnabled(b); updateCurrentToolTipText(); } /** * Updates the current tool tip text based on the toggle button's state. * <table> * <caption>The tool tip that will be set based on button's state</caption> * <tr> * <td>State</td> * <td>Tool tip text set</td> * </tr> * <tr> * <td>Disabled and selected</td> * <td>{@code disabledSelectedToolTipText} if non-{@code null} otherwise {@code defaultToolTipText}</td> * </tr> * <tr> * <td>Disabled</td> * <td>{@code disabledToolTipText} if non-{@code null} otherwise {@code defaultToolTipText}</td> * </tr> * <tr> * <td>Selected (but not disabled)</td> * <td>{@code selectedToolTipText} if non-{@code null} otherwise {@code defaultToolTipText}</td> * </tr> * <tr> * <td>Other states</td> * <td>{@code defaultToolTipText}</td> * </tr> * </table> * * @see #defaultToolTipText * @see #selectedToolTipText * @see #disabledToolTipText * @see #disabledSelectedToolTipText */ private void updateCurrentToolTipText() { String toolTipText; final boolean disabled = !isEnabled(); final boolean selected = isSelected(); if (disabled && selected && disabledSelectedToolTipText != null) { toolTipText = disabledSelectedToolTipText; } else if (disabled && disabledToolTipText != null) { toolTipText = disabledToolTipText; } else if (selected && selectedToolTipText != null) { toolTipText = selectedToolTipText; } else { toolTipText = defaultToolTipText; } super.setToolTipText(toolTipText); } /** * Sets the default tool tip text, shown when the toggle button is in normal state or in any other state if there's no * custom tool tip text set. If the given {@code text} is {@code null} no tool tip text is shown in normal state. * * @param text the tool tip text that will be shown when the toggle button is in normal state or {@code null} if no tool tip * text should be shown in normal state * @see #getToolTipText() * @see #setSelectedToolTipText(String) * @see #setDisabledToolTipText(String) * @see #setDisabledSelectedToolTipText(String) */ @Override public void setToolTipText(String text) { defaultToolTipText = text; updateCurrentToolTipText(); } /** * Returns the current tool tip text set, might be {@code null}. * <p> * <strong>Note:</strong> This is not the getter method for the default tool tip text, set using the method * {@code setToolTipText(String)} use {@code getDefaultToolTipText()} instead. * </p> * * @see #setToolTipText(String) * @see #getDefaultToolTipText() */ @Override public String getToolTipText() { return super.getToolTipText(); } /** * Returns the tool tip text that's shown when the toggle button is in normal state or in any other state if there's no * custom tool tip text set. Might be {@code null} if no tool tip text was set. * * @return the "default" tool tip text or {@code null} if not set * @see #setToolTipText(String) */ public String getDefaultToolTipText() { return defaultToolTipText; } /** * Sets the tool tip text that will be shown when the toggle button is selected (but not disabled). If the given * {@code text} is {@code null} the default tool tip text is shown instead, if set. * * @param text the tool tip text that will be shown when the toggle button is selected or {@code null} to show the default * tool tip text, if set * @see #getSelectedToolTipText() * @see #setToolTipText(String) * @see #setDisabledToolTipText(String) * @see #setDisabledSelectedToolTipText(String) */ public void setSelectedToolTipText(String text) { selectedToolTipText = text; addRemoveToolTipTextUpdaterOnSelectionStateChangeAsNeeded(); updateCurrentToolTipText(); } /** * Helper method that takes care to instantiate and add (as an ItemListener) the instance variable * {@code toolTipTextUpdaterOnSelectionStateChange} when a tool tip text that depends on the selection state (either * selectedToolTipText or disabledSelectedToolTipText) is not {@code null} or set to null and remove (as an ItemListener) if * it is. * * @see #toolTipTextUpdaterOnSelectionStateChange * @see #selectedToolTipText * @see #disabledSelectedToolTipText * @see #addItemListener(ItemListener) * @see #removeItemListener(ItemListener) */ private void addRemoveToolTipTextUpdaterOnSelectionStateChangeAsNeeded() { if (selectedToolTipText == null && disabledSelectedToolTipText == null) { if (toolTipTextUpdaterOnSelectionStateChange != null) { removeItemListener(toolTipTextUpdaterOnSelectionStateChange); toolTipTextUpdaterOnSelectionStateChange = null; } } else if (toolTipTextUpdaterOnSelectionStateChange == null) { toolTipTextUpdaterOnSelectionStateChange = new ToolTipTextUpdaterOnSelectionStateChange(); addItemListener(toolTipTextUpdaterOnSelectionStateChange); } } /** * Returns the tool tip text that's shown, if non-{@code null}, when the toggle button is selected. * * @return the "selected" tool tip text or {@code null} if not set * @see #setDisabledSelectedToolTipText(String) */ public String getSelectedToolTipText() { return selectedToolTipText; } /** * Sets the tool tip text that will be shown when the toggle button is disabled. If the given {@code text} is {@code null} * the default tool tip text is shown instead, if set. * * @param text the tool tip text that will be shown when the toggle button is disabled or {@code null} to show the default * tool tip text, if set * @see #getDisabledToolTipText() * @see #setToolTipText(String) * @see #setSelectedToolTipText(String) * @see #setDisabledSelectedToolTipText(String) */ public void setDisabledToolTipText(String text) { disabledToolTipText = text; updateCurrentToolTipText(); } /** * Returns the tool tip text that's shown, if non-{@code null}, when the toggle button is disabled. * * @return the "disabled" tool tip text or {@code null} if not set * @see #setDisabledToolTipText(String) */ public String getDisabledToolTipText() { return disabledToolTipText; } /** * Sets the tool tip text that will be shown when the toggle button is disabled and selected. If the given {@code text} is * {@code null} the default tool tip text is shown instead, if set. * * @param text the tool tip text that will be shown when the toggle button is disabled and selected or {@code null} to show * the default tool tip text, if set * @see #getDisabledSelectedToolTipText() * @see #setToolTipText(String) * @see #setSelectedToolTipText(String) * @see #setDisabledToolTipText(String) */ public void setDisabledSelectedToolTipText(String text) { disabledSelectedToolTipText = text; addRemoveToolTipTextUpdaterOnSelectionStateChangeAsNeeded(); updateCurrentToolTipText(); } /** * Returns the tool tip text that's shown, if non-{@code null}, when the toggle button is disabled and selected. * * @return the "disabled selected" tool tip text or {@code null} if not set * @see #setDisabledSelectedToolTipText(String) */ public String getDisabledSelectedToolTipText() { return disabledSelectedToolTipText; } /** * An {@code ItemListener} that updates the tool tip text of a {@code ZapToggleButton} instance on selection state changes * by calling the method {@code ZapToggleButton#updateCurrentToolTipText()}. * <p> * <strong>Note:</strong> It's used an {@code ItemListener} instead of overriding the method * {@code AbstractButton#setSelected(boolean)} because the selection state of the toggle button can be changed using its * {@code ButtonModel} in which case the method {@code AbstractButton#setSelected(boolean)} is not called, as opposed to the * enabled state which the method {@code AbstractButton#setEnabled(boolean)} is called and overridden. For more details see * the implementation of {@code AbstractButton}'s inner class {@code Handler}. * </p> * * @see ItemListener * @see ZapToggleButton#updateCurrentToolTipText() * @see javax.swing.AbstractButton#setSelected(boolean) * @see javax.swing.AbstractButton#getModel() * @see javax.swing.AbstractButton#setEnabled(boolean) */ private class ToolTipTextUpdaterOnSelectionStateChange implements ItemListener { @Override public void itemStateChanged(ItemEvent evt) { if (ItemEvent.ITEM_STATE_CHANGED == evt.getID()) { updateCurrentToolTipText(); } } } }