在鼠标单击位置显示多个图像并一次移动一个图像

时间:2014-03-15 16:20:45

标签: java

我有多个代表玩家的图片。每个图像都存储在一个标签中,然后将其添加到JPanel中。然后我简单地将JPanel添加到JFrame以显示屏幕上的所有玩家。

我必须鼠标点击屏幕上的某个位置,然后将当前玩家的标签移动到该位置。

我在每个标签上添加了一个MouseListener事件,但我无法弄清楚如何一次关注一个标签,所以例如当我在窗口上单击鼠标时,当前标签移动到该位置,并且然后将焦点设置在另一个标签上,这样当我再次点击屏幕时,不同的标签移动。

1 个答案:

答案 0 :(得分:1)

例如:

// in main GUI
private JLabel activePiece = null;
private Player activePlayer = null;

// in JLabel's MouseListener
public void mousePressed(MouseEvent mEvt) {
   JLabel currentPiece = (JLabel) mEvt.getSource();
   if (activePlayer.holds(currentPiece)) {
      // they've pressed on one of the current Player's pieces
      activePiece = currentPiece;
   }
}

// in main GUI's MouseListener
public void mousePressed(MouseEvent mEvt) {
   if (activePlayer != null && activePiece != null) {
      activePiece.setLocation(mEvt.getPoint());
      activePlayer = //.... next active player;
      revalidate();
      repaint();
   }
}

例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

import javax.swing.*;
import javax.swing.border.Border;

@SuppressWarnings("serial")
public class PlayerMover extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = 650;
   private static final Border ACTIVE_BORDER = BorderFactory.createLineBorder(Color.RED);
   private static final Border INACTIVE_BORDER = BorderFactory.createLineBorder(Color.BLUE.brighter());

   private Player[] players = { new Player("John"), new Player("Bill"),
         new Player("Boudreaux"), new Player("Thibodeaux") };
   private int currentPlayerIndex = 0;
   private Player currentPlayer = players[currentPlayerIndex];
   private JTextField currentPlayerField = new JTextField(currentPlayer.getName(), 20);
   private JLabel currentPiece = null;
   private Random random = new Random();

   public PlayerMover() {
      currentPlayerField.setEditable(false);
      JPanel northPanel = new JPanel();
      northPanel.add(currentPlayerField);

      JPanel gamePanel = new JPanel(null) {
         @Override
         public Dimension getPreferredSize() {
            return new Dimension(PREF_W, PREF_H);
         }
      };
      PlayerLabelListener playerLabelListener = new PlayerLabelListener();
      for (Player player : players) {
         JLabel playerLabel = new JLabel(player.getName(), SwingConstants.CENTER);
         int labelW = playerLabel.getPreferredSize().width + 10;
         int labelH = playerLabel.getPreferredSize().height + 10;
         playerLabel.setSize(new Dimension(labelW, labelH));
         playerLabel.setOpaque(true);
         playerLabel.setBorder(INACTIVE_BORDER);
         int x = random.nextInt(PREF_W - playerLabel.getPreferredSize().width);
         int y = random.nextInt(PREF_H - playerLabel.getPreferredSize().height);
         playerLabel.setLocation(x, y);
         player.setPlayerLabel(playerLabel);
         playerLabel.addMouseListener(playerLabelListener);
         playerLabel.addMouseMotionListener(playerLabelListener);
         gamePanel.add(playerLabel);
      }

      currentPlayer.getPlayerLabel().setBorder(ACTIVE_BORDER);

      setLayout(new BorderLayout());
      add(northPanel, BorderLayout.NORTH);
      add(gamePanel, BorderLayout.CENTER);
   }

   public void nextPlayer() {
      currentPlayerIndex++;
      currentPlayerIndex %= players.length;
      currentPlayer = players[currentPlayerIndex];
      currentPlayerField.setText(currentPlayer.getName());
      currentPiece = null;

      for (Player player : players) {
         player.getPlayerLabel().setBorder(INACTIVE_BORDER);
      }

      currentPlayer.getPlayerLabel().setBorder(ACTIVE_BORDER);
   }

   private class PlayerLabelListener extends MouseAdapter {
      private Point pressLoc;

      @Override
      public void mousePressed(MouseEvent evt) {
         if (evt.getButton() != MouseEvent.BUTTON1) {
            return;
         }
         JLabel pressedPiece = (JLabel) evt.getSource();
         if (currentPlayer.holds(pressedPiece)) {
            currentPiece = pressedPiece;
            pressLoc = evt.getPoint();
         }
      }

      @Override
      public void mouseDragged(MouseEvent mEvt) {
         if (currentPiece == null) {
            return;
         }
         dragPiece(mEvt);
      }

      private void dragPiece(MouseEvent mEvt) {
         Container cont = currentPiece.getParent();
         int deltaX = mEvt.getLocationOnScreen().x - pressLoc.x - cont.getLocationOnScreen().x;
         int deltaY = mEvt.getLocationOnScreen().y - pressLoc.y - cont.getLocationOnScreen().y;

         currentPiece.setLocation(deltaX, deltaY);
         cont.revalidate();
         cont.repaint();
      }

      @Override
      public void mouseReleased(MouseEvent mEvt) {
         if (currentPiece == null) {
            return;
         }
         dragPiece(mEvt);
         nextPlayer();
      }
   }

   private static void createAndShowGui() {
      PlayerMover mainPanel = new PlayerMover();

      JFrame frame = new JFrame("PlayerMover");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

}

class Player {
   private String name;
   private JLabel playerLabel;

   public Player(String name) {
      this.name = name;
   }

   public boolean holds(JLabel label) {
      return label == playerLabel;
   }

   public String getName() {
      return name;
   }

   public JLabel getPlayerLabel() {
      return playerLabel;
   }

   public void setPlayerLabel(JLabel playerLabel) {
      this.playerLabel = playerLabel;
   }

}