可能使用GridBagLayout在Java JFrame中的特定网格空间内移动对象吗?

问题描述 投票:0回答:1

我想在JFrame窗口的1x 10垂直网格上上下移动一个矩形。

网格应该编号,我应该能够知道矩形在网格上的哪个级别。

我没有大量的Java经验,但是到目前为止,我从我看过的教程中了解的基本代码允许我在屏幕上上下移动矩形,但是矩形不在屏幕上,它不在网格上。

package JavaWork;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Lift extends JPanel implements ActionListener, KeyListener {
    Timer tm = new Timer(5, this);
    int x = 0, y = 0, velX = 0, velY = 0;
    /**
     * 
     */
    public Lift() {
        // TODO Auto-generated constructor stub
        tm.start();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.RED);
        g.fillRect(x, y, 50, 30);

    }

    public void actionPerformed(ActionEvent e) {
        x = x + velX;
        y = y + velY;
        repaint();
    }

    public void keyPressed(KeyEvent e) {
        int c = e.getKeyCode();

        if (c == KeyEvent.VK_UP) {
            velX = 0;
            velY = -1;

        }
        if (c == KeyEvent.VK_DOWN) {
            velX = 0;
            velY = 1;

        }
    }

    public void keyTyped(KeyEvent e) {}
    public void keyReleased(KeyEvent e) {}


    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Lift t = new Lift();
        JFrame jf = new JFrame();

        jf.setTitle("Lift");
        jf.setSize(600, 400);
        jf.setVisible(true);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.add(t);
    }
}

任何建议,一段代码,一个教程的网站或视频链接都将不胜感激:)

java animation jframe gridbaglayout
1个回答
0
投票

您可以通过仅使用y坐标(是40的倍数)进行绘制来自己完成网格的等效操作。我建议使用40,因为您将窗口的高度设置为400,并且您希望在其中有10个“地板”网格和400÷10 = 40。

因此,paintComponent方法的最后一行应如下所示:

g.fillRect(x, y * 40, 50, 30);

从技术上讲,窗口的绘制区域将比400小一点,因为JFrame的大小包括窗口的标题栏和边框。您可以通过以下方式解决此问题:

jf.setSize(600, 400);

带有此:

jf.add(t);
jf.pack();

并删除另一条jf.add(t);行。您还需要在您的课程中添加getPreferredSize替代:

@Override
public Dimension getPreferredSize() {
    return new Dimension(600, 400);
}

((您还需要在程序顶部的import java.awt.Dimension;行。)

pack()方法告诉窗口尽其最大努力以容纳其包含的每个组件的首选大小。这就是为什么您的面板有必要报告其自己的首选大小,这就是为什么有必要在打包JFrame并将其设置为可见之前添加面板。

关于矩形为何如此快地移出屏幕,这是由于您传递给计时器的数字所致:

Timer tm = new Timer(5, this);

5表示每5毫秒Swing调用一次actionPerformed方法,即每秒200次!您可能想要一个更合理的值,例如每秒两次:

Timer tm = new Timer(500, this);

最后,通过在actionPerformed方法中检查最小和最大y值,可以确保矩形永远不会离开屏幕:

y = y + velY;
y = Math.max(0, y);     // don’t let y go off the top
y = Math.min(9, y);     // don’t let y go off the bottom
© www.soinside.com 2019 - 2024. All rights reserved.