当前位置: 首页 > 面试题库 >

使用Graphics2D绘制图像

龙珂
2023-03-14
问题内容

我正在尝试使用Java的Graphics2D在屏幕上绘制图像。这是我正在使用的代码。我想看到图像在屏幕上稳定移动。目前,我可以看到图像,但是除非调整窗口大小,否则图像不会移动,在这种情况下,图像确实会移动。我已经勾勒出以下课程。

 public class Tester extends JFrame {

    private static final long serialVersionUID = -3179467003801103750L;
    private Component myComponent;
    public static final int ONE_SECOND = 1000;
    public static final int FRAMES_PER_SECOND = 20;

    private Timer myTimer;

    public Tester (Component component, String title) {
        super(title);
        myComponent = component;
    }

    public void start () {

        myTimer = new Timer(ONE_SECOND / FRAMES_PER_SECOND, new ActionListener() {
            @Override
            public void actionPerformed (ActionEvent e) {
                repaint();
            }
        });
        myTimer.start();
    }

    @Override
    public void paint (Graphics pen) {
        if (myComponent != null) {
            myComponent.paint(pen);
        }
    }

}

传递给Tester的Component对象是以下类:

public class LevelBoard extends Canvas implements ISavable {

    private static final long serialVersionUID = -3528519211577278934L;

    @Override
    public void paint (Graphics pen) {
        for (Sprite s : mySprites) {
            s.paint((Graphics2D) pen);
        }
    }

    protected void add (Sprite sprite) {
        mySprites.add(sprite);
    }

我确保此类仅添加了一个精灵。Sprite类大致如下:

public class Sprite {

    private Image myImage;
    private int myX, myY;

    public Sprite () {
        URL path = getClass().getResource("/images/Bowser.png");
        ImageIcon img = new ImageIcon(path);
        myImage = img.getImage();

    }

    public void update () {
        myX += 5;
        myY += 5;
    }

    public void paint (Graphics2D pen) {
        update();
        pen.drawImage(myImage, myX, myY,null);
    }

但是,我在屏幕上仅看到固定的Bowser图像。除非调整窗口大小,否则他不会移动。我知道Sprite类中的paint(Graphics2D
pen)方法是按特定的时间间隔调用的(因为Tester类中的Timer)。但是,即使x和y位置每次都增加5。精灵不会移动。为什么不?我如何解决它?目前,我只是想测试程序的其他功能,因此我真的只需要启动并运行它。我不太在乎。


问题答案:

您的代码充满了问题:

  1. 不要改写JFrame.paint(),尤其是不打电话时super。设置一个ContentPane并覆盖其paintComponent()。虽然看起来很方便,但通常这是一个糟糕的设计,并且不必要。
  2. 不要覆盖JComponent.paint(),而是覆盖JComponent.paintComponent()(并调用super
  3. 使用JLabel显示图像。这要简单得多。
  4. 不要混合使用AWT(Canvas)和Swing(JFrame)。坚持摇摆。

这是一个简单的示例,显示Bowser在框架中移动。(这很有趣,当您减小帧大小并使用帧边框打图像时;-))

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UnsupportedLookAndFeelException;

public class TestAnimation2 {
    private static final int NB_OF_IMAGES_PER_SECOND = 50;
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;
    private Random random = new Random();

    private double dx;
    private double dy;

    private double x = WIDTH / 2;
    private double y = HEIGHT / 2;

    protected void initUI() throws MalformedURLException {
        final JFrame frame = new JFrame(TestAnimation2.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(null);
        final JLabel label = new JLabel(new ImageIcon(new URL("http://www.lemondedemario.fr/images/dossier/bowser/bowser.png")));
        label.setSize(label.getPreferredSize());
        frame.setMinimumSize(label.getPreferredSize());
        frame.add(label);
        frame.setSize(WIDTH, HEIGHT);
        dx = getNextSpeed();
        dy = getNextSpeed();
        Timer t = new Timer(1000 / NB_OF_IMAGES_PER_SECOND, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                x += dx;
                y += dy;
                if (x + label.getWidth() > frame.getContentPane().getWidth()) {
                    x = frame.getContentPane().getWidth() - label.getWidth();
                    dx = -getNextSpeed();
                } else if (x < 0) {
                    x = 0;
                    dx = getNextSpeed();
                }
                if (y + label.getHeight() > frame.getContentPane().getHeight()) {
                    y = frame.getContentPane().getHeight() - label.getHeight();
                    dy = -getNextSpeed();
                } else if (y < 0) {
                    y = 0;
                    dy = getNextSpeed();
                }
                label.setLocation((int) x, (int) y);

            }
        });
        frame.setVisible(true);
        t.start();
    }

    private double getNextSpeed() {
        return 2 * Math.PI * (0.5 + random.nextDouble());
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    new TestAnimation2().initUI();
                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }
}


 类似资料:
  • 我试图保存一个自助式图像,我已经画了一个新的文件。我打开这个文件,使用图形2d在上面绘制(然后在JFrame中显示图像,以确保其工作,它确实这样做),然后将其保存到一个新文件中。 问题是:保存的文件只是原始图像。它不包含我在上面绘制的任何新图形。 以下是我的代码的简化版本: 稍后在另一种方法中: 相关方法:

  • 问题内容: 我想在另一幅图像上绘制部分透明的图像(在物体上形成阴影)。我目前正在使用Java的Graphics2D类进行渲染,有人告诉我将合成设置为AlphaComposite,但这仅将其设置为完全透明。 我可以使用当前设置进行此操作吗?我必须怎么做才能解决此问题? 这是我被告知可以使其部分透明的代码: (顺便说一句,我正在使用png图像) 这是您的sscce(它们都在不同的类中,但是为了简单起见

  • 问题内容: 我一直在试图弄清楚如何翻转图像,但是还没有弄清楚。 我使用画一个与 我只需要一种在水平或垂直轴上翻转图像的方法。 如果您愿意,可以查看github上的完整源代码。 问题答案: 来自http://examples.javacodegeeks.com/desktop-java/awt/image/flipping-a- buffered-image :

  • 有没有一种方法我可以在Java中操纵一个PrinterJob而不是实际打印到打印机上,这样我就可以获得每一页的图形对象?我尝试将PrintService设置为null,但Java不允许这样做。 这样,我就可以检索文档的准确打印预览,而不必在不同的上下文中从头重新构建PrinterJobs函数。 下面是我的程序中打印函数的代码: 你已经可以看到图形对象被记录了,这样我就可以在另一个组件中绘制它们了,

  • 我正试着用Jupyter笔记本画热图。我的表由10个列和许多行组成。第一行是列名。我正在使用plotly lib。 dfs是数据帧。 而不是图形,我得到了很多这样的线条: '\n跟踪=判(\n x=x,y=y,z=z,\n类型="散射3d",\n模式=\'标记\',\n标记=判(大小=5,颜色=\'黑色\',线=判(宽度=0)))\n数据=[跟踪]\n\n\n etc 有什么问题?