Java GUI 在标签上绘制图片

Java GUI paint picture on labels

我想添加一张将出现在面板和标签上的图片,但我不知道该怎么做。

my code:

JFrame frame = new JFrame();
JPanel panel = new JPanel();
JPanel mainPanel = new JPanel();

panel.setLayout(new GridLayout(5, 5));
for (int i = 0; i < 5; i++) 
    for (int j = 0; j < 5; j++) 
    {
        JLabel label = new JLabel();
        label.setPreferredSize(new Dimension(50, 50));
        label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        panel.add(label);
    }



mainPanel.add(panel);
frame.add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);

我的图片: https://i.stack.imgur.com/w0Ssy.png

我想做的: https://i.stack.imgur.com/ZLPqF.png

执行此操作的方法是使用 JLabel.setIcon

JLabel l = ...;
l.setIcon(myIcon);

您可以使用 ImageIcon 从图像制作图标。

您可以通过从 disk/url 加载图像来获取图像,或者通过创建 BufferedImage 并绘制到其 Graphics 对象来创建自己的图像。

如果您要使用组件来完成这项工作,那么您将需要对布局管理器进行一些处理。由于它的灵活性,我会使用 GridBagLayout,事实上,我很确定它是唯一允许您执行类似操作的内置布局...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.MatteBorder;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new GamePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class GamePane extends JPanel {

        public GamePane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            for (int y = 0; y < 10; y++) {
                for (int x = 0; x < 10; x++) {
                    GridPane gridPane;
                    if (y == 9) {
                        if (x == 9) {
                            gridPane = new GridPane(1, 1, 1, 1);
                        } else {
                            gridPane = new GridPane(1, 1, 1, 0);
                        }
                    } else if (x == 9) {
                        gridPane = new GridPane(1, 1, 0, 1);
                    } else {
                        gridPane = new GridPane(1, 1, 0, 0);
                    }
                    gbc.gridx = x;
                    gbc.gridy = y;
                    add(gridPane, gbc);
                }
            }

            gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.gridwidth = 1;
            gbc.gridheight = 4;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(new ShipPane(1, 4), gbc, 0);

            gbc = new GridBagConstraints();
            gbc.gridx = 2;
            gbc.gridy = 1;
            gbc.gridwidth = 3;
            gbc.gridheight = 1;
            gbc.fill = GridBagConstraints.BOTH;
            add(new ShipPane(3, 1), gbc, 0);
        }

    }

    public class Configuration {
        public static int GRID_SIZE = 50;
    }

    public class GridPane extends JPanel {

        public GridPane(int top, int left, int bottom, int right) {
            setBorder(new MatteBorder(top, left, bottom, right, Color.DARK_GRAY));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(Configuration.GRID_SIZE, Configuration.GRID_SIZE);
        }

    }

    public class ShipPane extends JPanel {

        private int gridWidth, gridHeight;

        public ShipPane(int gridWidth, int gridHeight) {
            this.gridWidth = gridWidth;
            this.gridHeight = gridHeight;
            setOpaque(false);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(Configuration.GRID_SIZE * gridWidth, Configuration.GRID_SIZE * gridHeight);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(new Color(255, 0, 0, 128));
            g.fillRect(0, 0, getWidth(), getHeight());
        }
    }
}

现在,我只是在使用一个面板,但无需太多工作,您可以将 JLabel 添加到 ShipPane

现在,话虽如此。我想我会从完全“自定义绘画”的路线来解决这个问题