- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作一个 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 毫秒计时器滞后的时间量。我的问题:为什么会发生这种情况?除了返回计时器之外,还有什么方法可以防止闪烁吗?
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/
我正在编写一个小应用程序供我自己使用,它将使用公开发布的 RSS 提要。 据我所知,协议(protocol)中没有订阅/发布机制;我需要定期让我的应用程序 HTTP-GET RSS 提要。 如果是这样
我正在使用 requestAnimationFrame 在我的游戏中绘制玩家。其中一名球员比其他人移动得更快。我和他核对了一下,他告诉我他的显示器有 120hz 的刷新率。我假设这意味着 has 可以
我正在使用 onTouch(View arg0, MotionEvent arg1)作为游戏输入。它返回 false 所以它没有被处理。在我运行 4.0.4 的 HTC HD2 上,这足以让播放器足够
是否所有 RSS 提要都支持 HTTP ETags/last-modified header 用于指示提要是否已更新? 对于不包含最后修改标题的提要,确定提要更新频率的最佳方法是什么? 我希望根据每个
几个月来,我一直在将应用程序上传到 Google Play。我已经在我所有的 ~30 个应用程序中添加了 Admob 横幅广告。我将在本月收到第一笔付款,我将在 1 月份收到“大笔”付款(+2000
过去几天我一直在研究 Estimote Beacons。我开始怀疑 iBeacon 的有效性,因为它们在确定 Beacon 位置时存在高延迟。 当您移动 2-3 米时,它需要几秒钟才能找到正确的位置。
我目前正在为我的大学研究项目开发 Android 应用程序。此应用程序应该能够读取附近 GSM 基站的 RSSI 级别。我编写了以下函数,它成功读取了附近小区的 RSSI 电平。我每 200 毫秒调用
代码如下: Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nInd
所以我正在为 DOS 提示符开发老式 ASCII 游戏,你问值得我花时间吗?我想说的是,它是怀旧的。无论如何,自从我重新开始并重新学习如何直接访问屏幕内存以来,我一直享受着很多乐趣,直到最近我的游戏刷
如果我以尽可能高的精度单独使用 CoreLocation,我会每秒或 1Hz 获得一次更新。但是,如果我有一个刷新率为 10Hz 的外部蓝牙连接 GPS 单元,我仍然只会在 1Hz 时收到来自 Cor
我正在研究高速率渲染帧(理想情况下接近最大监视器速率),我想知道是否有人知道我应该在哪个级别开始研究:内核/驱动程序级别(操作系统空间)? X11级? svgalib(用户空间)? 最佳答案 在现代计
我正在创建一个多显示器全屏 DXGI/D3D 应用程序。我正在枚举可用的输出和适配器,以准备创建它们的交换链。 使用 DXGI 的 IDXGIFactory::CreateSwapChain 创建我的
在大多数教程或建议中,60 fps 的值被列为应用程序要达到的最终刷新率。 IE。如果该应用能够以 60 fps 的速度持续提供用户体验,则没有更多改进空间。 但是,对于较新的设备,例如哪些 iPad
我是一名优秀的程序员,十分优秀!