JDesktopPane加背景图片

一個基本的觀念:Container - paint method 有責任畫完自身的外觀後,也讓其內的 child component 畫在自己身上,特別是當 child 是 lightweight component 時。Lightweight component 強烈依賴其 parent 提供 Graphics 來繪製元件外觀,若一個 Container 沒有盡到責任留個機會給 lightweight child component 繪製外觀,child component 則無法面對世人(invisible)。Heavy component(如 java.awt.Button etc.)則不在此限,因為 heavyweight component 會促使底層的 windowing system 建立 native component(以 peer 溝通),windowing system 會負責繪出 native component。

瞧瞧你寫的 MyJDesktopPane 壞了規矩,paint method 只顧著繪自己,不管 child component,根本稱不上是合格的 Container。

本來你是可以在 paint method block 最後頭加上 super.paint(g); 來使用原來的 JDesktopPane 的功能(就會盡到 container 的責任),但是因為 JDesktopPane paint method 會先抹掉背景,這麼一來你繪製在先的 image 就被抹掉了;若是把 super.paint(g); 放在最前頭則變成 image 蓋在 child component 上(因為 child components 先繪,"背景" image 後繪)。

JComponent 把 paint method 拆成三個步驟,依序是 paintComponent, paintBorder, paintChildren,負責的任務顧名思義。要加入繪製背景圖的功能在 paintComponent method 裡實做比較適合。請見下面的 demo:

Demo1


package com.jsptw.j2se;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;

public class WPDesktop extends JDesktopPane {
private Image wallPaper;

public static void main(String[] args)
{
Image bg = Toolkit.getDefaultToolkit().createImage(
WPDesktop.class.getResource("images/risako.jpg"));
JDesktopPane desktop = new WPDesktop(bg);

JInternalFrame childFrame = new JInternalFrame("MDI child frame", true);
childFrame.setBounds(100, 100, 200, 200);
desktop.add(childFrame, new Integer(10));
childFrame.show();

JFrame mainFrame = new JFrame("Application main frame");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.getContentPane().add(desktop);
mainFrame.pack();
mainFrame.show();
}
public WPDesktop(Image wallPaper)
{
this.wallPaper = wallPaper;
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(wallPaper, 0);
try {
tracker.waitForAll();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}

protected void paintComponent(Graphics g)
{
super.paintComponent(g);

int width = wallPaper.getWidth(this);
int height = wallPaper.getHeight(this);
Dimension size = getSize();

// paint tiled wall paper
for (int x = 0; x < size.width; x += width)
for (int y = 0; y < size.height; y += height)
g.drawImage(wallPaper, x, y, this);
}

public Dimension getPreferredSize()
{
return new Dimension(wallPaper.getWidth(this), wallPaper.getHeight(this));
}
}


另外一種作法可以不要 customize JDesktopPane,如同前幾篇文章提到,把一張顯示 image 的 JLabel 放置於 JDesktoPane 最下層(JDesktopPane 就是 JLayeredPane)。如下:

package com.jsptw.j2se;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class DesktopDemo extends JFrame {

public static void main(String[] args)
{
Image bgImage = Toolkit.getDefaultToolkit().createImage(DesktopDemo.class.getResource(
"images/lavigne_avril_005.jpg"));
JFrame frm = new DesktopDemo(bgImage);
frm.setTitle("A MDI Frame with a image as background.");
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.pack();
frm.show();
}

public DesktopDemo(Image image) throws HeadlessException
{
super(image.toString());

_bgImage = image;
initComponsnts();
}

public Container getContentPane()
{
return _content;
}

private void initComponsnts()
{
JDesktopPane desk = new JDesktopPane() {
public Dimension getPreferredSize()
{
return _bgView.getPreferredSize();
}
};
_bgView = new JLabel(new ImageIcon(_bgImage), JLabel.CENTER);
_bgView.setOpaque(true);

_content = (JPanel) super.getContentPane();
_content.setOpaque(false);
desk.add(_content, JDesktopPane.FRAME_CONTENT_LAYER);

desk.add(
_bgView,
new Integer(JDesktopPane.FRAME_CONTENT_LAYER.intValue() - 1));

desk.addComponentListener(new ComponentAdapter(){
public void componentResized(ComponentEvent e)
{
Dimension size = e.getComponent().getSize();
_bgView.setSize(size);
_content.setSize(size);
_content.revalidate();
}
});
setContentPane(desk);

JInternalFrame dummy1 =
new JInternalFrame("Dummy frame A", true, true, true, true);
dummy1.setBounds(100, 100, 300, 200);
desk.add(dummy1, JDesktopPane.DEFAULT_LAYER);
dummy1.show();

JInternalFrame dummy2 = new JInternalFrame("Dummy frame B", true, true);
dummy2.setBounds(200, 200, 400, 300);
desk.add(dummy2, JDesktopPane.DEFAULT_LAYER);
dummy2.show();
}

private Image _bgImage;
private JLabel _bgView;
private JPanel _content;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值