001 ///////////////////////////////////////////////// 002 //This file is part of Sears project. 003 //Subtitle Editor And Re-Synch 004 //A tool to easily modify and resynch movies subtitles. 005 ///////////////////////////////////////////////// 006 //This program is free software; 007 //you can redistribute it and/or modify it under the terms 008 //of the GNU General Public License 009 //as published by the Free Software Foundation; 010 //either version 2 of the License, or (at your option) any later version. 011 ///////////////////////////////////////////////// 012 //Sears project is available under sourceforge 013 //at adress: http://sourceforge.net/projects/sears/ 014 //Copyright (C) 2005 Booba Skaya 015 //Mail: booba.skaya@gmail.com 016 ///////////////////////////////////////////////// 017 018 // some suggestions about this class: floriaen@gmail.com 019 020 package sears.gui.glassPane; 021 022 import java.awt.Graphics; 023 import java.awt.Graphics2D; 024 import java.awt.Rectangle; 025 026 import javax.swing.JComponent; 027 import javax.swing.JFrame; 028 import javax.swing.JViewport; 029 import javax.swing.SwingUtilities; 030 031 /** 032 * <p> 033 * This class provides a way to have a virtual rectangle over a viewport 034 * with viewport size and position. 035 * <br>Let the register listener and a resize of the viewport will affect the virtual bounds. 036 * <br>The advantage of this resides in the fact that you can do the same things out and inside of 037 * this virtual bounds. 038 * </p> 039 * <b>How to use it:</b> 040 * <pre> 041 * <i>// init components:</i> 042 * JComponent component = new JComponent(); 043 * JScrollPane scrollPane = new JScrollPane(component); 044 * frame.add(scrollPane); 045 * 046 * <i>// set up the <code>ViewportGlassPane</code> object</i> 047 * ViewportGlassPane gp = new ViewPortGlassPane(scrollPane.getViewport()); 048 * <i>// this method simply call frame.setGlassPane(gp) method</i> 049 * gp.addAsAGlassPane(frame); 050 * 051 * (...) 052 * 053 * EventQueue.invokeLater(new Runnable() { 054 * public void run() { 055 * gp.setVisible(true); 056 * } 057 * }); 058 * </pre> 059 * 060 * @see JViewport 061 */ 062 public abstract class ViewportGlassPane extends JComponent { 063 064 private static final long serialVersionUID = 5504986050347441090L; 065 066 private JViewport viewport; 067 private Rectangle virtualBounds; 068 private ViewportListener listener; 069 070 /** 071 * Constructs a new <code>ViewportGlassPane</code> instance 072 * <br>Register a component listener, instance of <code>ViewportListener</code> to the viewport. 073 * <br>Resizing the view (viewport) will have no indesirable effect on the virtual bounds 074 * 075 * @param viewport the viewport on which the virtual bounds is set 076 * @throws NullPointerException if viewport is null 077 */ 078 public ViewportGlassPane(JViewport viewport) { 079 super(); 080 if( viewport == null ) { 081 throw new NullPointerException("viewport cannot be null"); 082 } 083 this.viewport = viewport; 084 listener = new ViewportListener(this); 085 viewport.addComponentListener(listener); 086 } 087 088 /** 089 * Removes the listener associate to the viewport by the class constructor 090 * <br><b>SECURITY:</b> 091 * this method require that object which calls it knows and have an access 092 * to the viewport gives in parameter of the class constructor 093 * 094 * @param viewport must be equals to the one given in the class constructor parameter 095 * @see Object#equals(Object) 096 */ 097 protected void removeViewportListener(JViewport viewport) { 098 if( viewport.equals(this.viewport)) { 099 viewport.removeComponentListener(listener); 100 } 101 } 102 103 /* 104 * (non-Javadoc) 105 * @see javax.swing.JComponent#paint(java.awt.Graphics) 106 */ 107 public void paintComponent(Graphics g) { 108 super.paintComponent(g); 109 if( g instanceof Graphics2D ) { 110 Graphics2D gr = (Graphics2D) g; 111 paintComponentWithGraphics(gr); 112 } 113 } 114 115 /** 116 * This method is called in <code>paint(g)</code> method. 117 * Allow a way to use the graphics context of this component 118 * 119 * @param gr the graphics context of this component 120 */ 121 protected abstract void paintComponentWithGraphics(Graphics2D gr); 122 123 /** 124 * When viewport changed when a resize is set on it. 125 * And so, is needed to recalculate the virtual bounds 126 */ 127 public void fireViewportSizeChanged() { 128 virtualBounds = null; 129 } 130 131 /** 132 * Determines, if it is not already do, the virtual bounds size and position 133 * @return the virtual bonds as a <code>Rectangle</code> object 134 */ 135 public Rectangle getVirtualBounds() { 136 if( virtualBounds == null ) { 137 virtualBounds = SwingUtilities.convertRectangle(viewport, viewport.getVisibleRect(), this); 138 } 139 return virtualBounds; 140 } 141 142 /** 143 * Sets this as the glass pane of the frame given in parameters. 144 * If frame is null this method is a no op. 145 * @param frame if null nothing is done 146 * @see JFrame#setGlassPane(java.awt.Component) 147 */ 148 public void addAsAGlassPane(JFrame frame) { 149 if( frame != null ) { 150 frame.setGlassPane(this); 151 } 152 } 153 154 /** 155 * Convert and return the component's graphics context 156 * @return the component's graphics context or null if it is null 157 * or not instance of <code>Graphics2D</code> 158 */ 159 @Deprecated 160 protected Graphics2D getGraphics2D() { 161 Graphics2D gr = null; 162 Graphics g = getGraphics(); 163 if( g != null ) { 164 if( g instanceof Graphics2D ) { 165 gr = (Graphics2D) g; 166 } 167 } 168 return gr; 169 } 170 }