使用jframe的多个jComponents的动画

时间:2013-10-29 01:53:46

标签: java swing animation

我无法在我的花园网格面板上看到动画。无论我添加到最后一个显示的内容窗格。无论如何都要同时显示多个组件。我已经尝试切换类动画和花园网格来扩展jpanel但没有任何工作。动画是一系列图像,用于显示在用鼠标拖动时移动的角色。我需要那个角色移动到花园网格面板的顶部。有什么帮助吗?

  package view;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.GridBagLayout;
import java.awt.Panel;

import javax.swing.JFrame;
import javax.swing.JLayeredPane;


public class Driver {
public static void main(String[] args) {

    JFrame frame = new JFrame();
   JLayeredPane pane = new JLayeredPane();
   frame.add(pane);

   Animation animation = new Animation();
   GardenPanel garden = new GardenPanel(6,4,600,800);


   pane.add(animation,new Integer(1));

   pane.add(garden, new Integer(0));
    frame.setSize(800, 600);


    System.out.println(pane.highestLayer());// just to check I dont have hidden layers







    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    while(true){
        frame.repaint();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

}

--------动画类-----------

你应该看到一个移动的兽人。你可以用鼠标拖动兽人。如果按  *你的鼠标没有移动它,功率会增加。  *  * /

package view;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

public class Animation extends JComponent implements MouseMotionListener, MouseListener{
    final int frameCount = 10;
    int picNum = 0;
    BufferedImage[][] pics;
    int xloc = 0;
    int yloc = 0;
    final int xIncr = 8;
    final int yIncr = 2;
    final static int frameWidth = 900;
    final static int frameHeight = 600;
    final static int imgWidth = 165;
    final static int imgHeight = 165;
    //basic info about the orc

    BufferedImage seedImage; 
    int mouseX;
    int mouseY;
    int seedX = xloc;
    int seedY = yloc;
    boolean mouseholding;
    boolean moving = false;
    int power;
    public enum stage {
        MOVE, POWER
    }
    stage s;

    //Override this JPanel's paint method to cycle through picture array and draw images
    public void paint(Graphics g) {
        picNum = (picNum + 1) % frameCount;
        if(mouseholding && (s == s.POWER)){
            System.out.println(power++);
        }


        g.drawImage(pics[0][picNum], xloc, yloc, Color.gray, this);
        g.drawImage(seedImage, seedX, seedY, imgWidth/8, imgHeight/8, this);
    }


    //Constructor: get image, segment and store in array
    public Animation(){
        seedImage = createImage(); 
        BufferedImage[] img = createAnimation();
        pics = new BufferedImage[img.length][10];
        for(int j = 0; j < img.length; j++){
            for(int i = 0; i < frameCount; i++)
                pics[j][i] = img[j].getSubimage(imgWidth*i, 0, imgWidth, imgHeight);
        }
        addMouseMotionListener(this);
        addMouseListener(this);
    }  

    //Read image from file and return
    private BufferedImage[] createAnimation(){
        BufferedImage[] bufferedImage = new BufferedImage[4];
        try {
            bufferedImage[0] = ImageIO.read(new File("images/orc_forward_southeast.png"));
            bufferedImage[1] = ImageIO.read(new File("images/orc_forward_southwest.png"));
            bufferedImage[2] = ImageIO.read(new File("images/orc_forward_northeast.png"));
            bufferedImage[3] = ImageIO.read(new File("images/orc_forward_northwest.png"));
            return bufferedImage;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private BufferedImage createImage(){
        BufferedImage bufferedImage;
        try {
            bufferedImage = ImageIO.read(new File("images/seed.png"));
            return bufferedImage;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

        // TODO: Change this method so you can load other orc animation bitmaps
    }

    // implement the method in mouseListener and mouseMotionListener interface
    @Override
    public void mouseDragged(MouseEvent event) {
        mouseX = event.getX();
        mouseY = event.getY();
        if( ( xloc<mouseX ) && (xloc+imgWidth >mouseX) && (yloc<mouseY) && (yloc+imgHeight>mouseY) && (s==stage.MOVE) ){

            //System.out.println("Imagecoor:("+xloc+", "+yloc+")"+" mousecoor:("+mouseX+","+mouseY+")"); 
            // you can print the coordinate if you want     
            xloc = mouseX-imgWidth/2;
            yloc = mouseY-imgHeight/2;
            seedX = mouseX;
            seedY = mouseY;
        }   
    } // draging the image
    @Override
    public void mouseMoved(MouseEvent arg0) {
    }
    @Override
    public void mouseClicked(MouseEvent e) {
    }
    @Override
    public void mouseEntered(MouseEvent e) {    
    }
    @Override
    public void mouseExited(MouseEvent e) { 
    }

    // for increasing the power.
    @Override
    public void mousePressed(MouseEvent event) { 
        mouseholding = true;
        mouseX = event.getX();
        mouseY = event.getY();
        if( (xloc == mouseX-imgWidth/2) && (yloc == mouseY-imgHeight/2) ){
            s = stage.POWER;
        }
    }
    @Override
    public void mouseReleased(MouseEvent event) {
        mouseholding = false;
        s = stage.MOVE;
        power = 0;
    }
}

-------- GardenPanel类------------ 应显示2条黑线

package view;

import java.awt.Graphics;

import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

public class GardenPanel extends JComponent {
    private int numOfRows;
    private int numOfColumns;
    private int frameWidth;
    private int frameHeight;

    public GardenPanel(int numOfRows, int numOfColumns, int frameHeight, int frameWidth){
        this.numOfRows = numOfRows;
        this.numOfColumns = numOfColumns;
        this.frameHeight = frameHeight;
        this.frameWidth = frameWidth;


    }
    int secondX = ((frameWidth -((frameWidth/3) *2)) / 4) * 3;

    @Override
    public void paint(Graphics g){
        g.drawLine((frameWidth/3) * 2, (frameHeight/4) * 3, (frameWidth/3 * 2) - 30, frameHeight/4);

        g.drawLine(((frameWidth/3) * 2) + 200, (frameHeight/4) * 3, ((frameWidth -((frameWidth/3) *2)/4) * 3) - 30, frameHeight/4);



    }

}

2 个答案:

答案 0 :(得分:2)

你说:

  

我无法在我的花园网格面板上看到动画。无论我添加到最后一个显示的内容窗格。

JFrame的contentPane使用BorderLayout,这就是BorderLayouts的工作方式。如果默认情况下添加组件(没有int第二个参数),则默认情况下它将放置在BorderLayout.CENTER位置并覆盖之前添加的任何内容。您将需要阅读Swing布局管理器教程以获取更多详细信息。

  

无论如何都要同时显示多个组件。

是的,使用不同的布局管理器和组件。如果您希望组件彼此重叠,请考虑使用JLayeredPane。

  

我已经尝试切换类动画和花园网格以扩展jpanel但没有任何效果。动画是一系列图像,用于显示在用鼠标拖动时移动的角色。我需要那个角色移动到花园网格面板的顶部。有什么帮助吗?

不确定您的具体问题是什么。

答案 1 :(得分:1)

有两种方法可以让动画位于花园面板的顶部。 然而正如“Hovercraft Full Of Eels”所指出的那样,你使用“GridBagLayout”的方式存在问题。

使用动画时,我倾向于使用绝对定位,这样就可以轻松地手动指定组件的确切位置,并且可以确保一切都可见。我这样做是通过向jFrame添加一个jLayeredPane / jPanel并向它们添加组件而不是jFrame。

以下两种方法可以让动画位于GardenPanel之上。

1)以不同的顺序添加组件以获得不同的结果。试一试。

2)将所有组件添加到“ContentPane”后,您可以设置所需组件的Z顺序,如下所示:

//Create this object first so we can set the Z-Order later
Animation animation = new Animation()
frame.getContentPane().add(animation); //use object above, not a "new" Animation
frame.getContentPane().add(new GardenPanel(6,4,600,800));
//Do something like this after all other components have been added to the ContentPane.
frame.getContentPane().setComponentZOrder(animation, 0);

编辑: 从您所展示的内容来看,您已经掌握了基础知识,所以这里有一个自包含的示例,您可以编译,我相信它可以演示您想要做什么。

animation由红色框表示,GardenPanel由蓝色区域表示。

请注意:

  1. 我已将组件添加到pane的顺序。首先:pane.add(animation);然后:pane.add(GardenPanel);
  2. 我使用JLabel代替您的自定义Animation组件和JLayeredPane代替您的GardenPanel组件,让这个示例非常简单,您应该能够将它们交换出来。
  3. 删除Drive类中的while循环,至少在测试时。一旦您知道两个组件都正确显示,您可以稍后解决重绘问题。

    import java.awt.Point;
    import javax.swing.JFrame;
    import javax.swing.JLayeredPane;
    import javax.swing.JLabel;
    
    public class Driver
    {
    //components
    static JFrame frame = new JFrame();
    static JLayeredPane pane = new JLayeredPane();
    static JLabel animation = new JLabel();
    static JLayeredPane GardenPanel = new JLayeredPane();
    
    //variables
    static Point startPos = new Point(0, 0);
    static Point draggedPos = new Point(0, 0);
    
    public static void main(String[] args)
    {
    //setup components
    frame.setSize(800, 600);
    pane.setSize(frame.getSize());
        pane.setBackground(java.awt.Color.GRAY);
        pane.setOpaque(true);
    
    animation.setSize(100, 150);
    animation.setLocation((pane.getWidth() - animation.getWidth())/2, (pane.getHeight() - animation.getHeight())/2);
    animation.setOpaque(true);
    animation.setBackground(java.awt.Color.RED);
    animation.addMouseListener(new java.awt.event.MouseAdapter()
    {
        @Override
        public void mousePressed(java.awt.event.MouseEvent evt)
        {
        startPos = evt.getLocationOnScreen();
        }
    });
    animation.addMouseMotionListener(new java.awt.event.MouseMotionAdapter()
    {
        @Override
        public void mouseDragged(java.awt.event.MouseEvent evt)
        {
        draggedPos = evt.getLocationOnScreen();
        animation.setLocation(animation.getX() + (draggedPos.x - startPos.x), animation.getY() + (draggedPos.y - startPos.y));
        startPos = evt.getLocationOnScreen();
        }
    });
    
    GardenPanel.setSize(800, 600);
    GardenPanel.setLocation(0, 0);
    GardenPanel.setOpaque(true);
    GardenPanel.setBackground(java.awt.Color.BLUE);
    
    //add components
    frame.add(pane);
    //The order of the following will get the desired results, I do not specify Z-Order, I simply add the top component first
    pane.add(animation);
    pane.add(GardenPanel);
    
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    }
    

    }

  4. 使用此示例代码,您可以调整原始代码以遵循类似的路径。