001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.gui.component;
020
021import icy.gui.component.button.IcyButton;
022import icy.resource.ResourceUtil;
023import icy.resource.icon.IcyIcon;
024
025import java.awt.Color;
026import java.awt.Component;
027import java.awt.event.ActionEvent;
028import java.awt.event.ActionListener;
029import java.util.ArrayList;
030
031import javax.swing.BorderFactory;
032import javax.swing.BoxLayout;
033import javax.swing.Icon;
034import javax.swing.JLabel;
035import javax.swing.JPanel;
036import javax.swing.JTabbedPane;
037import javax.swing.SwingConstants;
038
039/**
040 * Basically a JTabbedPane which can handle ExternalizablePanel.
041 * 
042 * @author Stephane
043 */
044public class ExtTabbedPanel extends JTabbedPane
045{
046    /**
047     * 
048     */
049    private static final long serialVersionUID = -1217212007327960771L;
050
051    private class TabComponent extends JPanel
052    {
053        /**
054         * 
055         */
056        private static final long serialVersionUID = 4841789742300589373L;
057
058        final ExternalizablePanel extPanel;
059        final private IcyButton externButton;
060        final JLabel label;
061
062        /**
063         * needed for data save
064         */
065        final int index;
066        final String tip;
067
068        public TabComponent(String title, Icon icon, ExternalizablePanel panel, String tip, int index)
069        {
070            super();
071
072            setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
073            setBorder(BorderFactory.createEmptyBorder());
074            setOpaque(false);
075
076            this.index = index;
077            this.tip = tip;
078            extPanel = panel;
079
080            label = new JLabel(title + " ", icon, SwingConstants.CENTER);
081            label.setOpaque(false);
082
083            externButton = new IcyButton(new IcyIcon(ResourceUtil.ICON_WINDOW_EXPAND, 16));
084            externButton.setFlat(true);
085            externButton.setOpaque(false);
086            externButton.setContentAreaFilled(false);
087            externButton.setToolTipText("Externalize panel");
088            externButton.addActionListener(new ActionListener()
089            {
090                @Override
091                public void actionPerformed(ActionEvent e)
092                {
093                    // externalize panel
094                    extPanel.externalize();
095                }
096            });
097
098            add(label);
099            add(externButton);
100
101            validate();
102        }
103
104        public String getTitle()
105        {
106            return label.getText().trim();
107        }
108
109        public Icon getIcon()
110        {
111            return label.getIcon();
112        }
113
114        public void setTitle(String title)
115        {
116            label.setText(title + " ");
117        }
118
119        public void setIcon(Icon icon)
120        {
121            label.setIcon(icon);
122        }
123
124        public void setDisabledIcon(Icon disabledIcon)
125        {
126            label.setDisabledIcon(disabledIcon);
127        }
128
129        public void setBackgroundAll(Color background)
130        {
131            externButton.setBackground(background);
132            label.setBackground(background);
133        }
134
135        public void setForegroundAll(Color foreground)
136        {
137            externButton.setForeground(foreground);
138            label.setForeground(foreground);
139        }
140    }
141
142    final private ArrayList<TabComponent> tabComponents;
143
144    public ExtTabbedPanel()
145    {
146        this(TOP, WRAP_TAB_LAYOUT);
147    }
148
149    public ExtTabbedPanel(int tabPlacement)
150    {
151        this(tabPlacement, WRAP_TAB_LAYOUT);
152    }
153
154    public ExtTabbedPanel(int tabPlacement, int tabLayoutPolicy)
155    {
156        super(tabPlacement, tabLayoutPolicy);
157
158        tabComponents = new ArrayList<TabComponent>();
159    }
160
161    /**
162     * Find the ExtTabComponent attached to the specified ExternalizablePanel.
163     */
164    protected TabComponent getTabComponent(ExternalizablePanel panel)
165    {
166        for (TabComponent extTabComp : tabComponents)
167            if (extTabComp.extPanel == panel)
168                return extTabComp;
169
170        return null;
171    }
172
173    @Override
174    public Component add(Component component)
175    {
176        // special case of externalizable panel
177        if (component instanceof ExternalizablePanel)
178        {
179            final TabComponent tabComp = getTabComponent((ExternalizablePanel) component);
180
181            // already existing ?
182            if (tabComp != null)
183            {
184                // use its parameter
185                insertTab(tabComp.getTitle(), tabComp.getIcon(), component, tabComp.tip,
186                        Math.min(tabComp.index, getTabCount()));
187                return component;
188            }
189        }
190
191        return super.add(component);
192    }
193
194    @Override
195    public void setIconAt(int index, Icon icon)
196    {
197        super.setIconAt(index, icon);
198
199        final Component comp = getTabComponentAt(index);
200        if (comp instanceof TabComponent)
201            ((TabComponent) comp).setIcon(icon);
202    }
203
204    @Override
205    public void setDisabledIconAt(int index, Icon disabledIcon)
206    {
207        super.setDisabledIconAt(index, disabledIcon);
208
209        final Component comp = getTabComponentAt(index);
210        if (comp instanceof TabComponent)
211            ((TabComponent) comp).setDisabledIcon(disabledIcon);
212    }
213
214    @Override
215    public void setBackgroundAt(int index, Color background)
216    {
217        super.setBackgroundAt(index, background);
218
219        final Component comp = getTabComponentAt(index);
220        if (comp instanceof TabComponent)
221            ((TabComponent) comp).setBackgroundAll(background);
222    }
223
224    @Override
225    public void setForegroundAt(int index, Color foreground)
226    {
227        super.setForegroundAt(index, foreground);
228
229        final Component comp = getTabComponentAt(index);
230        if (comp instanceof TabComponent)
231            ((TabComponent) comp).setForegroundAll(foreground);
232    }
233
234    @Override
235    public void setTitleAt(int index, String title)
236    {
237        super.setTitleAt(index, title);
238
239        final Component comp = getTabComponentAt(index);
240        if (comp instanceof TabComponent)
241            ((TabComponent) comp).setTitle(title);
242    }
243
244    @Override
245    public void insertTab(String title, Icon icon, Component component, String tip, int index)
246    {
247        TabComponent tabComp;
248
249        if (component instanceof ExternalizablePanel)
250        {
251            final ExternalizablePanel panel = (ExternalizablePanel) component;
252            tabComp = getTabComponent(panel);
253
254            // not existing ?
255            if (tabComp == null)
256            {
257                // create the associated tab component
258                tabComp = new TabComponent(title, icon, panel, tip, index);
259                // and save it in the list to keep a reference
260                tabComponents.add(tabComp);
261            }
262
263            // externalized ?
264            if (panel.isExternalized())
265            {
266                // manually set parent and exit
267                panel.setParent(this);
268                return;
269            }
270        }
271        else
272            tabComp = null;
273
274        super.insertTab(title, icon, component, tip, index);
275
276        // use custom panel for externalizable panel
277        if (tabComp != null)
278            setTabComponentAt(index, tabComp);
279    }
280}