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.util;
020
021import icy.gui.frame.IcyFrame;
022import icy.gui.frame.IcyFrameAdapter;
023import icy.gui.frame.IcyFrameEvent;
024import icy.gui.frame.TitledFrame;
025import icy.util.GraphicsUtil;
026
027import java.awt.BorderLayout;
028import java.awt.Component;
029import java.awt.Container;
030import java.awt.Cursor;
031import java.awt.Dialog;
032import java.awt.Dimension;
033import java.awt.Font;
034import java.awt.Frame;
035import java.awt.Graphics;
036import java.awt.GridLayout;
037import java.awt.Image;
038import java.awt.Window;
039import java.awt.event.WindowAdapter;
040import java.awt.event.WindowEvent;
041import java.awt.event.WindowListener;
042import java.awt.geom.Rectangle2D;
043
044import javax.swing.BorderFactory;
045import javax.swing.Box;
046import javax.swing.BoxLayout;
047import javax.swing.JDialog;
048import javax.swing.JFrame;
049import javax.swing.JLabel;
050import javax.swing.JMenuBar;
051import javax.swing.JPanel;
052import javax.swing.JScrollPane;
053import javax.swing.JTextArea;
054import javax.swing.SwingConstants;
055import javax.swing.border.TitledBorder;
056
057/**
058 * This class is a toolbox with many simple GUI routines.
059 * 
060 * @author Fabrice & Stephane
061 */
062public class GuiUtil
063{
064    public static JPanel createLoweredPanel(Component comp)
065    {
066        final JPanel result = new JPanel();
067
068        result.setBorder(BorderFactory.createLoweredBevelBorder());
069        if (comp != null)
070        {
071            result.setLayout(new BorderLayout());
072            result.add(comp, BorderLayout.CENTER);
073        }
074        result.validate();
075
076        return result;
077    }
078
079    public static JPanel createRaisedPanel(Component comp)
080    {
081        final JPanel result = new JPanel();
082
083        result.setBorder(BorderFactory.createRaisedBevelBorder());
084        if (comp != null)
085        {
086            result.setLayout(new BorderLayout());
087            result.add(comp, BorderLayout.CENTER);
088        }
089        result.validate();
090
091        return result;
092    }
093
094    public static JLabel createBoldLabel(String text)
095    {
096        final JLabel label = new JLabel(text);
097
098        ComponentUtil.setFontBold(label);
099
100        return label;
101    }
102
103    public static JLabel createBigBoldLabel(String text, int incSize)
104    {
105        final JLabel label = createBoldLabel(text);
106
107        ComponentUtil.increaseFontSize(label, incSize);
108
109        return label;
110    }
111
112    public static JPanel createCenteredLabel(String text)
113    {
114        return createCenteredLabel(new JLabel(text));
115    }
116
117    public static JPanel createCenteredLabel(JLabel label)
118    {
119        return createLineBoxPanel(Box.createHorizontalGlue(), label, Box.createHorizontalGlue());
120    }
121
122    public static JPanel createCenteredBoldLabel(String text)
123    {
124        return createCenteredLabel(createBoldLabel(text));
125    }
126
127    public static JLabel createFixedWidthLabel(String text, int w)
128    {
129        final JLabel result = new JLabel(text);
130
131        ComponentUtil.setFixedWidth(result, w);
132
133        return result;
134    }
135
136    public static JLabel createFixedWidthBoldLabel(String text, int w)
137    {
138        final JLabel result = createBoldLabel(text);
139
140        ComponentUtil.setFixedWidth(result, w);
141
142        return result;
143    }
144
145    public static JLabel createFixedWidthRightAlignedLabel(String text, int w)
146    {
147        final JLabel result = new JLabel(text);
148
149        ComponentUtil.setFixedWidth(result, w);
150        result.setHorizontalAlignment(SwingConstants.RIGHT);
151
152        return result;
153    }
154
155    public static JPanel createTabLabel(String text, int width)
156    {
157        return createTabLabel(new JLabel(text), width);
158    }
159
160    public static JPanel createTabLabel(JLabel label, int width)
161    {
162        label.setVerticalTextPosition(SwingConstants.TOP);
163        label.setHorizontalTextPosition(SwingConstants.LEADING);
164
165        final JPanel panel = new JPanel();
166
167        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
168        if (width > 0)
169            panel.add(Box.createHorizontalStrut(width));
170        panel.add(label);
171        panel.add(Box.createHorizontalGlue());
172        panel.validate();
173
174        return panel;
175    }
176
177    public static JPanel createTabBoldLabel(String text, int width)
178    {
179        return createTabLabel(createBoldLabel(text), width);
180    }
181
182    public static JPanel createTabArea(String text, int width)
183    {
184        return createTabArea(new JTextArea(text), width);
185    }
186
187    public static JPanel createTabArea(JTextArea area, int width)
188    {
189        area.setEditable(false);
190        area.setOpaque(false);
191        area.setLineWrap(true);
192
193        final JPanel panel = new JPanel();
194
195        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
196        if (width > 0)
197            panel.add(Box.createHorizontalStrut(width));
198        panel.add(area);
199        panel.validate();
200
201        return panel;
202    }
203
204    public static JPanel createTabArea(String text, int width, int height)
205    {
206        return createTabArea(new JTextArea(text), width, height);
207    }
208
209    public static JPanel createTabArea(JTextArea area, int width, int height)
210    {
211        area.setEditable(false);
212        area.setOpaque(false);
213        area.setLineWrap(true);
214        area.setWrapStyleWord(true);
215
216        final JScrollPane scrollArea = new JScrollPane(area);
217        scrollArea.setPreferredSize(new Dimension(320, height));
218        scrollArea.setBorder(null);
219
220        final JPanel panel = new JPanel();
221
222        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
223        if (width > 0)
224            panel.add(Box.createHorizontalStrut(width));
225        panel.add(scrollArea);
226        panel.validate();
227
228        return panel;
229    }
230
231    public static JPanel createLineBoxPanel(Component... componentArray)
232    {
233        final JPanel result = new JPanel();
234
235        result.setLayout(new BoxLayout(result, BoxLayout.LINE_AXIS));
236        for (Component c : componentArray)
237            result.add(c);
238        result.validate();
239
240        return result;
241    }
242
243    public static JPanel createPageBoxPanel(Component... componentArray)
244    {
245        final JPanel result = new JPanel();
246
247        result.setLayout(new BoxLayout(result, BoxLayout.PAGE_AXIS));
248        for (Component c : componentArray)
249            result.add(c);
250        result.validate();
251
252        return result;
253    }
254
255    /**
256     * Creates a jpanel with a gridlayout of 1,2 with the given arguments, and
257     * force the width of the secon columns. Should be use for list of label
258     * beside parameters
259     */
260    public static JPanel besidesPanel(Component jc1, Component jc2, int widthOfSecondComponent)
261    {
262        JPanel panel = new JPanel();
263
264        panel.setLayout(new BorderLayout());
265        panel.add(jc1, BorderLayout.CENTER);
266        panel.add(jc2, BorderLayout.EAST);
267        jc2.setPreferredSize(new Dimension(widthOfSecondComponent, jc2.getPreferredSize().height));
268        panel.validate();
269
270        return panel;
271    }
272
273    /**
274     * Creates a jpanel with a gridlayout of 1,2 with the given arguments.
275     */
276    public static JPanel besidesPanel(Component... componentArray)
277    {
278        JPanel panel = new JPanel();
279
280        panel.setLayout(new GridLayout(1, componentArray.length));
281        for (int i = 0; i < componentArray.length; i++)
282            panel.add(componentArray[i]);
283        panel.validate();
284
285        return panel;
286    }
287
288    /**
289     * This generate a panel with an empty border on the side, so that it is
290     * quite pretty. Generated with a boxLayout
291     * 
292     * @return a JPanel
293     */
294    public static JPanel generatePanel()
295    {
296        JPanel panel = new JPanel();
297
298        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
299        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
300
301        return panel;
302    }
303
304    public static JPanel generatePanel(String string)
305    {
306        JPanel panel = generatePanel();
307
308        panel.setBorder(new TitledBorder(string));
309        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
310
311        return panel;
312    }
313
314    public static JPanel generatePanelWithoutBorder()
315    {
316        JPanel panel = new JPanel();
317
318        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
319
320        return panel;
321    }
322
323    /**
324     * Allow to enable/Disable all the content of a container ( such as a JPanel
325     * for instance )
326     * 
327     * @deprecated what was the goal of this method ???
328     */
329    @Deprecated
330    public static void setEnableContainer(Container container, boolean enable)
331    {
332        for (Component c : container.getComponents())
333        {
334            if (c instanceof Container)
335                setEnableContainer((Container) c, enable);
336            c.setEnabled(enable);
337        }
338    }
339
340    public static TitledFrame generateTitleFrame(String title, JPanel panel, Dimension titleDimension,
341            boolean resizable, boolean closable, boolean maximizable, boolean iconifiable)
342    {
343        final Dimension dim;
344
345        if (titleDimension == null)
346            dim = new Dimension(400, 70);
347        else
348            dim = titleDimension;
349
350        final TitledFrame result = new TitledFrame(title, dim, resizable, closable, maximizable, iconifiable);
351
352        result.getMainPanel().add(panel);
353        result.setVisible(true);
354
355        return result;
356    }
357
358    /**
359     * @param window
360     *        the window to convert in IcyFrame
361     * @return an IcyFrame with the content of specified window (same properties and components)<br/>
362     *         The returned frame windows event (opened, closing, closed) are forwarded to the original window to
363     *         maintain original event behaviors<br/>
364     *         Only the <code>closed</code> event is listened from the original window which will automatically call the
365     *         close() method of the returned IcyFrame.
366     */
367    public static IcyFrame createIcyFrameFromWindow(final Window window)
368    {
369        String title;
370        Component content;
371        JMenuBar menuBar;
372
373        if (window instanceof Frame)
374        {
375            final Frame f = (Frame) window;
376
377            title = f.getTitle();
378
379            if (f instanceof JFrame)
380            {
381                content = ((JFrame) f).getContentPane();
382                menuBar = ((JFrame) f).getJMenuBar();
383            }
384            else
385            {
386                content = f.getComponent(0);
387                menuBar = SwingUtil.getJMenuBar(f.getMenuBar(), false);
388            }
389        }
390        else if (window instanceof Dialog)
391        {
392            final Dialog d = (Dialog) window;
393
394            title = d.getTitle();
395
396            if (d instanceof JDialog)
397            {
398                content = ((JDialog) d).getContentPane();
399                menuBar = ((JDialog) d).getJMenuBar();
400            }
401            else
402            {
403                content = d.getComponent(0);
404                menuBar = null;
405            }
406        }
407        else
408        {
409            title = window.getName();
410            content = window.getComponent(0);
411            menuBar = null;
412        }
413
414        final IcyFrame frame = new IcyFrame(title, true, true, false, false);
415        frame.setLayout(new BorderLayout());
416        frame.add(content, BorderLayout.CENTER);
417        frame.setJMenuBar(menuBar);
418        
419        // keep this property
420        if (window instanceof JFrame)
421            frame.setDefaultCloseOperation(((JFrame) window).getDefaultCloseOperation());
422        else if (window instanceof JDialog)
423            frame.setDefaultCloseOperation(((JDialog) window).getDefaultCloseOperation());
424
425        frame.pack();
426        frame.getIcyExternalFrame().setSize(window.getSize());
427        frame.getIcyInternalFrame().setSize(window.getSize());
428        frame.center();
429
430        frame.setFocusable(window.isFocusable());
431        frame.setResizable(false);
432
433        frame.addFrameListener(new IcyFrameAdapter()
434        {
435            @Override
436            public void icyFrameOpened(IcyFrameEvent e)
437            {
438                for (WindowListener l : window.getWindowListeners())
439                    l.windowOpened(new WindowEvent(window, e.getEvent().getID()));
440            }
441
442            @Override
443            public void icyFrameClosing(IcyFrameEvent e)
444            {
445                // ensure we are not doing recursing 'close' calls
446                if (window.isVisible())
447                {
448                    window.setLocation(frame.getLocation());
449                    for (WindowListener l : window.getWindowListeners())
450                        l.windowClosing(new WindowEvent(window, e.getEvent().getID()));
451                }
452            }
453
454            @Override
455            public void icyFrameClosed(IcyFrameEvent e)
456            {
457                // ensure we are not doing recursing 'close' calls
458                if (window.isVisible())
459                {
460                    for (WindowListener l : window.getWindowListeners())
461                        l.windowClosed(new WindowEvent(window, e.getEvent().getID()));
462                }
463            }
464        });
465
466        window.addWindowListener(new WindowAdapter()
467        {
468            @Override
469            public void windowClosed(WindowEvent e)
470            {
471                super.windowClosed(e);
472                frame.close();
473            }
474        });
475
476        return frame;
477    }
478
479    public static void setCursor(Component c, int cursor)
480    {
481        if (c == null)
482            return;
483
484        if (c.getCursor().getType() != cursor)
485            c.setCursor(Cursor.getPredefinedCursor(cursor));
486    }
487
488    /**
489     * @deprecated Use {@link GraphicsUtil#paintIcyBackGround(int, int, Graphics)} instead
490     */
491    @Deprecated
492    public static void paintBackGround(int width, int height, Graphics g)
493    {
494        GraphicsUtil.paintIcyBackGround(width, height, g);
495    }
496
497    /**
498     * @deprecated Use {@link GraphicsUtil#paintIcyBackGround(Component, Graphics)} instead
499     */
500    @Deprecated
501    public static void paintBackGround(Component component, Graphics g)
502    {
503        GraphicsUtil.paintIcyBackGround(component, g);
504    }
505
506    /**
507     * @deprecated Use {@link GraphicsUtil#paintIcyBackGround(Component, Graphics)} instead
508     */
509    @Deprecated
510    public static void paintBackGround(Image image)
511    {
512        GraphicsUtil.paintIcyBackGround(image);
513    }
514
515    /**
516     * @deprecated Use {@link GraphicsUtil#getStringBounds(Graphics, Font, String)} instead
517     */
518    @Deprecated
519    public static Rectangle2D getStringBounds(Graphics g, Font f, String s)
520    {
521        return GraphicsUtil.getStringBounds(g, f, s);
522    }
523
524    /**
525     * @deprecated Use {@link GraphicsUtil#getStringBounds(Component, String)} instead
526     */
527    @Deprecated
528    public static Rectangle2D getStringBounds(Component c, String s)
529    {
530        return GraphicsUtil.getStringBounds(c, s);
531    }
532
533    /**
534     * @deprecated Use {@link GraphicsUtil#getStringBounds(Graphics, String)} instead
535     */
536    @Deprecated
537    public static Rectangle2D getStringBounds(Graphics g, String s)
538    {
539        return GraphicsUtil.getStringBounds(g, s);
540    }
541
542    /**
543     * @deprecated uses {@link GraphicsUtil#drawHCenteredString(Graphics, String, int, int, boolean)} instead
544     */
545    @Deprecated
546    public static void drawHCenteredText(Graphics g, String string, int w, int y)
547    {
548        GraphicsUtil.drawHCenteredString(g, string, w / 2, y, false);
549    }
550
551    /**
552     * @deprecated Use {@link GraphicsUtil#drawCenteredString(Graphics, String, int, int, boolean)} instead
553     */
554    @Deprecated
555    public static void drawCenteredText(Graphics g, String string, int w, int h)
556    {
557        GraphicsUtil.drawCenteredString(g, string, w / 2, h / 2, false);
558    }
559}