Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 鼠标侦听器未在JLayeredPane中注册JScrollPane_Java_Swing_Jscrollpane_Mouselistener_Jlayeredpane - Fatal编程技术网

Java 鼠标侦听器未在JLayeredPane中注册JScrollPane

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

我正在从事一个涉及JSwing的项目。 该项目由一个JLayeredPane组成,其中包含一个JScrollPane和一个游戏板(JPanel和JPanels和JLabel)

我的问题是,我在JLayeredPane中添加了一个自定义鼠标侦听器。但是,当我单击JScrollPane区域时,侦听器似乎没有注册。但是,如果我单击其他位置,它会。 有人能解释为什么会发生这种情况吗

提前谢谢

创建面板并将侦听器添加到JLayeredPane的代码:

    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();
}