如何在JPanel上绘制图像并在其中添加组件

时间:2018-08-13 14:34:24

标签: java swing paintcomponent

我的应用程序是一个简单的Brick Breaker游戏。为了绘制应用程序的外观,我使用paintComponent方法。该应用程序还具有使用以下代码添加的几个按钮:

levelMenu = new JPanel() {
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            double scale = screenSize.getHeight()/1080;
            Graphics2D g2d = (Graphics2D) g;
            g2d.scale(scale, scale);
            g2d.drawImage(background, 0, 0, null);
        }
    };
    levelMenu.setLayout(new FlowLayout());
    JPanel subPanel = new JPanel(new GridLayout(20, 2, 10, 10));
    subPanel.setBackground(Constants.CLEAR);

    subPanel.add(new JLabel());
    subPanel.add(new JLabel());
    for (JButton level: levelList) {
        subPanel.add(level);
    }
    subPanel.add(new JLabel());
    subPanel.add(back);

    levelMenu.add(subPanel);
    this.add(levelMenu);

我的问题是正在添加按钮,但它们似乎也涂在应用程序的背景图像中:example screen shot

右侧的按钮不起作用,仅是图像。有关如何解决此问题的任何线索。

2 个答案:

答案 0 :(得分:0)

使用以下代码段供您参考:

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicPanelUI;

class MyPanelUI extends BasicPanelUI {
    public void paint(Graphics g, JComponent c) {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Graphics2D g2d = (Graphics2D) g;

        Image img = toolkit.getImage("/usr/share/backgrounds/warty-final-ubuntu.png");
        g2d.drawImage(img, 0, 0, null);
    }

    public Dimension getPreferredSize(JComponent c) {
        return super.getPreferredSize(c);
    }
}

public class PanelBGTest {

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

        JPanel panel = new JPanel();
        panel.setUI(new MyPanelUI());
        panel.setLayout(new FlowLayout());
        panel.add(new JButton("This is button"));

        SwingUtilities.updateComponentTreeUI(frame);

        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setVisible(true);
    }
}

使用paint组件不是一个好习惯,因此从基础组件UI类扩展组件UI类并覆盖paint()方法总是更好的选择。这样,swing将负责所有渲染/重新渲染部分,并且添加到面板中的组件也将可见。

现在,我强烈建议您停下来通读一遍:

答案 1 :(得分:0)

主要问题归结于...

html_code

传递给Graphics2D g2d = (Graphics2D) g; g2d.scale(scale, scale); g2d.drawImage(background, 0, 0, null); 方法的Graphics上下文是共享资源,绘画过程中呈现的所有组件都将使用它。这意味着您对其进行的任何更改也会影响它们。您应该特别注意转换(例如paintComponenttranslate)。

通常的做法是在使用scale上下文之前制作快照状态,这使您可以在影响原始文档的情况下对副本进行更改,例如...

Graphics

另一个问题是Graphics2D g2d = (Graphics2D) g.create(); g2d.scale(scale, scale); g2d.drawImage(background, 0, 0, null); g2d.dispose(); 。我假设这是基于alpha的颜色。 Swing组件不支持基于Alpha的颜色,它们是完全不透明的或完全透明的(尽管您可以伪造它)。这是通过使用subPanel.setBackground(Constants.CLEAR);

来控制的

现在,我强烈建议您停下来通读一遍: