001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     *
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.gui.panels;
025    
026    import java.awt.Color;
027    import java.awt.Graphics;
028    import java.awt.Graphics2D;
029    import java.awt.event.ComponentEvent;
030    import java.awt.event.ComponentListener;
031    import java.awt.image.BufferedImage;
032    import java.lang.reflect.Method;
033    
034    import javax.swing.JPanel;
035    
036    import org.ujmp.gui.interfaces.CanBeRepainted;
037    import org.ujmp.gui.interfaces.CanBeUpdated;
038    import org.ujmp.gui.util.GraphicsExecutor;
039    import org.ujmp.gui.util.UIDefaults;
040    import org.ujmp.gui.util.UpdateListener;
041    
042    public class BufferedPanel extends JPanel implements CanBeRepainted,
043                    ComponentListener, UpdateListener {
044            private static final long serialVersionUID = 7495571585267828933L;
045    
046            private JPanel panel = null;
047    
048            private BufferedImage bufferedImage = null;
049    
050            public BufferedPanel(JPanel panel) {
051                    this.panel = panel;
052                    this.addComponentListener(this);
053                    GraphicsExecutor.scheduleUpdate(this);
054                    if (panel instanceof CanBeUpdated) {
055                            ((CanBeUpdated) panel).addUpdateListener(this);
056                    }
057            }
058    
059            protected void paintComponent(Graphics g) {
060                    super.paintComponent(g);
061                    Graphics2D g2d = (Graphics2D) g;
062                    if (bufferedImage != null) {
063                            g2d.drawImage(bufferedImage, 0, 0, getWidth(), getHeight(), null);
064                    } else {
065                            g2d.addRenderingHints(UIDefaults.AALIAS);
066                            g2d.setColor(Color.gray);
067                            g2d.drawLine(0, 0, getWidth(), getHeight());
068                            g2d.drawLine(getWidth(), 0, 0, getHeight());
069                    }
070            }
071    
072            public void paintUsingReflection(Graphics2D g2d) throws Exception {
073                    try {
074                            panel.paint(g2d);
075                    } catch (Exception e) {
076                            Method m = panel.getClass().getMethod("paintComponent",
077                                            Graphics.class);
078                            boolean accessible = m.isAccessible();
079                            m.setAccessible(true);
080                            m.invoke(panel, new Object[] { g2d });
081                            m.setAccessible(accessible);
082                    }
083            }
084    
085            public void repaintUI() {
086                    try {
087                            int width = getWidth();
088                            width = width < 1 ? 1 : width;
089                            int height = getHeight();
090                            height = height < 1 ? 1 : height;
091                            BufferedImage tempBufferedImage = new BufferedImage(width, height,
092                                            BufferedImage.TYPE_INT_RGB);
093                            panel.setSize(width, height);
094                            Graphics2D g2d = (Graphics2D) tempBufferedImage.getGraphics();
095                            paintUsingReflection(g2d);
096                            g2d.dispose();
097                            bufferedImage = tempBufferedImage;
098                    } catch (Exception e) {
099                            e.printStackTrace();
100                    }
101            }
102    
103            public void componentHidden(ComponentEvent e) {
104                    GraphicsExecutor.scheduleUpdate(this);
105            }
106    
107            public void componentMoved(ComponentEvent e) {
108                    GraphicsExecutor.scheduleUpdate(this);
109            }
110    
111            public void componentResized(ComponentEvent e) {
112                    GraphicsExecutor.scheduleUpdate(this);
113            }
114    
115            public void componentShown(ComponentEvent e) {
116                    GraphicsExecutor.scheduleUpdate(this);
117            }
118    
119            public void updated() {
120                    GraphicsExecutor.scheduleUpdate(this);
121            }
122    }