001/*
002 * Copyright (c) 2012 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: michalo $'
006 * '$Date: 2018-03-28 13:45:42 +0000 (Wed, 28 Mar 2018) $' 
007 * '$Revision: 34681 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029package org.kepler.gui;
030
031import java.awt.BasicStroke;
032import java.awt.Color;
033import java.awt.Component;
034import java.awt.Dimension;
035import java.awt.FlowLayout;
036import java.awt.Graphics;
037import java.awt.Graphics2D;
038import java.awt.event.ActionEvent;
039import java.awt.event.ActionListener;
040import java.awt.event.MouseAdapter;
041import java.awt.event.MouseEvent;
042import javax.swing.SwingUtilities;
043
044import javax.swing.AbstractButton;
045import javax.swing.BorderFactory;
046import javax.swing.JButton;
047import javax.swing.JLabel;
048import javax.swing.JPanel;
049
050import org.kepler.gui.frame.TabbedKeplerGraphFrame;
051
052import ptolemy.actor.gui.Tableau;
053import ptolemy.kernel.util.NamedObj;
054
055/** A Swing component on the tabs of composite actors.
056 * 
057 * @author Daniel Crawl
058 * @version $Id: TabbedCompositeTabComponent.java 34681 2018-03-28 13:45:42Z michalo $
059 *
060 */
061
062public class TabbedCompositeTabComponent extends JPanel implements ActionListener {
063
064    public TabbedCompositeTabComponent(NamedObj model, Tableau tableau) {
065        
066        super(new FlowLayout(FlowLayout.LEFT, 0, 0));
067        
068        setOpaque(false);
069        
070        _model = model;
071        _modelName = model.getName(model.toplevel());
072        _modelFullName = model.getFullName();
073        _tableau = tableau;
074        
075        // add the name of the model
076        JLabel label = new JLabel() {
077            @Override
078            public String getText() {
079                if( _modelName != null && _modelName.length() < 20 ) { 
080                  return _modelName;
081                } else {
082                  return _modelName.substring(0,4) + "..." + _modelName.substring(_modelName.length()-6,_modelName.length()-1);
083                }
084            }
085        };
086
087        add(label);
088        label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2));
089        
090        if(model.getContainer() != null) {
091            /*
092            // add a button for separating the tab
093            _separateButton = new TabSeparateButton();
094            _separateButton.addActionListener(this);
095            add(_separateButton);
096            */
097            
098            // add a button for closing the model            
099            _closeButton = new TabCloseButton();
100            _closeButton.addActionListener(this);
101            add(_closeButton);
102            
103        }
104        
105        setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
106    }
107    
108    @Override
109    public void actionPerformed(ActionEvent event) {
110        
111        final Object source = event.getSource();
112        if(source == _closeButton) {
113            TabbedKeplerGraphFrame frame = (TabbedKeplerGraphFrame) ModelToFrameManager.getInstance().getFrame(_model);
114            if(frame != null) {
115                frame.removeComposite(_model);
116            }
117        } 
118        /*
119        else if(source == _separateButton) {
120            TabbedKeplerGraphFrame frame = (TabbedKeplerGraphFrame) ModelToFrameManager.getInstance().getFrame(_model);
121            if(frame != null) {
122                frame.removeComposite(_model);
123            }
124            Configuration configuration = (Configuration) Configuration
125                    .configurations().get(0);
126            try {
127                configuration.openModel(_model);
128            } catch (IllegalActionException | NameDuplicationException e) {
129                MessageHandler.error("Error opening sub-workflow in separate window.", e);
130            }
131        }
132        */
133    }
134    
135    public String getModelFullName() {
136        return _modelFullName;
137    }
138    
139    public Tableau getTableau() {
140        return _tableau;
141    }
142    
143    public void refreshName() {
144        _modelName = _model.getName(_model.toplevel());
145        _modelFullName = _model.getFullName();
146        invalidate();
147    }
148    
149    private class TabButton extends JButton {
150
151        public TabButton() {
152            
153            setToolTipText("Close this sub-workflow tab.");
154            setOpaque(false);
155            setPreferredSize(new Dimension(18, 18));
156            setRolloverEnabled(true);
157            setContentAreaFilled(false);
158            setFocusable(false);
159            setBorder(BorderFactory.createEtchedBorder());
160            setBorderPainted(false);
161            
162            addMouseListener(new MouseAdapter() {
163                @Override
164                public void mouseEntered(MouseEvent e) {
165                    Component component = e.getComponent();
166                    if (component instanceof AbstractButton) {
167                        AbstractButton button = (AbstractButton) component;
168                        button.setBorderPainted(true);
169                    }
170                }
171
172                @Override
173                public void mouseExited(MouseEvent e) {
174                    Component component = e.getComponent();
175                    if (component instanceof AbstractButton) {
176                        AbstractButton button = (AbstractButton) component;
177                        button.setBorderPainted(false);
178                    }
179                }
180            });
181        }
182    }
183    
184    private class TabCloseButton extends TabButton {
185        
186        public TabCloseButton() {
187            super();
188            setToolTipText("Close this sub-workflow tab.");
189        }
190
191        /** Draw an X */
192        @Override
193        protected void paintComponent(Graphics g) {
194            super.paintComponent(g);
195            Graphics2D g2 = (Graphics2D) g.create();
196            g2.setStroke(new BasicStroke(2));
197            g2.setColor(Color.BLACK);
198            if (getModel().isRollover()) {
199                g2.setColor(Color.RED);
200            }
201            g2.drawString("X", 4, 14);
202            g2.dispose();
203        }
204    }
205    
206    /*
207    private class TabSeparateButton extends TabButton {
208        
209        public TabSeparateButton() {
210            super();
211            setToolTipText("Separate this sub-workflow tab.");
212        }
213
214        /** Draw a ^ * /
215        @Override
216        protected void paintComponent(Graphics g) {
217            super.paintComponent(g);
218            Graphics2D g2 = (Graphics2D) g.create();
219            g2.setStroke(new BasicStroke(2));
220            g2.setColor(Color.BLACK);
221            if (getModel().isRollover()) {
222                g2.setColor(Color.RED);
223            }
224            g2.drawString("^", 4, 14);
225            g2.dispose();
226        }
227    }
228    */
229
230
231    private String _modelName;
232    private NamedObj _model;
233    private JButton _closeButton;
234    //private JButton _separateButton;
235    private Tableau _tableau;
236    private String _modelFullName;
237
238}