java - 如何在屏幕上移动 jlabel 图像?

标签 java swing jpanel

我想单击屏幕并使角色移动到该目的地。不是立即,而是“步行”到给定的坐标。目前我正在使用 JLabels,如果我只使用静态图像,它们就很好,但每次我单击屏幕上的某个位置时,图像都会在该位置显示。有人可以给我一些建议吗?

编辑:我应该重写绘画类并以这种方式绘制一些项目吗?

这是一些代码:

package mod;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.awt.KeyboardFocusManager;


import javax.imageio.ImageIO;
import javax.swing.*;

public class Board2 extends JPanel  {

private Thread animator;
int x, y;
double ix, iy;
double dx, dy;
final int frameCount = 8;
BufferedImage flower;
private int[][] fPos = {{232, 15},{400, 200},{335, 335}}; // flower coordinates 
private static int bWIDTH = 800; // width of window 
private static int bHEIGHT = 600;// height of window
private Font font;
private FontMetrics metrics;

ImageIcon grassI = new ImageIcon(this.getClass().getResource("grass.png"));
ImageIcon riverI = new ImageIcon(this.getClass().getResource("river.png"));
private Image grass = grassI.getImage();
private Image river = riverI.getImage();

private House house = new House();
private River river1 = new River();
//private Flower flower = new Flower(); 
private TitleScreenLayer ts = new TitleScreenLayer();
private Player girlP = new Player();
private static int px = 250;
private static int py = 250;
private boolean visTl = false;
private boolean plant = false;
ArrayList<Flower> flowers= new ArrayList<Flower>();
private long period;

private volatile boolean running = false;
private volatile boolean gameOver = false;
private volatile boolean isPaused = false;

// New stuff for Board2 below

private JLayeredPane lpane;
private JLabel grassLabel;
private JLabel riverLabel;
private JLabel houseLabel;
private JLabel pear1Label;
private JLabel pear2Label;
private JLabel pear3Label;
private JLabel drivewayLabel;
private JLabel girlLabel;
private JProgressBar progressBar;
private JLabel toolLabel;
private JTextArea textBubble;

ImageIcon girlImage = new ImageIcon(girlP.getImage());

int mouseClicks = 0;

CountdownTimer cTimer;

private static String message;

public static String setMessage(String newMessage){
    return message = newMessage;
}

private static ImageIcon playerTool = new ImageIcon("BradfordPear.png");

public ImageIcon getPlayerTool(){
    return playerTool;
}

public static void setPlayerTool(String image){
    playerTool = new ImageIcon(image);
}

public JTextArea getTextBubble(){
    return textBubble;
}

public Player getPlayer(){
    return girlP;
}

public static int getPlayerX(){
    return px;
}

public static int getPlayerY(){
    return py;
}

public JLayeredPane getLayeredPane(){
    return lpane;
}

public Board2(){
    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

    //create the layered pane
    lpane = new JLayeredPane();
    lpane.setPreferredSize(new Dimension(800, 600));

    //create the "background" image
    ImageIcon image = new ImageIcon("grass.png");
    grassLabel = new JLabel(image);
    grassLabel.setBounds(0, 0, image.getIconWidth(), image.getIconHeight());

    //create the house image
    ImageIcon houseImage = new ImageIcon("house.png");
    houseLabel = new JLabel(houseImage);
    houseLabel.setBounds(-330, -150, image.getIconWidth(), image.getIconHeight());

    //create the driveway image
    ImageIcon drivewayImage = new ImageIcon("driveway.png");
    drivewayLabel = new JLabel(drivewayImage);
    drivewayLabel.setBounds(-335, 105, image.getIconWidth(), image.getIconHeight());


    //create the river image
    ImageIcon riverImage = new ImageIcon("river.png");
    riverLabel = new JLabel(riverImage);
    riverLabel.setBounds(360, 0, image.getIconWidth(), image.getIconHeight());

    //create pear1 image
    ImageIcon pear1Image = new ImageIcon("BradfordPear.png");
    pear1Label = new JLabel(pear1Image);
    pear1Label.setBounds(100, 100, image.getIconWidth(), image.getIconHeight());

    //create pear2 image
    ImageIcon pear2Image = new ImageIcon("BradfordPear.png");
    pear2Label = new JLabel(pear2Image);
    pear2Label.setBounds(50, -100, image.getIconWidth(), image.getIconHeight());

    //create pear3 image
    ImageIcon pear3Image = new ImageIcon("BradfordPear.png");
    pear3Label = new JLabel(pear3Image);
    pear3Label.setBounds(-100, -50, image.getIconWidth(), image.getIconHeight());

    //create initial Player(girl) image
    //ImageIcon girlImage = new ImageIcon(girlP.getImage());
    girlLabel = new JLabel(girlImage);
    girlLabel.setBounds((int)girlP.getPositionX(), (int)girlP.getPositionY(), image.getIconWidth(), image.getIconHeight());

    //create progress bar
    progressBar = new JProgressBar(JProgressBar.VERTICAL, 0, 10);
    progressBar.setValue(0);
    progressBar.setBounds(720, 50, 100, 500);

    //create timer
    JTextField timerField = new JTextField();
    cTimer = new CountdownTimer(timerField);
    timerField.setBounds(400, 0, 50, 50);

    //create toolbox
    Toolbox toolbox = new Toolbox();
    toolbox.setBounds(550, 0, 250, 50);

    //create the text bubble
    textBubble = new JTextArea("IDPC is the best coding group ever");
    textBubble.setLineWrap(true);
    //textBubble.setBounds(200, 200, 100, 100);

    //add the background & various images
    lpane.add(grassLabel, new Integer(1));
    lpane.add(houseLabel, new Integer(2));
    lpane.add(riverLabel, new Integer(2));
    lpane.add(drivewayLabel, new Integer(2));
    lpane.add(pear1Label, new Integer(2));
    lpane.add(pear2Label, new Integer(2));
    lpane.add(pear3Label, new Integer(2));
    lpane.add(progressBar, new Integer(3));
    lpane.add(girlLabel, new Integer(3));
    lpane.add(timerField, new Integer(2));
    lpane.add(toolbox, new Integer(3));


    add(lpane);

    cTimer.start();
    // listen for action events
    new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            girlP.move();
            //girlLabel.setLocation(px, py);
        }
    };

    // listen for mouse presses
    addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            //lpane.remove(textBubble);
            mouseClicks+= 1;
            testPress(e.getX(), e.getY());
            //textBubble.setBounds(e.getX(), e.getY(), 40, 40);
            updateProgressBar();
        }
    });

    //listen for player action
    addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            if(e.getClickCount() == 2){
                ImageIcon flowerImage = playerTool;
                JLabel flowerPanel = new JLabel(flowerImage);
                flowerPanel.setBounds((px -((int)girlP.getPositionX() / 2)), 
                        (py - ((int)girlP.getPositionY() / 2)),
                        flowerImage.getIconWidth(),
                        flowerImage.getIconHeight());
                lpane.add(flowerPanel, new Integer(3));
                textBubble.setBounds(e.getX(), e.getY(), 200, 40);
                textBubble.replaceSelection(message);
                lpane.add(textBubble, new Integer(3));
                //lpane.remove(textBubble);
            }
        }
    });

    x = 15;
    y = 150;
    ix = 0;
    iy = 0;
    dx = .05;
    dy = .05;
    girlP.setDestination(px, py);

}

public void testPress(int x, int y){
    px = x;
    py = y;

    if (px < (ix + house.getImage().getWidth(this))
            && (py < (iy + house.getImage().getHeight(this)))) {
        px = px + (house.getImage().getWidth(this)/3);
        py = py + (house.getImage().getHeight(this)/3);

    }
    if (px > (bWIDTH - river1.getImage().getWidth(this))) {
        px = px - 80 - (river1.getImage().getWidth(this)/2);

    }

    girlLabel.setBounds((px -((int)(girlP.getPositionX()*2.5))), 
            (py - ((int)(girlP.getPositionY()*2.5))), 
            girlImage.getIconWidth(), girlImage.getIconHeight());

    girlP.setDestination((px-(girlP.getImage().getWidth(this)/2)), 
            (py-(girlP.getImage().getHeight(this)/2)));
    girlP.pinned(x, y);

}

public void updateProgressBar(){
    if(progressBar.getValue() == 3){
        //progressBar.setBackground(Color.red);
        //UIManager.put("progressBar.foreground", Color.RED);
        UIDefaults defaults = new UIDefaults();
        defaults.put("progressBar[Enabled].foregroundPainter", Color.RED);
            progressBar.putClientProperty("Nimbus.Overrides.InheritDefaults",     Boolean.TRUE);
        progressBar.putClientProperty("Nimbus.Overrides", defaults);
    }
    progressBar.setValue(mouseClicks);
}

/**
 * Create the GUI and show it.  For thread safety,
 * this method should be invoked from the
 * event-dispatching thread.
 */
private static void createAndShowGUI() {
    //Create and set up the window.
    JFrame frame = new JFrame("Game");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Create and set up the content pane.
    JComponent newContentPane = new TitleScreenLayer();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.setContentPane(newContentPane);


    //Display the window.
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}

}

这是玩家类别:

package mod;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.ImageObserver;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.*;

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

public class Player {
int tile;
double positionX;
double positionY;
int destinationX;//Used when moving from place to place
int destinationY;
Tool currentTool;
int direction; //Position the image is facing
double dx;
double dy;
int [] pin = new int[10];
private String girl = "girl.png";
ImageIcon ii = new ImageIcon(this.getClass().getResource(girl)); // load girl         image 
private Image image = ii.getImage();

private boolean visible = true;
public boolean plant = false;

Image playerImage;




public double getPositionX() {
    return positionX;
}

public void setPositionX(double positionX) {
    this.positionX = positionX;
}

public double getPositionY() {
    return positionY;
}

public void setPositionY(double positionY) {
    this.positionY = positionY;
}

public Player(){
    positionX=30;
    positionY=20;
    dx = 0.2;
    dy = 0.2;
    destinationX=(int)positionX;
    destinationY=(int)positionY;

    //this.playerImage=playerImage;
}

public void doAction() {
    //currentTool.getNum();
    plant = true;
}

public void pinned(int x, int y) {
    if (plant == true) {
        pin[0] = x;
        pin[1] = y;
    }

    //plant = false;

}

public void plant(Graphics g, ImageObserver io) {
    int x = pin[0];
    int y = pin[1];
    if (plant == true) {
//          g.drawImage(flower.getImage(), x, y, io);
    }

}

public void ActionPerformed(ActionEvent e) {
    positionX += dx;
    positionY += dy;
}

public boolean isVisible() {
    return visible;
}

public void setVisible(Boolean visible) {
    this.visible = visible;
}

public Image getImage() {
    return image;
}

public void move(){
    //MOVE LEFT AND RIGHT
    if(destinationX<positionX){
        positionX-=dx;
    }
    if(destinationX>positionX){
        positionX+=dx;
    }

    //MOVE UP AND DOWN
    if(destinationY<positionY){
        positionY-=dy;
    }
    if(destinationY>positionY){
        positionY+=dy;
    }
}

public double setDx(double speed) {
    dx = speed;

    return dx;
}

public double setDy(double speed) {
    dy = speed;

    return dy;
}
public void TileIn(int px, int py)
{
    px=destinationX;
    py=destinationY;
    int tileX=1;
    int tileY = 1;
    int bWIDTH=800;
    int bHEIGHT=600;
    if(px >= 0 && px <= 800*.1)
    {
        tileX=2;
    }
    else if(px> bWIDTH*.1 && px <= bWIDTH*.2)
    {
        tileX=3;
    }
    else if(px > bWIDTH*.2 && px <= bWIDTH*.3)
    {
        tileX=4;
    }
    else if(px > bWIDTH*.3 && px <= bWIDTH*.4)
    {
        tileX=5;
    }
    else if(px > bWIDTH*.4 && px <= bWIDTH*.5)
    {
        tileX=6;
    }
    else if(px > bWIDTH*.5 && px <= bWIDTH*.6)
    {
        tileX=7;
    }
    else if(px > bWIDTH*.6 && px <= bWIDTH*.7)
    {
        tileX=8;
    }
    else if(px > bWIDTH*.7 && px <= bWIDTH*.8)
    {
        tileX=9;
    }
    else if(px > bWIDTH*.8 && px <= bWIDTH*.9)
    {
        tileX=10;
    }
    else if(px > bWIDTH*.9 && px <= bWIDTH)
    {
        tileX=11;
    }
    if(py >= 0 && py <= bHEIGHT*.1)
    {
        tileY=2;
    }
    else if(py> bHEIGHT*.1 && py <= bHEIGHT*.2)
    {
        tileY=3;
    }
    else if(py > bHEIGHT*.2 && py <= bHEIGHT*.3)
    {
        tileY=4;
    }
    else if(py > bHEIGHT*.3 && py <= bHEIGHT*.4)
    {
        tileY=5;
    }
    else if(py > bHEIGHT*.4 && py <= bHEIGHT*.5)
    {
        tileY=6;
    }
    else if(py > bHEIGHT*.5 && py <= bHEIGHT*.6)
    {
        tileY=7;
    }
    else if(py > bHEIGHT*.6 && py <= bHEIGHT*.7)
    {
        tileY=8;
    }
    else if(py > bHEIGHT*.7 && py <= bHEIGHT*.8)
    {
        tileY=9;
    }
    else if(py > bHEIGHT*.8 && py <= bHEIGHT*.9)
    {
        tileY=10;
    }
    else if(py > bHEIGHT*.9 && py <= bHEIGHT)
    {
        tileY=11;
    }
    System.out.println("Grid X: " + tileX + " Grid Y: " + tileY);
}

public void setDestination(int x, int y){
    destinationX=x;
    destinationY=y;
    System.out.println(x + "," + y);
    TileIn(x,y);
}
//  public void tileIn(int a)
//  {
//      
//      b=destinationY;
//      return TileIn(x,y)
//  }



public void draw(Graphics g,ImageObserver io){
    g.drawImage(image, (int)positionX,(int) positionY,io);
}



}

这是主类:

package mod;
import java.awt.Container;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;

public class Skeleton2 extends JFrame /*implements WindowListener*/{
private static int DEFAULT_FPS = 80;

private Board2 bd;

public Skeleton2(long period) {
    super("Skeleton");
    makeGUI(period);

    //addWindowListener(this);
    pack();
    setResizable(false);
    setVisible(true);

}

public void makeGUI(long period) {
    Container c = getContentPane();

    bd = new Board2();
    c.add(bd, "Center");

}   // end of makeGUI()

//==================================================================================
// Window Events
//==================================================================================
/*
    public void windowActivated(WindowEvent e) {
        bd.resumeGame();
    }

    public void windowDeactivated(WindowEvent e) {
        bd.pauseGame();
    }

    public void windowDeiconified(WindowEvent e) {
        bd.resumeGame();
    }

    public void windowIconified(WindowEvent e) {
        bd.pauseGame();
    }

    public void windowClosing(WindowEvent e) {
        bd.stopGame();
    }
    */

    public void windowClosed(WindowEvent e) {}
    public void windowOpened(WindowEvent e) {}
     //==================================================================================

public static void main(String[] args) {
    int fps = DEFAULT_FPS;
    long period = (long) 1000.0/fps;


    new Skeleton2(period);
    System.out.println("Period: " + period);
}


}

最佳答案

Not instantly, but rather "walk" to the given coordinate.

那么你需要使用 Swing Timer。定时器用于安排动画的播放时间。因此,您需要计算两点之间的路径。每次计时器触发时,您都会将标签移动几个像素,直到到达目的地。

无需为此进行自定义绘画。 JLabel 可以正常工作。困难的部分是计算你希望角色采取的路径。另请确保在添加 JLabel 的面板上使用空布局,这意味着您还需要将标签的大小设置为等于标签的首选大小。

关于java - 如何在屏幕上移动 jlabel 图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16016872/

相关文章:

java - 如何在 Gradle 任务中使用反射

java - 如何在不断移动的图像上记录鼠标事件?

java - 悬停时图像变化 Java

Java:JPanel 中的垂直对齐

java - 如何在窗口中移动图像?

java - 如何查看 Gradle 源集路径?

java - 找到最近的邻居/经纬度

java - 设计 : A Java Application with high throughput

Java 检测窗口中任意位置的鼠标点击在某些区域不起作用

java - 在调整应用程序窗口大小之前,jPanel 不会刷新