为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕盖茨4494581 2023-10-13 17:20:04
我正在尝试绘制 vlcj(VLC 库的 java 绑定)面板,以便我可以播放视频并在其上绘制。我遇到了一些问题。这是完整的基本代码:代码清单1:AppOverlay.javapackage 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();        }    }
查看完整描述

3 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

我对你的例子进行了一些研究,并提出了一些可行的方法,但我不会称其为一个很好的解决方案。

主要问题似乎是没有办法告诉覆盖层刷新(或者我只是没有找到它)。只是repainting叠加层不会在屏幕上更新它,因此我使用的解决方法是隐藏并再次显示它。

对于更新间隔的计时,我使用了javax.swing.Timer. (在真实版本中,您可能想通过 启动和停止计时器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 {


    private static final long serialVersionUID = -1569823648323129877L;


    public class Overlay extends Window {


        private static final long serialVersionUID = 8337750467830040964L;


        private int x, y;

        private boolean ltr = true;


        public Overlay(Window owner) throws HeadlessException {

            super(owner, WindowUtils.getAlphaCompatibleGraphicsConfiguration());

            setBackground(new Color(0,0,0,0));

        }


        @Override

        public void paint(Graphics g) {


            super.paint(g);


            if (ltr) {

                if (x < 1180)

                    x += 1;

                else

                    ltr = false;

            } else {

                if (x < 0)

                    ltr = true;

                else

                    x -= 1;

            }


            g.setColor(Color.RED);

            g.fillRect(x, y, 100, 100);


            String s = Integer.toString(x);

            g.setColor(Color.WHITE);

            g.drawChars(s.toCharArray(), 0, s.length(), x+10, y+50);

        }

    }


    private EmbeddedMediaPlayerComponent appPlayer;


    public void createAndShowGUI() {


        appPlayer = new EmbeddedMediaPlayerComponent();

        appPlayer.setPreferredSize(new Dimension(1280, 800));

        getContentPane().add(appPlayer);


        setDefaultCloseOperation(EXIT_ON_CLOSE);

        setTitle("App");

        setVisible(true);

        pack();


        Overlay overlay = new Overlay(this);


        OverlayApi api = appPlayer.mediaPlayer().overlay();

        api.set(overlay);

        api.enable(true);


        //appPlayer.mediaPlayer().media().play(" ... ");


        Timer timer = new Timer(0, new ActionListener() {

            @Override

            public void actionPerformed(ActionEvent e) {

                api.enable(false);

                api.enable(true);

            }

        });

        timer.setRepeats(true);

        timer.setDelay(200);

        timer.start();

    }

}

如果这对您来说是一个选择,那么使用 可能会更容易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 {


    private static final long serialVersionUID = -1569823648323129877L;


    public class OverlayPanel extends JPanel {


        private static final long serialVersionUID = 8070414617530302145L;


        private int x, y;

        private boolean ltr = true;


        public OverlayPanel() {

            this.setOpaque(false);

        }


        @Override

        public void paint(Graphics g) {


            super.paint(g);


            if (ltr) {

                if (x < 1180)

                    x += 1;

                else

                    ltr = false;

            } else {

                if (x < 0)

                    ltr = true;

                else

                    x -= 1;

            }


            g.setColor(Color.RED);

            g.fillRect(x, y, 100, 100);


            String s = Integer.toString(x);

            g.setColor(Color.WHITE);

            g.drawChars(s.toCharArray(), 0, s.length(), x+10, y+50);

        }

    }


    public class Overlay extends Window {


        private static final long serialVersionUID = 8337750467830040964L;


        OverlayPanel panel;


        public Overlay(Window owner) throws HeadlessException {

            super(owner);

            setBackground(new Color(0,0,0,0));


            panel = new OverlayPanel();

            this.add(panel);

        }

    }


    private EmbeddedMediaPlayerComponent appPlayer;


    public void createAndShowGUI() {


        appPlayer = new EmbeddedMediaPlayerComponent();

        appPlayer.setPreferredSize(new Dimension(1280, 800));

        getContentPane().add(appPlayer);


        setDefaultCloseOperation(EXIT_ON_CLOSE);

        setTitle("App");

        setVisible(true);

        pack();


        Overlay overlay = new Overlay(this);


        OverlayApi api = appPlayer.mediaPlayer().overlay();

        api.set(overlay);

        api.enable(true);


        //appPlayer.mediaPlayer().media().play(" ... ");


        Timer timer = new Timer(0, new ActionListener() {

            @Override

            public void actionPerformed(ActionEvent e) {

                overlay.panel.repaint();

            }

        });

        timer.setRepeats(true);

        timer.setDelay(17);

        timer.start();

    }

}



查看完整回答
反对 回复 2023-10-13
?
子衿沉夜

TA贡献1828条经验 获得超3个赞

您可以使用 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()


查看完整回答
反对 回复 2023-10-13
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

您已经完成了大部分工作。每次在框架上绘制时,只需通过调用重新绘制框架即可app.repaint();



查看完整回答
反对 回复 2023-10-13
  • 3 回答
  • 0 关注
  • 120 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信