是否可以在同一个 JPanel 中的按钮后面绘制更新图像?我试图让菜单屏幕正常工作,但是当我尝试放入一个绘画循环来更新背景图像时,按钮消失了。注意:这些是自定义按钮,它们是不可见的,除了我使用 JButton.setIcon 放入其中的自定义图像(如果这对渲染有任何影响)。
public class MenuPanel extends JPanel{
BufferedImage image;
private int height =Toolkit.getDefaultToolkit().getScreenSize().height-37;
private int width = Toolkit.getDefaultToolkit().getScreenSize().width;
private JButton optionsButton = new JButton("Options");
private JButton startButton = new JButton ("Start");
public MenuPanel() {
setLayout(null);
setSize(width, height);
try {image = ImageIO.read(new File("stuyrim.png"));}
catch (Exception e) {Utilities.showErrorMessage(this, e);}
optionsButton.addActionListener(e -> {
// optionsButton.getParent().getParent();
});
optionsButton.setOpaque(false);
optionsButton.setBorderPainted(false);
optionsButton.setContentAreaFilled(false);
optionsButton.setSize(width/10,height/20);
optionsButton.setVerticalTextPosition(SwingConstants.CENTER);
optionsButton.setHorizontalTextPosition(SwingConstants.CENTER);
optionsButton.setFont(new Font("TimesRoman", Font.PLAIN, 20));
optionsButton.setLocation((width/3)-(width/20), (height/7*6)-(height/40));
Image img = new ImageIcon("GUI Images/Button.png").getImage().getScaledInstance
(optionsButton.getWidth(),optionsButton.getHeight(),java.awt.Image.SCALE_SMOOTH);
optionsButton.setIcon(new ImageIcon(img));
optionsButton.setForeground(Color.white);
startButton.addActionListener(e -> {
startButton.getParent().getParent().add(new Screen());
startButton.getParent().getParent().add(new GamePanel());
Graphics g = getGraphics();
g.clearRect(0,0,width,height);
startButton.getParent().getParent().remove(this);
g.dispose();
});
startButton.setOpaque(false);
startButton.setBorderPainted(false);
startButton.setContentAreaFilled(false);
startButton.setSize(width/10,height/20);
startButton.setVerticalTextPosition(SwingConstants.CENTER);
startButton.setHorizontalTextPosition(SwingConstants.CENTER);
startButton.setFont(new Font("TimesRoman",Font.PLAIN, 20));
startButton.setLocation((width/3*2)-(width/20), (height/7*6)-(height/40));
Image img1 = new ImageIcon("GUI Images/Button.png").getImage().getScaledInstance
(optionsButton.getWidth(),optionsButton.getHeight(),java.awt.Image.SCALE_SMOOTH);
startButton.setIcon(new ImageIcon(img1));
startButton.setForeground(Color.white);
add(optionsButton);
add(startButton);
setVisible(true);
revalidate();
repaint();
}
public void paintComponent(Graphics g) {
g.drawImage(image,0,0,width,height, null);
g.dispose();
}
}
最佳答案
有两个基本问题...
首先,正如 System.exit 所强调的那样,您应该在执行任何自定义绘制之前调用 super.paintComponent
。
原因是传递给 paintComponent
的 Graphics
上下文是共享资源。在您的组件之前绘制的所有内容以及在它之后绘制的所有内容都将共享相同的 Graphics
上下文。
paintComponent
的其中一项工作是准备用于绘制的 Graphics
上下文(通常是用组件的背景色填充所需的空间)。
第二个是getGraphics
的使用。 getGraphics
获取对用于绘制组件的最后一个 Graphics
上下文的引用(如果组件尚未绘制,则可以为 null
) ,如果您在 Swings 定义的绘画链之外使用此绘画,这会产生随机且不可预测的结果。
Swing 使用被动渲染算法,也就是说,绘画以不规则的间隔发生,并且可能由于多种原因而发生,其中许多原因是您无法控制或没有发起的。
所有自定义绘画都应该在 Swing 定义的绘画链中完成,按照惯例,这通常是通过覆盖 paintComponent
方法来完成的。
看看Performing Custom Painting和 Painting in AWT and Swing了解更多详情
关于Java:为什么在按钮上绘制背景图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23878889/