gpt4 book ai didi

Java Graphics 图像刷新率

转载 作者:行者123 更新时间:2023-12-02 06:13:56 28 4
gpt4 key购买 nike

我正在制作一个 JFrame,其中包含使用 repaint() 刷新的多个图像。然而,问题是,我添加的图像越多(或者随着渲染区域的增加),帧速率就会急剧下降。

我最初试图减少 Swing 不可预测的计时器所经历的延迟,但没有成功。这次,我尝试打电话

repaint()

根据系统时间每 10 毫秒一次。 (为了绕过计时器,调用desktop.screenPaint.drawWindow();而不是repaint())

while(true)
{
long starttime = System.currentTimeMillis();
while(System.currentTimeMillis()-starttime < 10)
{
}
desktop.screenPaint.drawWindow();
desktop2.screenPaint.drawWindow();
}

每个“桌面”只是运行下面的代码时看到的可拖动窗口之一。我注意到,当仅将“桌面”添加到“框架”时,没有闪烁。然而,当还添加“desktop2”时,闪烁不会消失,直到每次刷新的时间设置为 20 或更多毫秒。这很奇怪,因为当我还在使用定时器时,即使等待设置为10毫秒,帧率也会降低到每20毫秒一帧!我测试了一下,发现了一个趋势:你会一直闪烁,直到等待时间达到 10 毫秒计时器滞后的时间量。我的问题:为什么会发生这种情况?除了返回计时器之外,还有什么方法可以防止闪烁吗?

What the image is supposed to look like

flickering

flickering

import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.SwingUtilities.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
import java.io.File;
import java.io.IOException;
public class Display extends JPanel
{
public static int width, height;
public static JFrame frame = new JFrame("");
private static int rh = 10;
public static Display desktop = new Display();
public static Display desktop2 = new Display();
public static void main(String[] args)
{
Dimension screen = new Dimension();
screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
width = (int)screen.getWidth();
height = (int)screen.getHeight();
frame.setLayout(null);
frame.setLocation(0, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
desktop.setBounds(0, 0, 620, 500+rh);
desktop2.setBounds(1000, 200, 620, 500+rh);
frame.add(desktop);
frame.add(desktop2);
frame.setUndecorated(true);
frame.setSize(width, height);
frame.setVisible(true);
while(true)
{
long starttime = System.currentTimeMillis();
while(System.currentTimeMillis()-starttime < 10)
{
}
desktop.screenPaint.drawWindow();
//desktop2.screenPaint.drawWindow();
}
}
private BufferedImage image;
private Graphics2D g;
public Listener screenPaint = new Listener();
private Display identify;
public Display()
{
identify = this;
image = new BufferedImage(620, 500+rh, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D)image.getGraphics();
Timer timer = new Timer(1, screenPaint);
timer.start();
addMouseListener(new mMouse());
addMouseWheelListener(new wWheel());
setFocusable(true);
}
private BufferedImage toCompatibleImage(BufferedImage image)
{
GraphicsConfiguration gfx_config = GraphicsEnvironment.
getLocalGraphicsEnvironment().getDefaultScreenDevice().
getDefaultConfiguration();
if (image.getColorModel().equals(gfx_config.getColorModel()))
return image;
BufferedImage new_image = gfx_config.createCompatibleImage(
image.getWidth(), image.getHeight(), image.getTransparency());
}
public void paint(Graphics view)
{
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
view.drawImage(toCompatibleImage(image), 0, 0, 620, 500+rh, null);
view.dispose();
}
private class Listener implements ActionListener
{
int y = 0;
int wy = 0;
int b = 500;
int c = 1500;
int iy = (int)(wy/(c/(double)b));
int a = -1;
int i = -1;
int j = -1;
boolean d = false;
boolean u = false;
int f = 0;
public void moveY(int sy)
{
f += sy;
}
public void actionPerformed(ActionEvent e)
{
//drawWindow();
}
public void drawWindow()
{
int lx = (int)(identify.getLocation().getX());
int ly = (int)(identify.getLocation().getY());
g.setColor(Color.white);
g.fillRect(0, 0, 620, 500+rh);
g.drawImage(new ImageIcon("image.png").getImage(), 0, wy+rh, 610, c, null);
if(c > b)
{
if(d || Mouse.withinRect(610+lx, (int)(-wy/(c/(double)b))+rh+ly, 10, (int)Math.ceil(Math.pow(b, 2)/(double)c)))
{
if(Mouse.pressLeft())
{
if(!d)d = true;
if(a == -1)a = Mouse.y()-(int)(-wy/(c/(double)b));
y = (int)((Mouse.y()-a)*(c/(double)b));
f = y;
g.setColor(Color.black);
}
else
{
if(d)d = false;
if(a != -1)a = -1;
g.setColor(new Color(60, 60, 60));
}
}
else
{
g.setColor(Color.gray);
if(a != -1)a = -1;
}
if(y == f){}
else if(y < f)
{
y += (int)((f-y)*0.1);
if(y < f)y++;
}
else
{
y -= (int)((y-f)*0.1);
if(y > f)y--;
}
if(y < 0)
{
y = 0;
f = 0;
}
else if(y > c-b)
{
y = c-b;
f = y;
}
wy = -y;
if(u || Mouse.withinRect(lx, ly, 620, 10))
{
if(Mouse.pressLeft())
{
if(!u)u = true;
if(i == -1)i = Mouse.x()-lx;
if(j == -1)j = Mouse.y()-ly;
identify.setLocation(Mouse.x()-i, Mouse.y()-j);
}
else
{
if(u)u = false;
if(i != -1)i = -1;
if(j != -1)j = -1;
}
}
else
{
if(u)u = false;
if(i != -1)i = -1;
if(j != -1)j = -1;
}
int scrollBarLength = (int)Math.ceil(Math.pow(b, 2)/(double)c);
g.fillRect(610, (int)(-wy/(c/(double)b))+rh, 10, scrollBarLength);
}
else
{
g.setColor(new Color(200, 200, 200));
g.fillRect(610, rh, 10, b);
}
g.setColor(new Color(50, 50, 50));
g.fillRect(0, 0, 620, rh);
if(identify == desktop)
repaint();
else if(false)
{}
}
}
}
public static boolean LMPress, LMRelease = false;
public static boolean LMRight, LMLeft = false;
private class mMouse extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
LMPress = true; LMRelease = false;
if(SwingUtilities.isRightMouseButton(e))
{
LMRight = true;
LMLeft = false;
}
else if(SwingUtilities.isLeftMouseButton(e))
{
LMLeft = true;
LMRight = false;
}
}
public void mouseReleased(MouseEvent e)
{
LMRelease = true; LMPress = false;
if(SwingUtilities.isRightMouseButton(e))
{
LMRight = true;
LMLeft = false;
}
else if(SwingUtilities.isLeftMouseButton(e))
{
LMLeft = true;
LMRight = false;
}
}
}
private class wWheel implements MouseWheelListener
{
public void mouseWheelMoved(MouseWheelEvent e)
{
int notches = e.getWheelRotation();
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {}
e.getScrollAmount();
screenPaint.moveY(e.getUnitsToScroll()*60); //desired pixel jump: 120
}
}
}

鼠标类:

import java.awt.*;
import java.awt.event.*;

public class Mouse {
public static int x() {
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
return (int) b.getX();
}

public static int y() {
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
return (int) b.getY();
}

public static boolean withinRect(int x, int y, int w, int h) {
if (x() >= x && x() < x + w && y() >= y && y() < y + h) return true;
else return false;
}

public static boolean press() {
return Display.LMPress;
}

public static boolean release() {
return Display.LMRelease;
}

public static boolean pressLeft() {
if (Display.LMPress && Display.LMLeft)
return true;
else return false;
}

public static boolean releaseLeft() {
if (Display.LMRelease && Display.LMLeft)
return true;
else return false;
}

public static boolean pressRight() {
if (Display.LMPress && Display.LMRight)
return true;
else return false;
}

public static boolean releaseRight() {
if (Display.LMRelease && Display.LMRight)
return true;
else return false;
}
}

最佳答案

以 1 kHz 的频率更新 View 是不现实的;相反,请考虑引用的替代方案 here 。看这个AnimationTest有关自行计时以确定动画预算的示例。

附录: while(true) 顶部循环以 100 Hz 运行。

System.currentTimeMillis() 的可用分辨率可能 vary by platform .

附录:我正在重新打开这个问题,因为我无法解决它。还有更多帮助吗?

缺少 Minimal, Complete, Tested and Readable Example ,很难说。您似乎正在覆盖 paint();已在 Painting in AWT and Swing: The Paint Methods 中注明,“Swing 程序应该重写 paintComponent()。”此外,您还需要调用super.paintComponent(),如图here ,以避免视觉伪影。

关于Java Graphics 图像刷新率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21652271/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com