簡體   English   中英

在網格中單擊 position。 Java Swing

[英]Get click position in grid. Java Swing

我得到了這個代碼,它創建了一個可點擊的網格,顯示了鼠標 position,盡管我無法在單擊鼠標的網格中找到 position,試圖同時成為 X 和 Y Z4757FE07FD492A38BE0EA6A760EZ。 有任何想法嗎?

這是網格的外觀

代碼:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;

public class TestGrid02 {


public TestGrid02() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            }

            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new TestPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

public class TestPane extends JPanel {
    private static final int ROWS = 20;
    private static final int COLUMNS = 20;
    private static GridBagConstraints gbc;

    public TestPane() {
        setLayout(new GridBagLayout());

        gbc = new GridBagConstraints();
        for (int row = 0; row < ROWS; row++) {
            for (int col = 0; col < COLUMNS; col++) {
                gbc.gridx = col;
                gbc.gridy = row;
                CellPane cellPane = new CellPane();
                Border border = null;
                if (row < ROWS-1) {
                    if (col < COLUMNS-1) {
                        border = new MatteBorder(1, 1, 0, 0, Color.GRAY);
                    } else {
                        border = new MatteBorder(1, 1, 0, 1, Color.GRAY);
                    }
                } else {
                    border = new MatteBorder(1, 1, 1, 0, Color.GRAY);
                }
                cellPane.setBorder(border);
                add(cellPane, gbc);
            }
        }
    }
}

public class CellPane extends JPanel {

    private Color defaultBackground;

    public CellPane() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                defaultBackground = getBackground();
                setBackground(Color.RED);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                setBackground(defaultBackground);
            }
            @Override
            public void mouseClicked(MouseEvent e){
                //Here is where it is supposed to be
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(30, 30);
    }
}

在 CellPane class 中,女巫是用來聽鼠標的,它應該是我需要的 function,在 mouseClicked 監聽器中,但是我嘗試過使用 e.getX() 或 e.getLocationOnScreen()每次我在同一個網格中單擊時,這些值都會發生變化。

嗯,看起來很眼熟

因此,基本思想是通過構造函數將其坐標(即行/列)值傳遞給單元格,例如...

public class CellPane extends JPanel {

    private Color defaultBackground;
    
    private Point cellCoordinate;

    public CellPane(Point cellCoordinate) {
        this.cellCoordinate = cellCoordinate;
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                defaultBackground = getBackground();
                setBackground(Color.RED);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                setBackground(defaultBackground);
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                //Here is where it is supposed to be
                System.out.println("Did click cell @ " + getCellCoordinate().x + "x" + getCellCoordinate().y);
            }
        });
    }

    public Point getCellCoordinate() {
        return cellCoordinate;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(30, 30);
    }
}

單元格本身並不真正關心,它沒有任何合理的信息可用於確定其布局方式,因此您最好的選擇是“告訴”它您希望它代表的信息。

對我來說,我只需傳入GridBagLayout行/列信息,例如......

gbc.gridx = col;
gbc.gridy = row;
CellPane cellPane = new CellPane(new Point(col, row));

通過這種方式,您可以刪除單元格布局方式的所有概念(以及與之相關的問題)

這種方法(使用按鈕和動作監聽器)是更好的 IMO。 它使用getButtonRowCol方法返回一個字符串,該字符串指示按鈕在數組中的位置( buttonArray )。

在此處輸入圖像描述

使用b.setBorderPainted(false); (取消注釋該代碼行)以消除每個按鈕周圍的邊框。 查看傳遞給GridLayout的構造函數的值以刪除按鈕之間的空間。

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

public class GameGridLayout {

    int size = 40;
    int iconSize = 10;
    JButton[][] buttonArray = new JButton[size][size];
    ActionListener actionListener;
    JLabel output = new JLabel("Click somewhere on the GUI");

    GameGridLayout() {
        JPanel gui = new JPanel(new BorderLayout(2,2));
        gui.setBorder(new EmptyBorder(4,4,4,4));
        gui.add(output,BorderLayout.PAGE_END);
        JPanel gameContainer = new JPanel(new GridLayout(0,size,2,2));
        gui.add(gameContainer);
        actionListener = e -> output.setText(getButtonRowCol((JButton)e.getSource()));
        for (int ii=0; ii<size*size; ii++) {
            JButton b = getButton();
            gameContainer.add(b);
            buttonArray[ii%size][ii/size] = b;
        }
        JFrame f = new JFrame("GameGridLayout");
        f.add(gui);
        f.pack();
        f.setMinimumSize(f.getSize());
        f.setLocationByPlatform(true);
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setVisible(true);
    }

    private String getButtonRowCol(JButton button) {
        StringBuilder sb = new StringBuilder();
        for (int xx=0; xx<size; xx++) {
            for (int yy=0; yy<size; yy++) {
                if (button.equals(buttonArray[xx][yy])) {
                    sb.append("User selected button at: ");
                    sb.append(xx+1);
                    sb.append(",");
                    sb.append(yy+1);
                    break;
                }
            }
        }
        return sb.toString();
    }

    private JButton getButton() {
        JButton b = new JButton();
        b.setIcon(new ImageIcon(
                new BufferedImage(iconSize,iconSize,BufferedImage.TYPE_INT_ARGB)));
        b.setRolloverIcon(new ImageIcon(
                new BufferedImage(iconSize,iconSize,BufferedImage.TYPE_INT_RGB)));
        b.setMargin(new Insets(0,0,0,0));
        //b.setBorderPainted(false);
        b.setContentAreaFilled(false);
        b.addActionListener(actionListener);
        return b;
    }

    public static void main(String[] args) {
        Runnable r = () -> new GameGridLayout();
        SwingUtilities.invokeLater(r);
    }
}

暫無
暫無

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

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