【发布时间】:2012-12-12 02:29:12
【问题描述】:
好的,我又来了。
我有一个 JPanel,我已在其上覆盖 paintComponent() 并在自定义 bufferedImage 上绘制,以为我的 JPanel 提供背景图像。我也有一个 JButton,我做了同样的事情,以便创建一个具有自定义形状的按钮。问题是,虽然 JButton 似乎已正确添加到带有背景图像的 JPanel 中,但并未正确绘制。
我可以从按钮获得输入,就好像它确实存在一样,但它实际上并没有显示出来,而它在标准 JPanel 上显示。下面是一个例子。
提前感谢您的帮助。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Test {
public static void main (String[] args){
final JFrame frame = new JFrame();
DrawPanel panel1 = new DrawPanel(createBufferedImage("background.png"));
JPanel panel2 = new JPanel();
DrawButton button1 = new DrawButton(createBufferedImage("button.png"));
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
JOptionPane.showMessageDialog(frame, "input detected, button1");
}
});
DrawButton button2 = new DrawButton(createBufferedImage("button.png"));
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
JOptionPane.showMessageDialog(frame, "input detected, button2");
}
});
panel1.add(button1);
panel2.add(button2);
frame.getContentPane().add(panel1, BorderLayout.NORTH);
frame.getContentPane().add(panel2, BorderLayout.CENTER);
frame.validate();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
protected static BufferedImage createBufferedImage(String path){
File img = new File(path);
BufferedImage bi = null;
try{
bi = ImageIO.read(img);
}
catch (IOException ioe){
throw new RuntimeException();
}
BufferedImage newImage = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = newImage.createGraphics();
g2d.drawImage(bi, 0, 0, null);
g2d.dispose();
return newImage;
}
}
class DrawPanel extends JPanel{
private BufferedImage bg;
public DrawPanel(BufferedImage bg){
this.bg = bg;
new JPanel();
setPreferredSize(new Dimension(bg.getWidth(), bg.getHeight()));
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(bg, 0, 0, null);
g.dispose();
}
}
class DrawButton extends JButton{
private BufferedImage bi;
public DrawButton(BufferedImage bi){
setPreferredSize(new Dimension(bi.getWidth(), bi.getHeight()));
this.bi = (BufferedImage) bi;
setContentAreaFilled(false);
}
@Override
public Dimension getPreferredSize(){
return new Dimension(bi.getWidth(), bi.getHeight());
}
public BufferedImage getIconImage(){
return bi;
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(bi, 0, 0, null);
g.dispose();
}
}
【问题讨论】:
-
DrawPanel构造函数中调用
new JPanel();的目的是什么?为什么要创建一个从不需要、从不使用、从不分配给变量并在构造函数超出范围时简单地处理掉的对象? -
@HovercraftFullOfEels 有……没有任何目的。我认为最初的 DrawPanel 只是一个 JPanel,而不是一个对象,我从来没有摆脱这个调用。哎呀。
-
class DrawButton extends JButton{不要那样做,只需为其添加一个图标,setContentAreaFilled(false)&setBorder(null)。 -
@AndrewThompson 由于我使用按钮的方式,我需要将 DrawButton 创建为自己的类。有关更多信息,请参阅此问题:link。我认为没有必要具体解释为什么我这样做,因为为什么似乎与手头的问题无关,只是它是一个问题。我知道您建议的方法,并且我已经将其视为不适合我的用例而将其驳回。
标签: java swing jpanel jbutton paintcomponent