如何在Java中刷新Window类的图形

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

我正在尝试绘制vlcj(VLC库的Java绑定)面板,以便可以播放视频并绘制它。我遇到了一些问题。这是完整的基本代码:

代码清单1:AppOverlay.java

package app;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.Window;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.sun.jna.platform.WindowUtils;

@SuppressWarnings("serial")
public class AppOverlay extends Window implements Runnable {

    private final boolean isRunning;
    private final int fps;
    private BufferedImage graphics;
    private BufferedImage img;
    private int x, y;
    private boolean ltr;

    public AppOverlay(Window owner) throws HeadlessException {
        super(owner, WindowUtils.getAlphaCompatibleGraphicsConfiguration());
        setBackground(new Color(0,0,0,0));

        graphics    = new BufferedImage(1280,800, BufferedImage.TYPE_INT_ARGB);
        isRunning   = true;
        img         = null;
        ltr         = true;
        fps         = 60;
        x           = 0;
        y           = 0;
    }

    @Override
    public void run(){
        while(isRunning){

            try{
                Thread.sleep(1000/fps);
            } catch(InterruptedException e){
                e.printStackTrace();
            }

            if(ltr) {
                if(x < 1280) x++;
                else ltr = false;
            } else {
                if(x < 0) ltr = true;
                else x--;
            }

            repaint();
        }
    }

    public void createAndShowGUI() {
        setVisible(true);

        Thread thread = new Thread(this);
        thread.start();

        String path = "Drive:\\path\\to\\image.png";
        try {
            img = ImageIO.read(new java.io.FileInputStream(path));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D)g;
        Graphics2D gfx = graphics.createGraphics();
        gfx.setColor(new Color(255,255,255,0));
        gfx.clearRect(0, 0, 1280, 800);
        if(img != null) gfx.drawImage(img, x, y, null);
        gfx.dispose();
        g2d.drawImage(graphics, 0, 0, null);
    }
}

代码清单2:AppPlayer.java

package app;

import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent;

@SuppressWarnings("serial")
public class AppPlayer extends EmbeddedMediaPlayerComponent {

}

代码清单3:AppFrame.java

package app;

import java.awt.Dimension;

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class AppFrame extends JFrame {

    private AppPlayer appPlayer;
    private AppOverlay overlay;

    public AppFrame(){
        super();
    }

    public void createAndShowGUI() {

        appPlayer = new AppPlayer();
        appPlayer.setPreferredSize(new Dimension(1280,800));
        getContentPane().add(appPlayer);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setTitle("App");
        setVisible(true);
        pack();

        overlay = new AppOverlay(this);
        appPlayer.mediaPlayer().overlay().set(overlay);
        appPlayer.mediaPlayer().overlay().enable(true);
        overlay.createAndShowGUI();
    }
}

代码清单4:Main.java

package main;

import javax.swing.SwingUtilities;

import app.AppFrame;

public class Main {

    public static void main(String[] args) {
        final AppFrame app = new AppFrame();
        SwingUtilities.invokeLater( new Runnable() {
            @Override
            public void run() {
                app.createAndShowGUI();
            }
        });
    }

}

使用该代码和vlcj-4库,您应该可以自己测试我的代码。我的问题是,除非取消选择窗口(单击另一个窗口或在桌面或OS工具栏上单击),否则Overlay(扩展Window类的AppOverlay类)不会显示或刷新动画。处于非活动状态,然后再次选择窗口(应用程序)。它只会加载一帧,仅此而已。我必须再次取消选择并重新选择窗口才能加载另一帧(这仅适用于Overlay,即如果我在AppPlayer类中播放视频,则视频将正常播放。

我想要的是能够在叠加层上绘制一些动画图形。我知道在JPanel类中有paintComponent()方法,但是Window类没有该方法(仅paint()和repaint()方法可用)。

我该怎么解决?

java awt vlcj
2个回答
0
投票

您已经完成了大部分工作。每次绘制框架时,只需调用app.repaint();

即可重新绘制框架

0
投票

您可以从JComponent使用以下方法:(http://download.oracle.com/javase/6/docs/api/javax/swing/JComponent.html

void    repaint(long tm, int x, int y, int width, int height)
 //**Adds the specified region to the dirty region list if the component is showing.*//
void    repaint(Rectangle r)
 /**Adds the specified region to the dirty region list if the component is showing.*//
You can call those before redraw()
© www.soinside.com 2019 - 2024. All rights reserved.