Java 鼠标侦听器未在JLayeredPane中注册JScrollPane
我正在从事一个涉及JSwing的项目。 该项目由一个JLayeredPane组成,其中包含一个JScrollPane和一个游戏板(JPanel和JPanels和JLabel) 我的问题是,我在JLayeredPane中添加了一个自定义鼠标侦听器。但是,当我单击JScrollPane区域时,侦听器似乎没有注册。但是,如果我单击其他位置,它会。 有人能解释为什么会发生这种情况吗 提前谢谢 创建面板并将侦听器添加到JLayeredPane的代码:Java 鼠标侦听器未在JLayeredPane中注册JScrollPane,java,swing,jscrollpane,mouselistener,jlayeredpane,Java,Swing,Jscrollpane,Mouselistener,Jlayeredpane,我正在从事一个涉及JSwing的项目。 该项目由一个JLayeredPane组成,其中包含一个JScrollPane和一个游戏板(JPanel和JPanels和JLabel) 我的问题是,我在JLayeredPane中添加了一个自定义鼠标侦听器。但是,当我单击JScrollPane区域时,侦听器似乎没有注册。但是,如果我单击其他位置,它会。 有人能解释为什么会发生这种情况吗 提前谢谢 创建面板并将侦听器添加到JLayeredPane的代码: private void initPanels
private void initPanels() {
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setLayout(new BorderLayout());
layeredPane.add(makeBoardPanel(), BorderLayout.CENTER, JLayeredPane.DEFAULT_LAYER);
JPanel panel = new JPanel(new BorderLayout());
panel.add(makeButtonPanel(), BorderLayout.WEST);
panel.add(makeDeckPanel(), BorderLayout.EAST);
layeredPane.add(panel, BorderLayout.SOUTH, JLayeredPane.DEFAULT_LAYER);
layeredPane.add(makeMeeplePanel(), BorderLayout.NORTH, JLayeredPane.DEFAULT_LAYER);
//TODO: fix adapter + add others;
TileMouseAdapter tileMouseAdapter = new TileMouseAdapter(layeredPane);
layeredPane.addMouseListener(tileMouseAdapter);
layeredPane.addMouseMotionListener(tileMouseAdapter);
add(layeredPane);
myController.reset(TileDeck.getDemo(), NUM_PLAYERS); //sets up game
}
使用JScrollPane制作电路板的代码:
private JScrollPane makeBoardPanel() {
JScrollPane scrollPane = new JScrollPane(CarcassoneBoard.getInstance());
CarcassoneBoard.getInstance().setScrollPane(scrollPane);
return scrollPane;
}
下面是最后一行的代码(myController.reset(…)
听众似乎在黑板上记录了点击,这让我相信
它与JScrollPane有关。我通过将print语句放在mousePressed方法头之后来确定这一点。当我点击黑板时,它在抱怨我引用了一个代码中不存在的JScrollPane之前打印了一条语句://请显示一个演示问题的SSCCE。要更快地获得更好的帮助,请发布一个。
public void reset(Map<TileFactory, Integer> deck, int numPlayers) {
myDeck.reset(deck);
myBoard.reset(myDeck.getDeckSize()); //only panel contained in JScrollPane
myMeeplePanel.reset(numPlayers);
}
public void reset(int num_tiles) {
super.removeAll();
NUM_TILES = num_tiles;
BOARD_SIZE = (int) Math.ceil(num_tiles / 2.0);
setLayout(new GridLayout(BOARD_SIZE, BOARD_SIZE, 1, 1));
setPreferredSize(new Dimension(BOARD_SIZE * TILE_WIDTH, BOARD_SIZE * TILE_HEIGHT));
STARTING_TILE = new BubbleCity((int) Math.ceil(BOARD_SIZE / 2.0 - 1), (int) Math.ceil(BOARD_SIZE / 2.0 - 1));
myTiles = new TilePanel[BOARD_SIZE][BOARD_SIZE];
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
myTiles[i][j] = new TilePanel(i, j, new EmptyTile(i, j));
add(myTiles[i][j]);
}
}
myTiles[STARTING_TILE.getRow()][STARTING_TILE.getCol()].setTile(STARTING_TILE);
revalidate();
repaint();
}
public class TileMouseAdapter extends MouseAdapter {
private JLayeredPane myLayeredPane;
private Tile myTile;
private TilePanel myClickedPanel;
public TileMouseAdapter(JLayeredPane layeredPane) {
myLayeredPane = layeredPane;
}
private void reset() {
if (myTile != null) {
myLayeredPane.remove(myTile);
myLayeredPane.revalidate();
myLayeredPane.repaint();
}
myTile = null;
myClickedPanel = null;
}
//point p is a point relative to myLayeredPane...
public Point translatePoint(Component component, Point p) {
return SwingUtilities.convertPoint(myLayeredPane, p, component);
}
//point p is relative to the screen (event.getLocationOnScree()). We want to check if that point is in component.
public boolean containsPoint(Component component, Point p) {
Point translated = translatePoint(component, p );
return translated.getX() > 0 && translated.getY() > 0
&& translated.getX() < component.getWidth() && translated.getY() < component.getHeight();
}
@Override
public void mouseClicked(MouseEvent event) {
}
@Override
public void mousePressed(MouseEvent event) {
//no registering jscrollpane?
CarcassoneBoard board = CarcassoneBoard.getInstance();
TileDeck deck = TileDeck.getInstance();
System.out.println("pressed!");
if (containsPoint(deck, event.getPoint())) {
System.out.println("deck");
myClickedPanel = deck;
myTile = myClickedPanel.getTile();
}
else if (containsPoint(board.getScrollPane().getViewport(), event.getPoint())) {
System.out.println("board");
Component component = board.getComponentAt(translatePoint(board.getScrollPane().getViewport(), event.getPoint()));
if (component instanceof CarcassoneBoard) {return;} //user clicked in between tiles...do nothing.
myClickedPanel = (TilePanel) component;
myTile = myClickedPanel.getTile();
}
if (myTile == null || myTile instanceof EmptyTile || !myTile.isDraggable()) {
//TODO: scroll with drag!
reset();
return;
}
myClickedPanel.setEmpty(); //panel will set an empty tile automatically and remove myTile...
int x = event.getPoint().x - myTile.getWidth() / 2;
int y = event.getPoint().y - myTile.getHeight() / 2;
myTile.setLocation(x, y);
myLayeredPane.revalidate();
myLayeredPane.repaint();
try {
myLayeredPane.add(myTile, JLayeredPane.DRAG_LAYER);
myLayeredPane.revalidate();
myLayeredPane.repaint();
} catch (IllegalArgumentException e) {
//TODO: deal with this?
//gives error for some unknown reason, but doesnt effect anything? ignore...dumb error cus jswing sucks
}
}
@Override
public void mouseDragged(MouseEvent event) {
if (myTile == null) {
return;
}
int x = event.getPoint().x - myTile.getWidth() / 2;
int y = event.getPoint().y - myTile.getHeight() / 2;
myTile.setLocation(x, y);
myLayeredPane.revalidate();
myLayeredPane.repaint();
}
@Override
public void mouseReleased(MouseEvent event) {
if (myTile == null) {// || !myTile.isDraggable()) {
return; //do nothing...board scrolling
}
CarcassoneBoard board = CarcassoneBoard.getInstance();
myLayeredPane.remove(myTile);
TilePanel dropped = (TilePanel) board.getComponentAt(translatePoint(board.getScrollPane().getViewport(), event.getPoint()));
if (dropped == null) {
//reset tile to original spot
myClickedPanel.setTile(myTile);
reset();
return;
}
dropped.setTile(myTile);
reset();
}
}
private JPanel makeBoardPanel() {
return CarcassoneBoard.getInstance();
}