我有一个带有GridBagLayout()的JFrame窗口。有一个带图标的JLabel -它是一个地图。现在我需要在地图上方显示另一张图片(玩家位置指示器)。
这可能吗,怎么可能?
非常感谢!
子类JLabel并重写paint方法
public void paintComponent(Graphics g) {
super.paintComponent(g);
// paint player location on map
}
处理从游戏坐标到地图坐标的转换
作为paintComponent()
的替代品,您可能还想看看OverlayLayout
,如图所示。由于某些原因,它没有包含在图库中,但它可能是有用的。
忍不住把这个问题作为一个机会来玩新的jdk7 api:-)
Override paintComponent 绝对是一个很好的解决方案。然而,它需要子类化,只是为了在给定位置的其他东西上面绘制一些东西。旧的方法是使用JLayeredPane(处理起来很麻烦)。新jdk有一个JLayer组件,通过对组件的简单修饰,就可以实现这个功能(以及更多)。下面是一个代码片段
- 有一个带有基本图像的标签,并使用默认的JLayer 来装饰它
- 将"player"图像添加到图层的玻璃窗格
- 使用Rob的DragLayout(设置在glasspan上)来移动玩家,带有两个滑块的裸骨ui
工作代码(只是一些外部锅炉板丢失,你都有你的模板来坚持:)
// to please Andrew :)
JLabel fooLabel = new JLabel(new ImageIcon(ImageIO.read(
new URL("http://pscode.org/media/stromlo2.jpg"))));
final JLayer<JLabel> layer = new JLayer<JLabel>(fooLabel);
final JLabel player = new JLabel(new CursorIcon(30));
// to please myself (never-ever use a null layout :)
layer.getGlassPane().setLayout(new DragLayout());
layer.getGlassPane().add(player);
layer.getGlassPane().setVisible(true);
final JSlider horizontal = new JSlider(0, fooLabel.getPreferredSize().width, 0);
final JSlider vertical = new JSlider(JSlider.VERTICAL, 0, fooLabel.getPreferredSize().height, 0);
vertical.setInverted(true);
ChangeListener l = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
player.setLocation(horizontal.getValue(), vertical.getValue());
layer.revalidate();
}
};
horizontal.addChangeListener(l);
vertical.addChangeListener(l);
快速图标:
public static class CursorIcon implements Icon {
private int size;
public CursorIcon(int size) {
this.size = size;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.red);
g.drawLine(size/2,y,size/2,size);
g.drawLine(x,size/2,size,size/2);
}
@Override
public int getIconWidth() {
return size;
}
@Override
public int getIconHeight() {
return size;
}
}
对于早期的jdk版本,SwingLabs子项目JXLayer是可用的