先看效果图片:
好吧,你没看懂就对了,我来解释一下
图中的效果是,拖动滚动条,背景的云图片 和 飞碟图片 位置都不变,文本内容跟着滚动条变化
可能你觉得这个没什么实际用处,不过飞碟图片换成某些logo或许好点,比如CCTV
来看实现原理
首先你要知道JScrollPane分9个区域(可以参考http://blog.csdn.net/mylxiaoyi/article/details/7487167),中间的viewport区域就是内容
一般我们是用JScrollPane的这个方法来添加控件到中间区域public void setViewportView(Component view)
但是需要画的背景就是中间区域的背景,所以要重写JViewport类,然后重载paintComponent和paintChildren,再把JViewport set到JScrollPane
JViewport先调用paintComponent来画自己,然后调用paintChildren来画添加到JViewport的Component
这样思路就来了,先在paintComponent方法里画云图片背景,然后在paintChildren里调用super画子控件,再画飞碟图片
上代码:
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.imageio.*;
import java.awt.image.*;
import javax.swing.table.*;
// put a texture in the background
// put a translucent image in the foreground
// put a yellow gradient inthe background
// put a translucent sun in the upper right
public class ScrollPaneWatermark extends JViewport {
BufferedImage fgimage, bgimage;
TexturePaint texture;
public ScrollPaneWatermark(){
super();
//setOpaque(false);
}
public void setBackgroundTexture(URL url) throws IOException {
bgimage = ImageIO.read(url);
Rectangle rect = new Rectangle(0,0,
bgimage.getWidth(null),bgimage.getHeight(null));
texture = new TexturePaint(bgimage, rect);
}
public void setForegroundBadge(URL url) throws IOException {
fgimage = ImageIO.read(url);
}
public void paintComponent(Graphics g) {
// do the superclass behavior first
super.paintComponent(g);
System.out.println("p");
//画云背景
if(texture != null) {
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(texture);
g.fillRect(0,0,getWidth(),getHeight());
}
}
public void paintChildren(Graphics g) {
super.paintChildren(g);
//画飞碟
if(fgimage != null) {
g.drawImage(fgimage,
getWidth()-fgimage.getWidth(null), 0,
null);
}
}
public void setView(JComponent view) {
view.setOpaque(false);
super.setView(view);
}
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame("Scroll Pane Watermark Hack");
JTextArea ta = new JTextArea();
ta.setText(fileToString(new File("alice.txt")));
ta.setLineWrap(true);
ta.setWrapStyleWord(true);
//ta.setOpaque(false);
ScrollPaneWatermark watermark = new ScrollPaneWatermark();
watermark.setBackgroundTexture(new File("clouds.jpg").toURL());
watermark.setForegroundBadge(new File("flyingsaucer.png").toURL());
watermark.setView(ta);
JScrollPane scroll = new JScrollPane();
scroll.setViewport(watermark);
frame.getContentPane().add(scroll);
frame.pack();
frame.setSize(600,600);
frame.show();
}
public static String fileToString( File file )
throws FileNotFoundException, IOException {
FileReader reader = new FileReader( file );
StringWriter writer = new StringWriter();
char[] buf = new char[1000];
while ( true ) {
int n = reader.read( buf, 0, 1000 );
if ( n == -1 ) {
break;
}
writer.write( buf, 0, n );
}
return writer.toString();
}
}