gpt4 book ai didi

java - 如何在面板内创建网格(带有网格线),并让鼠标监听器在单击任何网格单元格时给出相对于面板的坐标?

转载 作者:行者123 更新时间:2023-12-01 11:45:00 24 4
gpt4 key购买 nike

我希望使下面的代码生成的网格报告单击时鼠标指针相对于 pnlGrid 的位置的 x 和 y 坐标。但无论我单击什么位置(在添加 JLayeredPane 之前),除了鼠标指针位于红色区域时之外,我都没有得到任何坐标。

因此,我添加了几行代码来制作 JLayeredPane,并且获得了鼠标坐标输出,但没有网格线,如第二个屏幕截图所示。

当单击网格中的任何位置时,如何获取网格线和鼠标坐标报告?

enter image description here

package gridcellcoordinator;
import gbl.GBConstraints;
import static java.awt.Color.*;
import java.awt.Color;
import java.awt.Dimension;
import static java.awt.EventQueue.invokeLater;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import static javax.swing.JLayeredPane.DEFAULT_LAYER;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.event.MouseInputAdapter;

public class GridCellCoordinator {

final static int
GRID_PANEL_BORDER_WIDTH = 5,
N = 11,
CELLSIZE = 40;

//static final JLayeredPane layer = new JLayeredPane();
static final JPanel panel = new JPanel();
static final int SM_CELL_BORDER_WIDTH = 1;
static LineBorder SMcellBorder = new LineBorder(BLACK,SM_CELL_BORDER_WIDTH);

static JTextField[][] cells = new JTextField[N][N];

static JFrame frame = new JFrame();
public GridCellCoordinator(){
makeGrid();
}

private void makeGrid(){
JPanel pnlGrid = new JPanel();
pnlGrid.setLayout(new GridLayout(N,N));
pnlGrid.setBackground(BLUE);
pnlGrid.setBorder(BorderFactory.createLineBorder(Color.red,GRID_PANEL_BORDER_WIDTH));
pnlGrid.setLayout(new GridLayout(N, N));

for(int i = 0 ; i < N ; i++)
for(int j = 0; j < N; j++){
cells[i][j] = new JTextField();
cells[i][j].setText("X");
cells[i][j].setPreferredSize(new Dimension(CELLSIZE,CELLSIZE));
cells[i][j].setHorizontalAlignment(JTextField.CENTER);
cells[i][j].setFocusTraversalKeysEnabled(false);
cells[i][j].setBorder(SMcellBorder);
cells[i][j].setOpaque(true);
pnlGrid.add(cells[i][j], new GBConstraints());
}

panel.addMouseListener(new MouseInputAdapter()
{
public void mousePressed (MouseEvent e){panelMousePressed (e);}
});

pnlGrid.setPreferredSize(new Dimension(N*(CELLSIZE + 1) + 2*GRID_PANEL_BORDER_WIDTH ,
N*(CELLSIZE + 1) + 2*GRID_PANEL_BORDER_WIDTH));
panel.add(pnlGrid);
panel.setVisible(true);
panel.setOpaque(true);
panel.setPreferredSize(pnlGrid.getPreferredSize());
panel.setVisible(true);
//layer.add(pnlGrid, DEFAULT_LAYER);
//layer.setPreferredSize(pnlGrid.getPreferredSize());
//layer.setVisible(true);
frame.add(panel);
frame.setSize(new Dimension(pnlGrid.getPreferredSize()));
frame.setVisible(true);
frame.pack();
System.out.println("pnlGrid component count: " + pnlGrid.getComponentCount());
System.out.println("computed dimension: " + (N*(CELLSIZE + 1) + 2*GRID_PANEL_BORDER_WIDTH));
System.out.println("pnlGrid pref size: " + pnlGrid.getPreferredSize());
System.out.println("layer pref size: " + layer.getPreferredSize());
System.out.println("panel pref size: " + panel.getPreferredSize());
}

public void panelMousePressed(MouseEvent e){
JOptionPane.showMessageDialog(null,"Pressed:" + e.getX() + " " + e.getY());
}

public static void main(String[] args) {
invokeLater(new Runnable() {
public void run() {
new GridCellCoordinator();
}
});
}

}

附注照原样,代码在左侧生成网格,但仅给出红色边框内的坐标。去掉4层线上的注释栏可以得到坐标,但没有网格线。我想要网格线和坐标。

最佳答案

您可以使用类似 this 的内容或this

但是,要修复代码,您需要改变焦点。您不需要将 MouseListener 附加到 pnlGrid,而是需要将其附加到文本字段。原因是鼠标事件就像雨滴,任何附加了 MouseListener 的组件都会像一把雨伞一样,防止 MouseEvents 发生在视觉上位于其下方的组件上

要将 MouseEvent 从一个组件上下文转换为另一个组件上下文,您可以使用 SwingUtilities.convertMouseEventSwingUtilities.convertPoint

例如...

import java.awt.Color;
import static java.awt.Color.BLACK;
import static java.awt.Color.BLUE;
import java.awt.Dimension;
import static java.awt.EventQueue.invokeLater;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class GridCellCoordinator {

final static int GRID_PANEL_BORDER_WIDTH = 5,
N = 11,
CELLSIZE = 40;

//static final JLayeredPane layer = new JLayeredPane();
static final JPanel panel = new JPanel();
static final int SM_CELL_BORDER_WIDTH = 1;
static LineBorder SMcellBorder = new LineBorder(BLACK, SM_CELL_BORDER_WIDTH);

static JTextField[][] cells = new JTextField[N][N];

static JFrame frame = new JFrame();

public GridCellCoordinator() {
makeGrid();
}

private void makeGrid() {
JPanel pnlGrid = new JPanel();
pnlGrid.setLayout(new GridLayout(N, N));
pnlGrid.setBackground(BLUE);
pnlGrid.setBorder(BorderFactory.createLineBorder(Color.red, GRID_PANEL_BORDER_WIDTH));
pnlGrid.setLayout(new GridLayout(N, N));

MouseListener mouseHandler = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
doMousePressed(e);
}
};

for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cells[i][j] = new JTextField() {
@Override
public Dimension getPreferredSize() {
return new Dimension(20, 20);
}
};
cells[i][j].setText("X");
cells[i][j].setPreferredSize(new Dimension(CELLSIZE, CELLSIZE));
cells[i][j].setHorizontalAlignment(JTextField.CENTER);
cells[i][j].setFocusTraversalKeysEnabled(false);
cells[i][j].setBorder(SMcellBorder);
cells[i][j].addMouseListener(mouseHandler);
pnlGrid.add(cells[i][j]);
}
}
panel.add(pnlGrid);
panel.setVisible(true);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}

public void doMousePressed(MouseEvent e) {
Point p = e.getPoint();
System.out.println("Source point = " + p + " within " + e.getComponent());
p = SwingUtilities.convertPoint(e.getComponent(), p, e.getComponent().getParent());
System.out.println("Converted point = " + p + " within " + e.getComponent().getParent());
}

public static void main(String[] args) {
invokeLater(new Runnable() {
public void run() {
new GridCellCoordinator();
}
});
}

}

您应该避免使用setPreferredSize,并在需要时更多地依赖getPreferredSize。请参阅Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?了解更多详情

关于java - 如何在面板内创建网格(带有网格线),并让鼠标监听器在单击任何网格单元格时给出相对于面板的坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29221232/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com