我该如何在一张图片上放置一个JButton?

5
我正在尝试修复一个JFrame,其中将有一个背景图像和在图像上执行某些命令的JButtons。我尝试不使用布局来完成它,因为我想在JFrame的特定位置放置小按钮,但每次我这样做时,背景图像就会到前面或JFrame的大小等于JFrame大小。使用以下代码,JButton与JFrame具有相同的大小。我已经尝试更改JButton的大小和位置,但没有效果。你能帮我吗?

以下是代码:


public final class Test extends JComponent
{
 private Image background;
 private JFrame frame;
 private Dimension dimension;

public Test()
{  
    dimension = new Dimension(15, 15);
    frame = new JFrame("Iphone");
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(this);
    frame.setBounds(641, 0, 344, 655);
    frame.setVisible(true);

    test = displayButton("tigka");
    frame.getContentPane().add(test);
}

public void update(Graphics g)
{
    paint(g);
}


public void paintComponent(Graphics g)
{
    super.paintComponents(g);
    g.drawImage(background, 0, 25, null); // draw background

// 标签();


摆脱update()方法。在Swing中没有必要覆盖此方法。那是AWT的旧代码,不应在Swing应用程序中使用。 - camickr
4个回答

6
您需要更改“内容窗格”以为您的“Frame”获取背景。
public static void main(String[] args) throws IOException {

    JFrame frame = new JFrame("Test");

    frame.setContentPane(new JPanel() {
        BufferedImage image = ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, 300, 300, this);
        }
    });

    frame.add(new JButton("Test Button"));

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(300, 300);
    frame.setVisible(true);
}

输出:

截图


1
错误:(可能是打字错误)调用超级方法的正确方法是paintComponent而不是paintComponents。 - kleopatra
2
@dacwe @kleopatra 如果你将它改为paintComponent(我认为是正确的),那么它应该被用作首先完成所有默认绘画,然后再在其上绘制图像。自己测试一下。 - Boro
@Boro,那就是我想说的——请看我对Thomas答案的评论——我懒得在这里重复了 :-) - kleopatra
当我尝试将按钮定位到某个位置x,y时,它无法正常工作。请回复。 - Raj Trivedi
@RajTrivedi,你的评论对这个问题/答案没有贡献,请写另一个问题,我很乐意回答。 - dacwe
显示剩余5条评论

1
你尝试过在JLabel标签中使用HTML吗?像这样:
import javax.swing.*;

public class SwingImage1
{
  public static void main( String args[] )
  {
    JFrame  frm = new JFrame( "Swing Image 1" );
    JLabel  lbl = new JLabel( "<html><body><img src=\"http://liv.liviutudor.com/images/liv.gif\"></body></html>" );
    frm.getContentPane().add( lbl );
    frm.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    frm.pack();
    frm.setVisible( true );
  }
}

然后在您的标签上方添加按钮即可?


实际上这是解决问题的一种不同方法。它将帮助我解决当前的问题,但我认为它也会改变许多事情。无论如何,感谢您的回答。 - Eristikos
不要在不必要的地方使用HTML,而应该创建并设置ImageIcon。此外,使用JLabel也不是一个好主意:要求是在添加的常规组件下面有一个背景。 - kleopatra

1
你应该交换这两行代码的位置:
super.paintComponents(g);  //paints the children, like the button
g.drawImage(background, 0, 25, null); // draw background later possibly overwriting the button

因此应该是这个顺序:

g.drawImage(background, 0, 25, null);
super.paintComponents(g); 

此外,请注意内容窗格的默认布局是BorderLayout。因此,您需要显式地将内容窗格的布局设置为null。

这是一个非常有帮助的答案,因为我不知道内容面板的默认布局。谢谢。关于第一个提示,有什么区别吗? - Eristikos
我的帖子中没有任何区别,只是你的代码加上了注释和交换提示。 :) - Thomas
2
不要在Swing JComponents中触碰awt绘图方法;-) 所以它是一个-1,除了在完全困惑我的情况下有所帮助 - 因为在自定义绘制代码之前调用super.paintComponent 实现顺序(否则,自定义绘制将被不透明组件的背景覆盖) - kleopatra
是的,这将是正确的顺序,但他调用了super.paintComponents而不是super.paintComponent。除此之外你是对的,不应该手动调用那个方法,而是调用paintComponent(没有认出那可能是一个打字错误 :))。 - Thomas

0
/*it is simple to put button on image first set image by making object then make button object & add the button object direct to image object rather then add to frame.*/

package frame;



import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class frame 
{

    public frame() 
    {
        JFrame obj = new JFrame("Banking Software");
        JButton b1 = new JButton("Opening Account");
        JLabel image = new JLabel(new ImageIcon("money.jpg"));
        image.setBounds(0,0, 1600, 1400);
        obj.setExtendedState(JFrame.MAXIMIZED_BOTH);
        obj.add(image);
        b1.setBounds(500,400, 100, 40);
        image.add(b1);
        obj.setVisible(true);
    }

    public static void main(String args[]) 
    {
        new frame();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接