/* * Copyright 2001-2013 Stephen Colebourne * * 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.joda.beans.ui.swing.component; import java.awt.AlphaComposite; import java.awt.Component; import java.awt.Container; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Objects; import javax.swing.JComponent; import javax.swing.JLayer; import javax.swing.JRootPane; import javax.swing.plaf.LayerUI; /** * Utilities for the Swing UI. */ public final class SwingUtils { /** * The error status key. */ private static final String ERROR_STATUS_KEY = "JodaBeans.errorStatus"; /** * Restricted constructor. */ private SwingUtils() { } //------------------------------------------------------------------------- /** * Gets the error status of a component. * * @param component the component to set the status of, not null * @return the status, not null */ public static ErrorStatus getErrorStatus(final JComponent component) { Objects.requireNonNull(component, "component"); Object status = component.getClientProperty(ERROR_STATUS_KEY); return (status instanceof ErrorStatus ? (ErrorStatus) status : ErrorStatus.VALID); } /** * Sets the error status of a component. * * @param component the component to set the status of, not null * @param status the status, not null */ public static void setErrorStatus(final JComponent component, ErrorStatus status) { Objects.requireNonNull(component, "component"); Objects.requireNonNull(status, "status"); component.putClientProperty(ERROR_STATUS_KEY, status); } //------------------------------------------------------------------------- /** * Enables and disables the whole of a frame/dialog. * <p> * This is intended to be used when working with a modal dialog. * It finds the root pane of the component and changes the content pane to * be a {@code JLayer} decorator. Once installed, the layer alters the paining. * * @param componentInWindow a component in the window to be disabled, not null * @param enabled true if enabled, false if disabled */ public static void setWindowEnabled(final JComponent componentInWindow, boolean enabled) { Objects.requireNonNull(componentInWindow, "componentInWindow"); JRootPane root = componentInWindow.getRootPane(); if (root != null) { Container content = root.getContentPane(); if (isDisabledLayer(content)) { content.setEnabled(enabled); return; } for (Component comp : content.getComponents()) { if (isDisabledLayer(comp)) { comp.setEnabled(enabled); return; } } JLayer<Component> layer = new JLayer<Component>(root.getContentPane(), new DisabledLayerUI()); root.setContentPane(layer); root.revalidate(); layer.setEnabled(enabled); } } private static boolean isDisabledLayer(Component comp) { return (comp instanceof JLayer && ((JLayer<?>) comp).getUI() instanceof DisabledLayerUI); } //------------------------------------------------------------------------- /** * Special decorating painter. */ private static class DisabledLayerUI extends LayerUI<Component> { private static final long serialVersionUID = 1L; @Override public void paint(Graphics g, JComponent comp) { // paint normal super.paint(g, comp); // paint disabled if (comp.isEnabled() == false) { Graphics2D g2 = (Graphics2D) g.create(); int w = comp.getWidth(); int h = comp.getHeight(); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.12f)); g2.fillRect(0, 0, w, h); g2.dispose(); } } } }