/* * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing.plaf.synth; import javax.swing.*; import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicDesktopPaneUI; import java.beans.*; import java.awt.event.*; import java.awt.*; /** * Provides the Synth L&F UI delegate for * {@link javax.swing.JDesktopPane}. * * @author Joshua Outwater * @author Steve Wilson * @since 1.7 */ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements PropertyChangeListener, SynthUI { private SynthStyle style; private TaskBar taskBar; private DesktopManager oldDesktopManager; /** * Creates a new UI object for the given component. * * @param c component to create UI object for * @return the UI object */ public static ComponentUI createUI(JComponent c) { return new SynthDesktopPaneUI(); } /** * {@inheritDoc} */ @Override protected void installListeners() { super.installListeners(); desktop.addPropertyChangeListener(this); if (taskBar != null) { // Listen for desktop being resized desktop.addComponentListener(taskBar); // Listen for frames being added to desktop desktop.addContainerListener(taskBar); } } /** * {@inheritDoc} */ @Override protected void installDefaults() { updateStyle(desktop); if (UIManager.getBoolean("InternalFrame.useTaskBar")) { taskBar = new TaskBar(); for (Component comp : desktop.getComponents()) { JInternalFrame.JDesktopIcon desktopIcon; if (comp instanceof JInternalFrame.JDesktopIcon) { desktopIcon = (JInternalFrame.JDesktopIcon)comp; } else if (comp instanceof JInternalFrame) { desktopIcon = ((JInternalFrame)comp).getDesktopIcon(); } else { continue; } // Move desktopIcon from desktop to taskBar if (desktopIcon.getParent() == desktop) { desktop.remove(desktopIcon); } if (desktopIcon.getParent() != taskBar) { taskBar.add(desktopIcon); desktopIcon.getInternalFrame().addComponentListener( taskBar); } } taskBar.setBackground(desktop.getBackground()); desktop.add(taskBar, Integer.valueOf(JLayeredPane.PALETTE_LAYER.intValue() + 1)); if (desktop.isShowing()) { taskBar.adjustSize(); } } } private void updateStyle(JDesktopPane c) { SynthStyle oldStyle = style; SynthContext context = getContext(c, ENABLED); style = SynthLookAndFeel.updateStyle(context, this); if (oldStyle != null) { uninstallKeyboardActions(); installKeyboardActions(); } context.dispose(); } /** * {@inheritDoc} */ @Override protected void uninstallListeners() { if (taskBar != null) { desktop.removeComponentListener(taskBar); desktop.removeContainerListener(taskBar); } desktop.removePropertyChangeListener(this); super.uninstallListeners(); } /** * {@inheritDoc} */ @Override protected void uninstallDefaults() { SynthContext context = getContext(desktop, ENABLED); style.uninstallDefaults(context); context.dispose(); style = null; if (taskBar != null) { for (Component comp : taskBar.getComponents()) { JInternalFrame.JDesktopIcon desktopIcon = (JInternalFrame.JDesktopIcon)comp; taskBar.remove(desktopIcon); desktopIcon.setPreferredSize(null); JInternalFrame f = desktopIcon.getInternalFrame(); if (f.isIcon()) { desktop.add(desktopIcon); } f.removeComponentListener(taskBar); } desktop.remove(taskBar); taskBar = null; } } /** * {@inheritDoc} */ @Override protected void installDesktopManager() { if (UIManager.getBoolean("InternalFrame.useTaskBar")) { desktopManager = oldDesktopManager = desktop.getDesktopManager(); if (!(desktopManager instanceof SynthDesktopManager)) { desktopManager = new SynthDesktopManager(); desktop.setDesktopManager(desktopManager); } } else { super.installDesktopManager(); } } /** * {@inheritDoc} */ @Override protected void uninstallDesktopManager() { if (oldDesktopManager != null && !(oldDesktopManager instanceof UIResource)) { desktopManager = desktop.getDesktopManager(); if (desktopManager == null || desktopManager instanceof UIResource) { desktop.setDesktopManager(oldDesktopManager); } } oldDesktopManager = null; super.uninstallDesktopManager(); } @SuppressWarnings("serial") // Same-version serialization only and // internal anonymous classes static class TaskBar extends JPanel implements ComponentListener, ContainerListener { TaskBar() { setOpaque(true); setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0) { public void layoutContainer(Container target) { // First shrink buttons to fit Component[] comps = target.getComponents(); int n = comps.length; if (n > 0) { // Start with the largest preferred width int prefWidth = 0; for (Component c : comps) { c.setPreferredSize(null); Dimension prefSize = c.getPreferredSize(); if (prefSize.width > prefWidth) { prefWidth = prefSize.width; } } // Shrink equally to fit if needed Insets insets = target.getInsets(); int tw = target.getWidth() - insets.left - insets.right; int w = Math.min(prefWidth, Math.max(10, tw/n)); for (Component c : comps) { Dimension prefSize = c.getPreferredSize(); c.setPreferredSize(new Dimension(w, prefSize.height)); } } super.layoutContainer(target); } }); // PENDING: This should be handled by the painter setBorder(new BevelBorder(BevelBorder.RAISED) { protected void paintRaisedBevel(Component c, Graphics g, int x, int y, int w, int h) { Color oldColor = g.getColor(); g.translate(x, y); g.setColor(getHighlightOuterColor(c)); g.drawLine(0, 0, 0, h-2); g.drawLine(1, 0, w-2, 0); g.setColor(getShadowOuterColor(c)); g.drawLine(0, h-1, w-1, h-1); g.drawLine(w-1, 0, w-1, h-2); g.translate(-x, -y); g.setColor(oldColor); } }); } void adjustSize() { JDesktopPane desktop = (JDesktopPane)getParent(); if (desktop != null) { int height = getPreferredSize().height; Insets insets = getInsets(); if (height == insets.top + insets.bottom) { if (getHeight() <= height) { // Initial size, because we have no buttons yet height += 21; } else { // We already have a good height height = getHeight(); } } setBounds(0, desktop.getHeight() - height, desktop.getWidth(), height); revalidate(); repaint(); } } // ComponentListener interface public void componentResized(ComponentEvent e) { if (e.getSource() instanceof JDesktopPane) { adjustSize(); } } public void componentMoved(ComponentEvent e){} public void componentShown(ComponentEvent e) { if (e.getSource() instanceof JInternalFrame) { adjustSize(); } } public void componentHidden(ComponentEvent e) { if (e.getSource() instanceof JInternalFrame) { ((JInternalFrame)e.getSource()).getDesktopIcon().setVisible(false); revalidate(); } } // ContainerListener interface public void componentAdded(ContainerEvent e) { if (e.getChild() instanceof JInternalFrame) { JDesktopPane desktop = (JDesktopPane)e.getSource(); JInternalFrame f = (JInternalFrame)e.getChild(); JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon(); for (Component comp : getComponents()) { if (comp == desktopIcon) { // We have it already return; } } add(desktopIcon); f.addComponentListener(this); if (getComponentCount() == 1) { adjustSize(); } } } public void componentRemoved(ContainerEvent e) { if (e.getChild() instanceof JInternalFrame) { JInternalFrame f = (JInternalFrame)e.getChild(); if (!f.isIcon()) { // Frame was removed without using setClosed(true) remove(f.getDesktopIcon()); f.removeComponentListener(this); revalidate(); repaint(); } } } } @SuppressWarnings("serial") // Same-version serialization only class SynthDesktopManager extends DefaultDesktopManager implements UIResource { public void maximizeFrame(JInternalFrame f) { if (f.isIcon()) { try { f.setIcon(false); } catch (PropertyVetoException e2) { } } else { f.setNormalBounds(f.getBounds()); Component desktop = f.getParent(); setBoundsForFrame(f, 0, 0, desktop.getWidth(), desktop.getHeight() - taskBar.getHeight()); } try { f.setSelected(true); } catch (PropertyVetoException e2) { } } public void iconifyFrame(JInternalFrame f) { JInternalFrame.JDesktopIcon desktopIcon; Container c = f.getParent(); JDesktopPane d = f.getDesktopPane(); boolean findNext = f.isSelected(); if (c == null) { return; } desktopIcon = f.getDesktopIcon(); if (!f.isMaximum()) { f.setNormalBounds(f.getBounds()); } c.remove(f); c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight()); try { f.setSelected(false); } catch (PropertyVetoException e2) { } // Get topmost of the remaining frames if (findNext) { for (Component comp : c.getComponents()) { if (comp instanceof JInternalFrame) { try { ((JInternalFrame)comp).setSelected(true); } catch (PropertyVetoException e2) { } ((JInternalFrame)comp).moveToFront(); return; } } } } public void deiconifyFrame(JInternalFrame f) { JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon(); Container c = desktopIcon.getParent(); if (c != null) { c = c.getParent(); if (c != null) { c.add(f); if (f.isMaximum()) { int w = c.getWidth(); int h = c.getHeight() - taskBar.getHeight(); if (f.getWidth() != w || f.getHeight() != h) { setBoundsForFrame(f, 0, 0, w, h); } } if (f.isSelected()) { f.moveToFront(); } else { try { f.setSelected(true); } catch (PropertyVetoException e2) { } } } } } protected void removeIconFor(JInternalFrame f) { super.removeIconFor(f); taskBar.validate(); } public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) { super.setBoundsForFrame(f, newX, newY, newWidth, newHeight); if (taskBar != null && newY >= taskBar.getY()) { f.setLocation(f.getX(), taskBar.getY()-f.getInsets().top); } } } /** * {@inheritDoc} */ @Override public SynthContext getContext(JComponent c) { return getContext(c, getComponentState(c)); } private SynthContext getContext(JComponent c, int state) { return SynthContext.getContext(SynthContext.class, c, SynthLookAndFeel.getRegion(c), style, state); } private int getComponentState(JComponent c) { return SynthLookAndFeel.getComponentState(c); } /** * Notifies this UI delegate to repaint the specified component. * This method paints the component background, then calls * the {@link #paint(SynthContext,Graphics)} method. * *

In general, this method does not need to be overridden by subclasses. * All Look and Feel rendering code should reside in the {@code paint} method. * * @param g the {@code Graphics} object used for painting * @param c the component being painted * @see #paint(SynthContext,Graphics) */ @Override public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); SynthLookAndFeel.update(context, g); context.getPainter().paintDesktopPaneBackground(context, g, 0, 0, c.getWidth(), c.getHeight()); paint(context, g); context.dispose(); } /** * Paints the specified component according to the Look and Feel. *

This method is not used by Synth Look and Feel. * Painting is handled by the {@link #paint(SynthContext,Graphics)} method. * * @param g the {@code Graphics} object used for painting * @param c the component being painted * @see #paint(SynthContext,Graphics) */ @Override public void paint(Graphics g, JComponent c) { SynthContext context = getContext(c); paint(context, g); context.dispose(); } /** * Paints the specified component. This implementation does nothing. * * @param context context for the component being painted * @param g the {@code Graphics} object used for painting * @see #update(Graphics,JComponent) */ protected void paint(SynthContext context, Graphics g) { } /** * {@inheritDoc} */ @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { context.getPainter().paintDesktopPaneBorder(context, g, x, y, w, h); } /** * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent evt) { if (SynthLookAndFeel.shouldUpdateStyle(evt)) { updateStyle((JDesktopPane)evt.getSource()); } if (evt.getPropertyName() == "ancestor" && taskBar != null) { taskBar.adjustSize(); } } }