Java,如何绘制不断变化的图形

以前没有做过,所以显然我很烂。在此处,当前鼠标位置周围的64个像素会在窗体上绘制得更大一些。问题是,它有点“慢”,而且我不知道从哪里开始修复。

除此之外,我还创建了一个线程,该线程在完成时会不断调用更新图形,并像文本一样以每秒fps的速度调用,以真正显示绘制速度。

替代文字

代码示例:

@SuppressWarnings("serial")

public static class AwtZoom extends Frame {

private BufferedImage image;

private long timeRef = new Date().getTime();

Robot robot = null;

public AwtZoom() {

super("Image zoom");

setLocation(new Point(640, 0));

setSize(400, 400);

setVisible(true);

final Ticker t = new Ticker();

this.image = (BufferedImage) (this.createImage(320, 330));

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent we) {

t.done();

dispose();

}

});

try {

robot = new Robot();

} catch (AWTException e) {

e.printStackTrace();

}

t.start();

}

private class Ticker extends Thread {

public boolean update = true;

public void done() {

update = false;

}

public void run() {

try {

while (update == true) {

update(getGraphics());

// try {

// Thread.sleep(200);

// } catch (InterruptedException e) {

// e.printStackTrace();

// return;

// }

}

} catch (Exception e) {

update=false;

}

}

}

public void update(Graphics g) {

paint(g);

}

boolean isdone = true;

public void paint(Graphics g) {

if (isdone) {

isdone=false;

int step = 40;

Point p = MouseInfo.getPointerInfo().getLocation();

Graphics2D gc = this.image.createGraphics();

try {

for (int x = 0; x < 8; x++) {

for (int y = 0; y < 8; y++) {

gc.setColor(robot.getPixelColor(p.x - 4 + x, p.y

- 4 + y));

gc.fillOval(x * step, y * step, step - 3, step - 3);

gc.setColor(Color.GRAY);

gc.drawOval(x * step, y * step, step - 3, step - 3);

}

}

} catch (Exception e) {

e.printStackTrace();

}

gc.dispose();

isdone = true;

iter++;

}

g.drawImage(image, 40, 45, this);

g.setColor(Color.black);

StringBuilder sb = new StringBuilder();

sb.append(iter)

.append(" frames in ")

.append((double) (new Date().getTime() - this.timeRef) / 1000)

.append("s.");

g.drawString(sb.toString(), 50, 375);

}

int iter = 0;

}

所做的更改:

*添加了“ gc.dispose();”

*添加了“ isdone”,因此不能更快地调用重绘,然后应该这样。

* 将此链接添加到thrashgod源重写

* 将此链接添加到thrashgod源重写2

回答:

这是我的主要重写,其中包含以下值得注意的更改:

  • 我将检测像素颜色的任务与绘图任务分开了
  • 我已将robot.getPixelColor(…)替换为robot.createScreenCapture(…),以一次获取所有64个像素,而不是一次获取一个像素。
  • 我介绍了智能剪辑-仅重绘需要重绘的内容。
  • 我已经修复了线程,因此对模型和视图的所有更新都发生在事件调度线程上

    股票行情不断运行。当它检测到像素颜色的变化(由于鼠标移至其他区域或鼠标下方的像素变化)时,它会准确检测出变化的内容,更新模型,然后请求视图重新绘制。这种方法可以立即更新到人眼。289次屏幕更新累计花费了1秒。

在一个安静的星期六晚上,这是一个令人愉快的挑战。

import javax.swing.*;

import java.awt.*;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.awt.geom.Ellipse2D;

import java.awt.image.BufferedImage;

public class ZoomPanel extends JPanel {

private static final int STEP = 40;

private int iter = 0;

private long cumulativeTimeTaken = 0;

public static void main(String[] args) {

final JFrame frame = new JFrame("Image zoom");

final ZoomPanel zoomPanel = new ZoomPanel();

frame.getContentPane().add(zoomPanel);

final Ticker t = new Ticker(zoomPanel);

frame.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent we) {

t.done();

frame.dispose();

}

});

t.start();

frame.setLocation(new Point(640, 0));

frame.pack();

frame.setVisible(true);

}

private final Color[][] model = new Color[8][8];

public ZoomPanel() {

setSize(new Dimension(400, 400));

setMinimumSize(new Dimension(400, 400));

setPreferredSize(new Dimension(400, 400));

setOpaque(true);

}

private void setColorAt(int x, int y, Color pixelColor) {

model[x][y] = pixelColor;

repaint(40 + x * STEP, 45 + y * STEP, 40 + (x * STEP) - 3, 45 + (y * STEP) - 3);

}

private Color getColorAt(int x, int y) {

return model[x][y];

}

public void paintComponent(Graphics g) {

long start = System.currentTimeMillis();

if (!SwingUtilities.isEventDispatchThread()) {

throw new RuntimeException("Repaint attempt is not on event dispatch thread");

}

final Graphics2D g2 = (Graphics2D) g;

g2.setColor(getBackground());

try {

for (int x = 0; x < 8; x++) {

for (int y = 0; y < 8; y++) {

g2.setColor(model[x][y]);

Ellipse2D e = new Ellipse2D.Double(40 + x * STEP, 45 + y * STEP, STEP - 3, STEP - 3);

g2.fill(e);

g2.setColor(Color.GRAY);

g2.draw(e);

}

}

} catch (Exception e) {

e.printStackTrace();

}

iter++;

g2.setColor(Color.black);

long stop = System.currentTimeMillis();

cumulativeTimeTaken += stop - start;

StringBuilder sb = new StringBuilder();

sb.append(iter)

.append(" frames in ")

.append((double) (cumulativeTimeTaken) / 1000)

.append("s.");

System.out.println(sb);

}

private static class Ticker extends Thread {

private final Robot robot;

public boolean update = true;

private final ZoomPanel view;

public Ticker(ZoomPanel zoomPanel) {

view = zoomPanel;

try {

robot = new Robot();

} catch (AWTException e) {

throw new RuntimeException(e);

}

}

public void done() {

update = false;

}

public void run() {

int runCount = 0;

while (update) {

runCount++;

if (runCount % 100 == 0) {

System.out.println("Ran ticker " + runCount + " times");

}

final Point p = MouseInfo.getPointerInfo().getLocation();

Rectangle rect = new Rectangle(p.x - 4, p.y - 4, 8, 8);

final BufferedImage capture = robot.createScreenCapture(rect);

for (int x = 0; x < 8; x++) {

for (int y = 0; y < 8; y++) {

final Color pixelColor = new Color(capture.getRGB(x, y));

if (!pixelColor.equals(view.getColorAt(x, y))) {

final int finalX = x;

final int finalY = y;

SwingUtilities.invokeLater(new Runnable() {

public void run() {

view.setColorAt(finalX, finalY, pixelColor);

}

});

}

}

}

}

}

}

}

以上是 Java,如何绘制不断变化的图形 的全部内容, 来源链接: utcz.com/qa/421749.html

回到顶部