简体   繁体   English

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

[英]How can I move a jlabel image around the screen?

I want to click on the screen and have the character move to that destination. 我想点击屏幕并让角色移动到该目的地。 Not instantly, but rather "walk" to the given coordinate. 不是立即,而是“走”到给定的坐标。 Currently I'm using JLabels and they're fine if I only use static images, but everytime I click somewhere on the screen the image shows up at that exact point. 目前我正在使用JLabel,如果我只使用静态图像它们就没问题了,但每次我点击屏幕上的某个地方时,图像就显示在那个确切的位置。 Could someone give me some tips? 有人可以给我一些提示吗?

edit: Should I override the paint class and draw some items that way? 编辑:我应该覆盖绘画类并以这种方式绘制一些项目吗?

Here's some code: 这是一些代码:

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

}

Here's the player class: 这是玩家类:

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



}

Here is the main class: 这是主要类:

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. 不是立即,而是“走”到给定的坐标。

Then you need to use a Swing Timer. 然后你需要使用Swing Timer。 The Timer is used to schedule the animation. Timer用于安排动画。 So you would need to calculate a path between the two points. 所以你需要计算两点之间的路径。 Every time the Timer fires you would move the label a few pixels until it reaches it's destination. 每次定时器触发时,您都会将标签移动几个像素,直到它到达目的地。

There is no need to do custom painting for this. 没有必要为此做定制绘画。 A JLabel will work fine. JLabel会正常工作。 The hard part is calculating the path you want the character to take. 困难的部分是计算你想要角色的路径。 Also make sure you use a null layout on the panel you add the JLabel to, which means you will also need to set the size of the label equal to the preferred size of the label. 还要确保在添加JLabel的面板上使用空布局,这意味着您还需要将标签的大小设置为等于标签的首选大小。

您应该在组件paintComponent方法中使用g.drawImage。

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

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