/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy 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 for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.imagej; import icy.gui.util.LookAndFeelUtil; import icy.gui.util.LookAndFeelUtil.WeakSkinChangeListener; import icy.system.IcyExceptionHandler; import icy.system.SystemUtil; import icy.util.ColorUtil; import icy.util.ReflectionUtil; import ij.IJ; import ij.gui.Toolbar; import ij.plugin.MacroInstaller; import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.awt.MenuComponent; import java.awt.PopupMenu; import java.lang.reflect.Field; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.JToolBar; import javax.swing.SwingConstants; import org.pushingpixels.substance.api.skin.SkinChangeListener; /** * ImageJ ToolBar Wrapper class. * * @author Stephane */ public class ToolbarWrapper extends Toolbar { private class CustomToolBar extends JToolBar { /** * */ private static final long serialVersionUID = -3278693015639517146L; /** * @param orientation */ public CustomToolBar(int orientation) { super(orientation); setBorder(BorderFactory.createEmptyBorder()); setFloatable(false); } @Override protected void paintComponent(Graphics g) { ToolbarWrapper.this.paint(g); // try // { // if (drawButtonsMethod != null) // drawButtonsMethod.invoke(ToolbarWrapper.this, g); // } // catch (Exception e) // { // IcyExceptionHandler.showErrorMessage(e, false); // System.err.println("Cannot redraw toolbar buttons from ImageJ."); // } } @Override public void removeNotify() { try { // TODO: remove this temporary hack when the "window dispose" bug will be fixed // on the OpenJDK / Sun JVM if (SystemUtil.isUnix()) { @SuppressWarnings("rawtypes") Vector pp = (Vector) ReflectionUtil.getFieldObject(this, "popups", true); pp.clear(); } } catch (Exception e) { IcyExceptionHandler.showErrorMessage(e, false); System.err.println("Cannot remove toolbar buttons from ImageJ."); } super.removeNotify(); } } /** * */ private static final long serialVersionUID = 6546185720732862969L; final CustomToolBar swingComponent; private final SkinChangeListener skinChangeListener; /** * leaked methods and fields */ // Method drawButtonsMethod; Field grayField; Field brighterField; Field darkerField; Field evenDarkerField; Field toolColorField; // private Color gray = ImageJ.backgroundColor; // private Color brighter = gray.brighter(); // private Color darker = new Color(175, 175, 175); // private Color evenDarker = new Color(110, 110, 110); public ToolbarWrapper(ImageJWrapper ijw) { super(); swingComponent = new CustomToolBar(SwingConstants.HORIZONTAL); swingComponent.setMinimumSize(getMinimumSize()); swingComponent.setPreferredSize(getPreferredSize()); swingComponent.addKeyListener(ijw); swingComponent.addMouseListener(this); swingComponent.addMouseMotionListener(this); try { @SuppressWarnings("rawtypes") final Vector popups = (Vector) ((Vector) ReflectionUtil.getFieldObject(this, "popups", true)).clone(); // transfer all popup from original toolbar to the swing toolbar for (Object obj : popups) { final PopupMenu popup = (PopupMenu) obj; super.remove(popup); swingComponent.add(popup); } // get access to private methods // drawButtonsMethod = ReflectionUtil.getMethod(this.getClass(), "drawButtons", true, // Graphics.class); // get access to private fields grayField = ReflectionUtil.getField(this.getClass(), "gray", true); brighterField = ReflectionUtil.getField(this.getClass(), "brighter", true); darkerField = ReflectionUtil.getField(this.getClass(), "darker", true); evenDarkerField = ReflectionUtil.getField(this.getClass(), "evenDarker", true); toolColorField = ReflectionUtil.getField(this.getClass(), "toolColor", true); } catch (Exception e) { IcyExceptionHandler.showErrorMessage(e, false); System.err.println("Cannot restore toolbar buttons from ImageJ."); } skinChangeListener = new SkinChangeListener() { @Override public void skinChanged() { Color bgCol = LookAndFeelUtil.getBackground(swingComponent); Color brighterCol; Color darkerCol; Color evenDarkerCol; if (ColorUtil.getLuminance(bgCol) < 64) bgCol = ColorUtil.mix(bgCol, Color.gray); brighterCol = ColorUtil.mix(bgCol, Color.white); darkerCol = ColorUtil.mix(bgCol, Color.black); evenDarkerCol = ColorUtil.mix(darkerCol, Color.black); if (ColorUtil.getLuminance(bgCol) < 128) brighterCol = ColorUtil.mix(bgCol, brighterCol); else { darkerCol = ColorUtil.mix(bgCol, darkerCol); evenDarkerCol = ColorUtil.mix(darkerCol, evenDarkerCol); } try { if (grayField != null) grayField.set(ToolbarWrapper.this, bgCol); if (brighterField != null) brighterField.set(ToolbarWrapper.this, brighterCol); if (darkerField != null) darkerField.set(ToolbarWrapper.this, darkerCol); if (evenDarkerField != null) evenDarkerField.set(ToolbarWrapper.this, evenDarkerCol); if (toolColorField != null) toolColorField.set(ToolbarWrapper.this, LookAndFeelUtil.getForeground(swingComponent)); swingComponent.repaint(); } catch (Exception e) { IcyExceptionHandler.showErrorMessage(e, false); System.err.println("Cannot hack background color of ImageJ toolbar."); } } }; // install default tools and macros new MacroInstaller().run(IJ.getDirectory("macros") + "StartupMacros.txt"); LookAndFeelUtil.addSkinChangeListener(new WeakSkinChangeListener(skinChangeListener)); } @Override public Container getParent() { return swingComponent.getParent(); } /** * @return the swingComponent */ public JToolBar getSwingComponent() { return swingComponent; } @Override public synchronized void add(PopupMenu popup) { if (swingComponent == null) super.add(popup); else { swingComponent.add(popup); swingComponent.repaint(); } } @Override public synchronized void remove(MenuComponent popup) { if (swingComponent == null) super.remove(popup); else { swingComponent.remove(popup); swingComponent.repaint(); } } // @Override // public void itemStateChanged(ItemEvent e) // { // super.itemStateChanged(e); // // swingComponent.repaint(); // } // // @Override // public void paint(Graphics g) // { // swingComponent.repaint(); // } @Override public Graphics getGraphics() { return swingComponent.getGraphics(); } // /** // * Rebuild swing toolbar component // */ // protected void rebuild() // { // swingComponent.removeAll(); // swingComponent.validate(); // } }