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

我正在尝试绘制 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) {

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

        }


    }


慕盖茨4494581
浏览 77回答 3
3回答

HUH函数

我对你的例子进行了一些研究,并提出了一些可行的方法,但我不会称其为一个很好的解决方案。主要问题似乎是没有办法告诉覆盖层刷新(或者我只是没有找到它)。只是repainting叠加层不会在屏幕上更新它,因此我使用的解决方法是隐藏并再次显示它。对于更新间隔的计时,我使用了javax.swing.Timer.&nbsp;(在真实版本中,您可能想通过 启动和停止计时器MediaPlayerEventListener)。作为副作用,repaint调用该方法并x调整坐标以在屏幕上移动图像。在下面的简化示例中(使用您的main来运行它),我用 x 坐标移动了一个红色矩形,而不是一些未知图像。import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.HeadlessException;import java.awt.Window;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JFrame;import javax.swing.Timer;import com.sun.jna.platform.WindowUtils;import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent;import uk.co.caprica.vlcj.player.embedded.OverlayApi;public class AppFrame extends JFrame {&nbsp; &nbsp; private static final long serialVersionUID = -1569823648323129877L;&nbsp; &nbsp; public class Overlay extends Window {&nbsp; &nbsp; &nbsp; &nbsp; private static final long serialVersionUID = 8337750467830040964L;&nbsp; &nbsp; &nbsp; &nbsp; private int x, y;&nbsp; &nbsp; &nbsp; &nbsp; private boolean ltr = true;&nbsp; &nbsp; &nbsp; &nbsp; public Overlay(Window owner) throws HeadlessException {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super(owner, WindowUtils.getAlphaCompatibleGraphicsConfiguration());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setBackground(new Color(0,0,0,0));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public void paint(Graphics g) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super.paint(g);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (ltr) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (x < 1180)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x += 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ltr = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (x < 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ltr = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x -= 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.setColor(Color.RED);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.fillRect(x, y, 100, 100);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String s = Integer.toString(x);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.setColor(Color.WHITE);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.drawChars(s.toCharArray(), 0, s.length(), x+10, y+50);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private EmbeddedMediaPlayerComponent appPlayer;&nbsp; &nbsp; public void createAndShowGUI() {&nbsp; &nbsp; &nbsp; &nbsp; appPlayer = new EmbeddedMediaPlayerComponent();&nbsp; &nbsp; &nbsp; &nbsp; appPlayer.setPreferredSize(new Dimension(1280, 800));&nbsp; &nbsp; &nbsp; &nbsp; getContentPane().add(appPlayer);&nbsp; &nbsp; &nbsp; &nbsp; setDefaultCloseOperation(EXIT_ON_CLOSE);&nbsp; &nbsp; &nbsp; &nbsp; setTitle("App");&nbsp; &nbsp; &nbsp; &nbsp; setVisible(true);&nbsp; &nbsp; &nbsp; &nbsp; pack();&nbsp; &nbsp; &nbsp; &nbsp; Overlay overlay = new Overlay(this);&nbsp; &nbsp; &nbsp; &nbsp; OverlayApi api = appPlayer.mediaPlayer().overlay();&nbsp; &nbsp; &nbsp; &nbsp; api.set(overlay);&nbsp; &nbsp; &nbsp; &nbsp; api.enable(true);&nbsp; &nbsp; &nbsp; &nbsp; //appPlayer.mediaPlayer().media().play(" ... ");&nbsp; &nbsp; &nbsp; &nbsp; Timer timer = new Timer(0, new ActionListener() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void actionPerformed(ActionEvent e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; api.enable(false);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; api.enable(true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; timer.setRepeats(true);&nbsp; &nbsp; &nbsp; &nbsp; timer.setDelay(200);&nbsp; &nbsp; &nbsp; &nbsp; timer.start();&nbsp; &nbsp; }}如果这对您来说是一个选择,那么使用 可能会更容易animated gif。至少它自己可以工作(不需要计时器)。更新:正如您所发现的,使用 aJPanel似乎效果更好。只需使用setOpaque(false)使其透明即可。这是一个调整后的例子。import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.HeadlessException;import java.awt.Window;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.Timer;import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent;import uk.co.caprica.vlcj.player.embedded.OverlayApi;public class AppFrame2 extends JFrame {&nbsp; &nbsp; private static final long serialVersionUID = -1569823648323129877L;&nbsp; &nbsp; public class OverlayPanel extends JPanel {&nbsp; &nbsp; &nbsp; &nbsp; private static final long serialVersionUID = 8070414617530302145L;&nbsp; &nbsp; &nbsp; &nbsp; private int x, y;&nbsp; &nbsp; &nbsp; &nbsp; private boolean ltr = true;&nbsp; &nbsp; &nbsp; &nbsp; public OverlayPanel() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.setOpaque(false);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public void paint(Graphics g) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super.paint(g);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (ltr) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (x < 1180)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x += 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ltr = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (x < 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ltr = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x -= 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.setColor(Color.RED);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.fillRect(x, y, 100, 100);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String s = Integer.toString(x);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.setColor(Color.WHITE);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.drawChars(s.toCharArray(), 0, s.length(), x+10, y+50);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public class Overlay extends Window {&nbsp; &nbsp; &nbsp; &nbsp; private static final long serialVersionUID = 8337750467830040964L;&nbsp; &nbsp; &nbsp; &nbsp; OverlayPanel panel;&nbsp; &nbsp; &nbsp; &nbsp; public Overlay(Window owner) throws HeadlessException {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super(owner);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setBackground(new Color(0,0,0,0));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; panel = new OverlayPanel();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.add(panel);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private EmbeddedMediaPlayerComponent appPlayer;&nbsp; &nbsp; public void createAndShowGUI() {&nbsp; &nbsp; &nbsp; &nbsp; appPlayer = new EmbeddedMediaPlayerComponent();&nbsp; &nbsp; &nbsp; &nbsp; appPlayer.setPreferredSize(new Dimension(1280, 800));&nbsp; &nbsp; &nbsp; &nbsp; getContentPane().add(appPlayer);&nbsp; &nbsp; &nbsp; &nbsp; setDefaultCloseOperation(EXIT_ON_CLOSE);&nbsp; &nbsp; &nbsp; &nbsp; setTitle("App");&nbsp; &nbsp; &nbsp; &nbsp; setVisible(true);&nbsp; &nbsp; &nbsp; &nbsp; pack();&nbsp; &nbsp; &nbsp; &nbsp; Overlay overlay = new Overlay(this);&nbsp; &nbsp; &nbsp; &nbsp; OverlayApi api = appPlayer.mediaPlayer().overlay();&nbsp; &nbsp; &nbsp; &nbsp; api.set(overlay);&nbsp; &nbsp; &nbsp; &nbsp; api.enable(true);&nbsp; &nbsp; &nbsp; &nbsp; //appPlayer.mediaPlayer().media().play(" ... ");&nbsp; &nbsp; &nbsp; &nbsp; Timer timer = new Timer(0, new ActionListener() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void actionPerformed(ActionEvent e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; overlay.panel.repaint();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; timer.setRepeats(true);&nbsp; &nbsp; &nbsp; &nbsp; timer.setDelay(17);&nbsp; &nbsp; &nbsp; &nbsp; timer.start();&nbsp; &nbsp; }}

子衿沉夜

您可以使用 JComponent 中的以下方法:( http://download.oracle.com/javase/6/docs/api/javax/swing/JComponent.html )void&nbsp; &nbsp; repaint(long tm, int x, int y, int width, int height)&nbsp;//**Adds the specified region to the dirty region list if the component is showing.*//void&nbsp; &nbsp; repaint(Rectangle r)&nbsp;/**Adds the specified region to the dirty region list if the component is showing.*//You can call those before redraw()

慕田峪7331174

您已经完成了大部分工作。每次在框架上绘制时,只需通过调用重新绘制框架即可app.repaint();
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java