簡體   English   中英

Java將圖形繪圖與Swing組件結合在一起

[英]Java combine graphics drawing with swing components

我正在嘗試創建地圖編輯器,並且希望能夠獲得使用Graphics2d繪制的網格的位置。 但是,我沒有找到任何解決方案,因此我想到了在每個矩形內用MouseListener繪制不可見的JLabel的想法。 但是,我無法使JLabel適合繪制的矩形。

之所以這樣做,是因為我要繪制多個組件,並且希望它們彼此堆疊。 因此,我不能使用任何組件,因為它們一次只能容納1張圖像。

目前,這是我正在使用的最低工作示例:

public class MainGui extends JFrame {

    public MainGui(int width, int height) {
        this.setTitle("Map Editor");
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        GuiGridPanel guiGridPanel = new GuiGridPanel(width, height);
        add(guiGridPanel.buildGuiGrid(), BorderLayout.CENTER);

        setSize(new Dimension(780,480));
        setLocationRelativeTo(null);
        setVisible(true);
    }
}

public class GuiGridPanel extends JPanel {
    private Graphics2D render;
    private int width;
    private int height;
    private JPanel gridPanel;
    private final int gridSize = 32;

    public GuiGridPanel(int width, int height){
        this.width = (width);
        this.height = (height);
        gridPanel = new JPanel(new GridLayout(height, width));
        buildLabels();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        render = (Graphics2D) g;
        drawMap();
    }

    public JScrollPane buildGuiGrid() {
        add(gridPanel);
        JScrollPane jScrollPane = new JScrollPane(this);
        jScrollPane.getVerticalScrollBar().setUnitIncrement(16);
        return jScrollPane;
    }

    private void buildLabels() {
        for(int x = 0; x < height; x++) {
            for (int y = 0; y < width; y++) {
                JLabel label = new JLabel("HERE");
                label.setBounds(x*gridSize, y*gridSize, gridSize, gridSize);
                gridPanel.add(label);
            }
        }
    }

    private void drawMap() {
        for(int x = 0; x < height; x++) {
            for(int y = 0; y < width; y++) {

                render.drawRect(x*gridSize, y*gridSize, gridSize, gridSize);
            }
        }
    }
}

用於測試目的。 我將“ Here”作為JLabel的名稱,以確保它們進入每個矩形內。 但是目前他們還沒有這樣做。 我嘗試修改JLabel的邊界,甚至將其布局管理器設置為null,以便可以自由放置它們,但無法使其正常工作。

謝謝

不會解決您的問題,但不應將變量“ render”變量定義為實例變量。

Graphics對象只能在paintComponent()方法或paintComponent(...)方法調用的方法中使用。

因此,該變量應在本地定義:

    //render = (Graphics2D) g;
    //drawMap();
    Graphics2D render = (Graphics2D) g;
    drawMap(render);

然后您更改drawMap(...)方法:

//private void drawMap() 
private void drawMap(Graphics2d render) 

編輯:

我希望它們彼此堆疊。 因此,我不能使用任何組件,因為它們一次只能容納1張圖像。

您可以將一個組件添加到另一個組件:

JLabel background = new JLabel(...);
background.setLayout( new BorderLayout() );
JLabel foreground = new Jlabel(...);
background.add( foreground );

然后,您可以在上面重復,然后將另一個組件添加到“前景”中。

另一種選擇是創建一個包含多個圖標的圖標。 請查看“ 復合圖標”以獲取此方法的示例。

另一種方法是創建BufferedImage並將所有圖像繪制在BufferedImage上。

您的問題確實不清楚。 我不知道這些圖像是動態變化還是固定的,因此很難提出一種方法。

在以下示例中, GridPainter呈現指定大小的網格,其中每個單元格均基於選擇狀態由藍色填充(請參見addMouseListener )。

public class MainFrame extends JFrame {
    public MainFrame() {
        GridPainter gp = new GridPainter(5,5);
        gp.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1) {
                    // onLeftButtonClick
                    gp.selectCell(e.getX(), e.getY()); 
                } else { 
                    // onWheelButton/RightButtonClick
                    gp.unselectCell(e.getX(), e.getY()); 
                }
            }
        });
        add(gp);
        setSize(new Dimension(500,500));
        setVisible(true);
    }
}

public class GridPainter extends JComponent {
    private final int rows;
    private final int columns;
    private boolean[][] isSelected; // selection state of cells

    public GridPainter(int rows, int columns) {
        this.rows = rows;
        this.columns = columns;
        isSelected = new boolean[rows][columns];
    }

    private int getRowSize() {return getHeight() / rows;}
    private int getColSize() {return getWidth() / columns;}

    private int[] resolveIndices(int x, int y) {
        int i = y / getRowSize();
        int j = x / getColSize();
        return new int[] {i, j};
    }

    public void selectCell(int x, int y) {
        int[] indices = resolveIndices(x, y);
        int i = indices[0];
        int j = indices[1];
        isSelected[i][j] = true;
        repaint();
    }
    public void unselectCell(int x, int y) {
        int[] indices = resolveIndices(x, y);
        int i = indices[0];
        int j = indices[1];
        isSelected[i][j] = false;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        int width = this.getWidth();
        int height = this.getHeight();

        // draw rows
        int rowSize = getRowSize();
        for (int i = 0; i < columns; i++) {
            int yOffset = i * rowSize;
            g2.drawLine(0, yOffset, width, yOffset);
        }

        // draw lines
        int colSize = getColSize();
        for (int j = 0; j < rows; j++) {
            int xOffset = j * colSize;
            g2.drawLine(xOffset, 0, xOffset, height);
        }

        // fill selected cells
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                if (isSelected[i][j]) {
                    Color oldColor = g2.getColor();
                    g2.setColor(Color.BLUE);
                    int x = j * colSize;
                    int y = i * rowSize;
                    int w = colSize;
                    int h = rowSize;
                    g2.fillRect(x, y, w, h);
                    g2.setColor(oldColor);
                }
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM