简体   繁体   English

无法在JPanel上移动JLabel

[英]Can't move JLabel on JPanel

Ok, so I am making a monopoly game. 好的,所以我正在做一个垄断游戏。 I so far have a JFrame , with a JPanel acting as a board. 到目前为止,我有一个JFrame ,其中一个JPanel用作板。 I have loaded all necessary images. 我已经加载了所有必要的图像。 I create a Player object which extends JLabel , to represent the player on the board. 我创建了一个扩展JLabelPlayer对象,以表示板上的玩家。

I am trying to set the location of (in hopes of moving pieces around the board) Player object (which is a JLabel ), on the board (which is a JPanel ). 我试图在板上(这是JPanel )设置Player对象(它是JLabel )的位置(希望在板上移动)。 I tried the .setLocation method, .setBounds method. 我尝试了.setLocation方法, .setBounds方法。

For some reason, no matter what i do the Player object only shows up on the top middle of the JPanel . 出于某种原因,无论我做什么, Player对象仅显示在JPanel的顶部中间。 I was wondering how I could move the Player object on my board. 我想知道如何在板上移动Player对象。

JFrame code (I attempt to move the JLabel in the bottom of the constructor): JFrame代码(我尝试将JLabel移动到构造函数的底部):

   package com.Game.Monopoly;

    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.Timer;

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.LayoutManager;
    import java.awt.Point;
    import java.awt.SystemColor;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.IOException;

    import net.miginfocom.swing.MigLayout;

    //a class that represent the board (JFrame) and all of it components 
    public class GameFrame extends JFrame {
        private final double SCALE;
        // all the graphical components
        private Board board;
        private JLabel lblPlayerMoney;
        private JLabel lblCurrentPlayer;
        private JLabel lblDice1;
        private JLabel lblDice2;
        private JList lstPropertiesList;
        private JButton btnEndTurn;
        private JButton btnBuyProperty;
        private JButton btnRollDice;

        // all images needed
        private ImageIcon imgDice1;
        private ImageIcon imgDice2;
        private ImageIcon imgDice3;
        private ImageIcon imgDice4;
        private ImageIcon imgDice5;
        private ImageIcon imgDice6;
        private ImageIcon icnAirplane;

        // all players
        private Player[] playerList;
        // all properties
        private Property[] propertiesList;

        public GameFrame(double scale) {
            // SCALE = scale;
            SCALE = 1;

            // set up the JFrame
            setResizable(true);
            setTitle("Monopoly");
            // etUndecorated(true);
            // set size to a scale of 1080p
            setSize((int) (1920 * SCALE), (int) (1080 * SCALE));
            setLayout(new MigLayout());
            loadImages();

            // add the components to the frame
            board = new Board(SCALE);
            board.setPreferredSize(new Dimension((int) (1024 * SCALE),
                    (int) (1024 * SCALE)));
            board.setBackground(Color.BLACK);
            add(board, "east, gapbefore 80");
            lblCurrentPlayer = new JLabel("Current Player:" + " Player 1");
            add(lblCurrentPlayer, "wrap");
            lblPlayerMoney = new JLabel("Player1's money:" + "$14000000");
            add(lblPlayerMoney, "wrap");
            lstPropertiesList = new JList();
            add(new JScrollPane(lstPropertiesList),
                    "span 2 2, grow, height 70:120:200");
            btnRollDice = new JButton("Roll Dice");
            add(btnRollDice, "wrap");
            lblDice1 = new JLabel(imgDice1);
            add(lblDice1);
            lblDice2 = new JLabel(imgDice1);
            add(lblDice2, "wrap");
            btnBuyProperty = new JButton("Buy Property");
            add(btnBuyProperty, "wrap, top");
            btnEndTurn = new JButton("End Turn");
            add(btnEndTurn, "aligny bottom");

            setUpEventListeners();
            loadProperties();

            // load players
            playerList = new Player[6];
            playerList[0] = new Player("Player 1", icnAirplane);

            // add Players to the board

            board.add(playerList[0]);
            playerList[0].setLocation(new Point(500, 230));
        }

        public static void main(String[] args) {
            GameFrame board = new GameFrame(1);
            board.setVisible(true);

        }

        // method to add event listeners
        public void setUpEventListeners() {

            // roll dice
            btnRollDice.addActionListener(new ActionListener() {
                // creates an object with an timers to help with rolling dice
                class RollDice implements ActionListener {
                    private Timer time = new Timer(152, this);
                    private int count = 0;

                    public void actionPerformed(ActionEvent e) {
                        count++;
                        if (count == 21)
                            time.stop();

                        int whatDice1 = (int) (Math.random() * 6) + 1;
                        int whatDice2 = (int) (Math.random() * 6) + 1;

                        // set the icons of the labels according to the random
                        // number

                        if (whatDice1 == 1)
                            lblDice1.setIcon(imgDice1);
                        else if (whatDice1 == 2)
                            lblDice1.setIcon(imgDice2);
                        else if (whatDice1 == 3)
                            lblDice1.setIcon(imgDice3);
                        else if (whatDice1 == 4)
                            lblDice1.setIcon(imgDice4);
                        else if (whatDice1 == 5)
                            lblDice1.setIcon(imgDice5);
                        else if (whatDice1 == 6)
                            lblDice1.setIcon(imgDice6);

                        if (whatDice2 == 1)
                            lblDice2.setIcon(imgDice1);
                        else if (whatDice2 == 2)
                            lblDice2.setIcon(imgDice2);
                        else if (whatDice2 == 3)
                            lblDice2.setIcon(imgDice3);
                        else if (whatDice2 == 4)
                            lblDice2.setIcon(imgDice4);
                        else if (whatDice2 == 5)
                            lblDice2.setIcon(imgDice5);
                        else if (whatDice2 == 6)
                            lblDice2.setIcon(imgDice6);
                    }

                    public void roll() {
                        count = 0;
                        time.start();
                    }
                }

                // create a new dice roll object
                RollDice roll = new RollDice();

                // if the roll dice button is clicked
                public void actionPerformed(ActionEvent arg0) {
                    roll.roll();
                }

            });

        }

        // load all images to memory
        public void loadImages() {
            BufferedImage i = null;
            try {
                i = ImageIO.read((getClass().getResource("/resources/Dice 1.png")));
                imgDice1 = new ImageIcon(i.getScaledInstance(100, 100,
                        java.awt.Image.SCALE_SMOOTH));

                i = ImageIO.read((getClass().getResource("/resources/Dice 2.png")));
                imgDice2 = new ImageIcon(i.getScaledInstance(100, 100,
                        java.awt.Image.SCALE_SMOOTH));

                i = ImageIO.read((getClass().getResource("/resources/Dice 3.png")));
                imgDice3 = new ImageIcon(i.getScaledInstance(100, 100,
                        java.awt.Image.SCALE_SMOOTH));

                i = ImageIO.read((getClass().getResource("/resources/Dice 4.png")));
                imgDice4 = new ImageIcon(i.getScaledInstance(100, 100,
                        java.awt.Image.SCALE_SMOOTH));

                i = ImageIO.read((getClass().getResource("/resources/Dice 5.png")));
                imgDice5 = new ImageIcon(i.getScaledInstance(100, 100,
                        java.awt.Image.SCALE_SMOOTH));

                i = ImageIO.read((getClass().getResource("/resources/Dice 6.png")));
                imgDice6 = new ImageIcon(i.getScaledInstance(100, 100,
                        java.awt.Image.SCALE_SMOOTH));

                i = ImageIO.read((getClass()
                        .getResource("/resources/Airplane Icon.png")));
                icnAirplane = new ImageIcon(i.getScaledInstance(40, 40,
                        java.awt.Image.SCALE_SMOOTH));

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        // load all properties
        public void loadProperties() {
            propertiesList = new Property[40];

            // set up the properties list
            // (name, index, isBuyable, price, initial rent)
            propertiesList[0] = new Property("Go", 0, false, 0, 0);
            propertiesList[1] = new Property("Jacob's Field", 1, true, 600000,
                    20000);
            propertiesList[2] = new Property("Community Chest", 2, false, 0, 0);
            propertiesList[3] = new Property("Texas Stadium", 3, true, 600000,
                    40000);
            propertiesList[4] = new Property("Income Tax", 4, false, 0, 0);
            propertiesList[5] = new Property("O'Hare International Airport", 5,
                    true, 2000000, 250000);
            propertiesList[6] = new Property("Grand Ole Opry", 6, true, 1000000,
                    60000);
            propertiesList[7] = new Property("Chance", 7, false, 0, 0);

        }
    }

JPanel Code: JPanel代码:

package com.Game.Monopoly;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class Board extends JPanel {
    private static final long serialVersionUID = 1L;
    private Image board;

    public Board(double scale) {
        this.setPreferredSize(new Dimension((int) (1024 * scale),
                (int) (1024 * scale)));

        BufferedImage i = null;
        try {
            i = ImageIO.read((getClass().getResource("/resources/monopoly-board-web.jpg")));

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        board = i.getScaledInstance((int) (1024 * scale), (int) (1024 * scale), java.awt.Image.SCALE_SMOOTH);

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(board, 0, 0, this);
    }

}

Player Object Code: Player目标代码:

package com.Game.Monopoly;

import javax.swing.ImageIcon;
import javax.swing.JLabel;

//a class representing a player with its graphical component 
public class Player extends JLabel {

    private String playerName;
    private int money;
    private Property[] propertiesOwned;

    public Player(String n, ImageIcon icon) {
        playerName = n;
        this.setIcon(icon);
    }

    // changes the amount of money available 
    public void changeMoney(int amount) {
        money = money + amount;
    }

    public void movePlayer(int x, int y){ 
        this.setLocation(x, y);
    }

}

There are a couple of ways you can achieve this, personally, the simplest would be to use custom painting directly and not bother with using Swing based components for the players. 就个人而言,有两种方法可以实现,最简单的方法是直接使用自定义绘画,而不必为播放器使用基于Swing的组件而烦恼。

The basic problem you have is JPanel uses a FlowLayout by default, which means that you will always be fighting layout manager. 您遇到的基本问题是, JPanel默认使用FlowLayout ,这意味着您将一直在与布局管理器作斗争。 In this case you might consider using a custom layout manager, for example... 在这种情况下,您可以考虑使用自定义布局管理器,例如...

垄断

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager2;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Monopoly {

    public static void main(String[] args) {
        new Monopoly();
    }

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

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

    public class MonopolyBoard extends JPanel {

        private List<JLabel> players;

        public MonopolyBoard() {
            setLayout(new MonopolyBoardLayout());

            players = new ArrayList<>(2);
            try {
                players.add(makePlayer("/Dog.png"));
                players.add(makePlayer("/Car.png"));

                for (JLabel player : players) {
                    add(player, new Integer(0));
                }
            } catch (IOException exp) {
                exp.printStackTrace();
            }

            Timer timer = new Timer(1000, new ActionListener() {
                private int count = 0;
                private Random rnd = new Random();

                @Override
                public void actionPerformed(ActionEvent e) {
                    int playerIndex = count % players.size();
                    JLabel player = players.get(playerIndex);

                    MonopolyBoardLayout layout = (MonopolyBoardLayout) getLayout();
                    int position = layout.getPosition(player);

                    position += rnd.nextInt(5) + 1;
                    if (position > 35) {
                        position -= 35;
                    }

                    layout.setPosition(player, position);

                    revalidate();
                    repaint();
                    count++;
                }
            });
            timer.start();
        }

        protected JLabel makePlayer(String path) throws IOException {
            JLabel label = new JLabel(new ImageIcon(ImageIO.read(getClass().getResource(path))), JLabel.CENTER);
            return label;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int width = getWidth();
            int height = getHeight();

            for (int index = 0; index < 36; index++) {
                Rectangle bounds = MonopolyBoardLayoutHelper.getCellBounds(index, width, height);
                g2d.draw(bounds);
            }

            g2d.dispose();
        }

    }

    public static class MonopolyBoardLayoutHelper {

        private static Map<Integer, Point> mapBoardCells;

        static {
            mapBoardCells = new HashMap<>(25);

            mapBoardCells.put(10, new Point(0, 8));
            mapBoardCells.put(11, new Point(0, 7));
            mapBoardCells.put(12, new Point(0, 6));
            mapBoardCells.put(13, new Point(0, 5));
            mapBoardCells.put(14, new Point(0, 4));
            mapBoardCells.put(15, new Point(0, 3));
            mapBoardCells.put(16, new Point(0, 2));
            mapBoardCells.put(17, new Point(0, 1));
            mapBoardCells.put(18, new Point(0, 0));

            mapBoardCells.put(0, new Point(9, 9));
            mapBoardCells.put(1, new Point(8, 9));
            mapBoardCells.put(2, new Point(7, 9));
            mapBoardCells.put(3, new Point(6, 9));
            mapBoardCells.put(4, new Point(5, 9));
            mapBoardCells.put(5, new Point(4, 9));
            mapBoardCells.put(6, new Point(3, 9));
            mapBoardCells.put(7, new Point(2, 9));
            mapBoardCells.put(8, new Point(1, 9));
            mapBoardCells.put(9, new Point(0, 9));

            mapBoardCells.put(19, new Point(1, 0));
            mapBoardCells.put(20, new Point(2, 0));
            mapBoardCells.put(21, new Point(3, 0));
            mapBoardCells.put(22, new Point(4, 0));
            mapBoardCells.put(23, new Point(5, 0));
            mapBoardCells.put(24, new Point(6, 0));
            mapBoardCells.put(25, new Point(7, 0));
            mapBoardCells.put(26, new Point(8, 0));
            mapBoardCells.put(27, new Point(9, 0));

            mapBoardCells.put(28, new Point(9, 1));
            mapBoardCells.put(29, new Point(9, 2));
            mapBoardCells.put(30, new Point(9, 3));
            mapBoardCells.put(31, new Point(9, 4));
            mapBoardCells.put(32, new Point(9, 5));
            mapBoardCells.put(33, new Point(9, 6));
            mapBoardCells.put(34, new Point(9, 7));
            mapBoardCells.put(35, new Point(9, 8));

        }

        public static Rectangle getCellBounds(int index, int width, int height) {
            Rectangle bounds = new Rectangle(0, 0, 0, 0);
            int size = Math.min(width, height);
            int cellSize = size / 10;

            int xOffset = (width - size) / 2;
            int yOffset = (height - size) / 2;

            Point point = mapBoardCells.get(index);
            if (point != null) {

                int x = xOffset + (point.x * cellSize);
                int y = yOffset + (point.y * cellSize);
                bounds = new Rectangle(x, y, cellSize, cellSize);

            }

            return bounds;

        }

    }

    public static class MonopolyBoardLayout implements LayoutManager2 {

        public static final int DEFAULT_CELL_SIZE = 64;

        private Map<Component, Integer> cellConstraints;

        public MonopolyBoardLayout() {
            cellConstraints = new HashMap<>(5);
        }

        public Integer getPosition(Component comp) {
            return cellConstraints.get(comp);
        }

        public void setPosition(Component comp, int position) {
            cellConstraints.put(comp, position);
        }

        @Override
        public void addLayoutComponent(Component comp, Object constraints) {
            if (constraints instanceof Integer) {
                int cell = (int) constraints;
                if (cell >= 0 && cell <= 35) {
                    cellConstraints.put(comp, cell);
                } else {
                    throw new IllegalArgumentException(constraints + " is not within the bounds of a valid cell reference (0-35)");
                }
            } else {
                throw new IllegalArgumentException(constraints + " is not a valid cell reference (integer within 0-35)");
            }
        }

        @Override
        public Dimension maximumLayoutSize(Container target) {
            return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10);
        }

        @Override
        public float getLayoutAlignmentX(Container target) {
            return 0.5f;
        }

        @Override
        public float getLayoutAlignmentY(Container target) {
            return 0.5f;
        }

        @Override
        public void invalidateLayout(Container target) {
        }

        @Override
        public void addLayoutComponent(String name, Component comp) {
        }

        @Override
        public void removeLayoutComponent(Component comp) {
            cellConstraints.remove(comp);
        }

        @Override
        public Dimension preferredLayoutSize(Container parent) {
            return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10);
        }

        @Override
        public Dimension minimumLayoutSize(Container parent) {
            return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10);
        }

        @Override
        public void layoutContainer(Container parent) {
            int width = parent.getWidth();
            int height = parent.getHeight();

            Map<Integer, List<Component>> components = new HashMap<>(25);

            for (Component child : parent.getComponents()) {
                Integer cell = cellConstraints.get(child);
                if (cell != null) {
                    List<Component> children = components.get(cell);
                    if (children == null) {
                        children = new ArrayList<>(4);
                        components.put(cell, children);
                    }
                    children.add(child);
                } else {
                    child.setBounds(0, 0, 0, 0);
                }
            }

            for (Map.Entry<Integer, List<Component>> entry : components.entrySet()) {
                int index = entry.getKey();
                Rectangle bounds = MonopolyBoardLayoutHelper.getCellBounds(index, width, height);
                List<Component> comp = entry.getValue();
                int xDelta = 0;
                int yDelta = 0;
                int availableWidth = bounds.width;
                int availableHeight = bounds.height;
                switch (comp.size()) {
                    case 2:
                        availableWidth /= 2;
                        xDelta = availableWidth;
                        break;
                    case 3:
                    case 4:
                        availableWidth /= 2;
                        xDelta = availableWidth;
                        availableHeight /= 2;
                        yDelta = availableHeight;
                        break;
                }
                int x = bounds.x;
                int y = bounds.y;
                for (int count = 0; count < comp.size() && count < 4; count++) {
                    Component child = comp.get(count);
                    child.setSize(availableWidth, availableHeight);
                    child.setLocation(x, y);

                    x += xDelta;
                    if (x >= bounds.x + bounds.width) {
                        x = bounds.x;
                        y += yDelta;
                    }
                }
            }

        }

    }

}

As you can see, this becomes real complicated real quick. 如您所见,这很快变得非常复杂。 This example currently only allows 4 players per cell, so if you want more, then you're going to have to create your own algorithim 此示例当前每个单元只允许4个玩家,因此,如果您需要更多的玩家,则必须创建自己的算法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM