/* * Copyright to the original author or authors. * * 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.rioproject.ui; import javax.swing.*; import java.awt.*; import java.io.Serializable; /** * A utility that allows glass pane type effects to be applied to portions of * your UI instead of the entire UI. * * <p>This class is part of the rio-api module because it will be downloaded with service ui * classes. If we were to put it into the rio-lib module, the rio-lib module would have to * be declared as part of the codebase (dependencies) of the watch-ui module. */ @SuppressWarnings("PMD") public class GlassPaneContainer extends JPanel { private JComponent glassPane; public GlassPaneContainer() { setLayout(new Layout()); setGlassPane(createGlassPane()); } public GlassPaneContainer(final Component singleComponent) { this(); add(singleComponent); } public void setGlassPane(final JComponent glass) { if (glass == null) { setGlassPane(createGlassPane()); return; } final JComponent old = this.glassPane; final boolean visible; if (this.glassPane != null && this.glassPane.getParent() == this) { this.remove(this.glassPane); visible = this.glassPane.isVisible(); } else { visible = false; } glass.setVisible(visible); this.glassPane = glass; this.add(this.glassPane); firePropertyChange("glassPane", old, glass); if (visible) { repaint(); } } public JComponent getGlassPane() { return glassPane; } public static GlassPaneContainer findGlassPaneContainerFor(Component c) { while (c != null && !(c instanceof GlassPaneContainer)) { c = c.getParent(); } return (GlassPaneContainer) c; } @Override protected void addImpl(Component comp, Object constraints, int index) { if (comp == getGlassPane()) { super.addImpl(comp, constraints, 0); } else { if (index == 0) { index = 1; } super.addImpl(comp, constraints, index); } } @Override public boolean isOptimizedDrawingEnabled() { return !getGlassPane().isVisible() && super.isOptimizedDrawingEnabled(); } protected JPanel createGlassPane() { final JPanel ret = new JPanel(); ret.setName(getName() + ".glassPane"); ret.setVisible(false); ret.setOpaque(false); return ret; } protected class Layout implements LayoutManager2, Serializable { public Dimension maximumLayoutSize(final Container target) { assert target == GlassPaneContainer.this; final int componentCount = getComponentCount(); final JComponent glassPane = getGlassPane(); final Dimension max = new Dimension(); for (int i = 0; i < componentCount; i++) { final Component c = getComponent(i); if (c != glassPane) { final Dimension cMax = c.getMaximumSize(); max.setSize(Math.max(max.width, cMax.width), Math.max(max.height, cMax.height)); } } return max; } public Dimension preferredLayoutSize(final Container target) { assert target == GlassPaneContainer.this; final int componentCount = getComponentCount(); final JComponent glassPane = getGlassPane(); final Dimension pref = new Dimension(); for (int i = 0; i < componentCount; i++) { final Component c = getComponent(i); if (c != glassPane) { final Dimension cPref = c.getPreferredSize(); pref.setSize(Math.max(pref.width, cPref.width), Math.max(pref.height, cPref.height)); } } return pref; } public Dimension minimumLayoutSize(final Container target) { assert target == GlassPaneContainer.this; final int componentCount = getComponentCount(); final JComponent glassPane = getGlassPane(); final Dimension min = new Dimension(); for (int i = 0; i < componentCount; i++) { final Component c = getComponent(i); if (c != glassPane) { final Dimension cMin = c.getMinimumSize(); min.setSize(Math.max(min.width, cMin.width), Math.max(min.height, cMin.height)); } } return min; } public void layoutContainer(final Container target) { assert target == GlassPaneContainer.this; final Rectangle bounds = getBounds(); final Insets insets = getInsets(); final int width = bounds.width - insets.right - insets.left; final int height = bounds.height - insets.bottom - insets.top; final int componentCount = getComponentCount(); for (int i = 0; i < componentCount; i++) { final Component c = getComponent(i); c.setBounds(0, 0, width, height); } } public float getLayoutAlignmentX(Container target) { return 0f; } public float getLayoutAlignmentY(Container target) { return 0f; } public void addLayoutComponent(Component comp, Object constraints) { } public void invalidateLayout(Container target) { } public void addLayoutComponent(String name, Component comp) { } public void removeLayoutComponent(Component comp) { } } }