1

我昨天发现了机器人课,觉得很酷。今天我想尝试一下,看看有什么可能;所以我决定制作一个程序,它可以截取整个屏幕,并在 JPanel 上逐个像素地渲染出图像。我已经完成了程序(两个类),但它不工作,我无法找出原因(我已经查看了几次代码)。这是代码:

(头等舱)

import java.awt.AWTException;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;

public class One { 
    public static void main(String[] args) { 
        BufferedImage screenCap = null;
        Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        try {
            screenCap = new Robot().createScreenCapture(screenRect);
            Two imageRenderer = new Two(screenCap, screenRect);
            imageRenderer.doRender();
            JFrame frame = new JFrame();
            frame.setVisible(true);
            frame.setResizable(false);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new FlowLayout());
            frame.add(imageRenderer);
            frame.pack();
        } catch (AWTException e) { 
            e.printStackTrace(); 
        } 
    } 
}

(二等)

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

public class Two extends JPanel {
    private BufferedImage screenCap;
    private Rectangle screenRect;

    private Color pixelRGB;
    //c1 and c2 are the x and y co-ordinates of the selected pixel.
    private int c1, c2;

    public Two(BufferedImage sC, Rectangle rect) {
        screenCap = sC;
        screenRect = rect;
        setPreferredSize(new Dimension(rect.width, rect.height));
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        setBackground(Color.WHITE);

        g.setColor(pixelRGB);
        g.drawRect(c1, c2, 1, 1);
    }

    public void doRender() {
        for(int i=0; i<screenRect.width; i++) {
            for(int j=0; j<screenRect.height; j++) {
                pixelRGB = new Color(screenCap.getRGB(i, j));
                c1 = i;
                c2 = j;
                repaint();
            }
        }
    }
}

我用谷歌搜索了这个问题无济于事。

谁能告诉我我做错了什么?

4

3 回答 3

3

为了使其工作,只需将您paintComponent()的类中的方法替换Two为以下内容:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    setBackground(Color.WHITE);
    g.drawImage(screenCap, 0, 0, getWidth(), getHeight(), null);
}

您也可以摆脱该doRender()方法。

于 2012-09-10T18:13:51.627 回答
1

Two应该可能是JLabel正在显示的 a 的一个实例screenCap。例如

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class Screenshot {

    public static void main(String[] args) throws Exception {
        Rectangle screenRect = new Rectangle(
                Toolkit.getDefaultToolkit().getScreenSize());

        final BufferedImage screenCap = 
                new Robot().createScreenCapture(screenRect);
        Runnable r = new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(null, new ImageIcon(screenCap));
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

如果您希望非常整洁,请将其放在滚动窗格中。不包括电池。

如果不是很明显:AJOptionPane使用 aJLabel来渲染ImageIcon.

于 2012-09-10T19:35:15.433 回答
0

每次重新绘制时,您都会在整个面板上绘制白色,然后只绘制一个像素。所以在每一个之后,你只会得到一个像素。也不应该repaint多次调用。实际上,当您调用时repaint,它不会立即实际调用paintComponent。它只是提交一个重绘请求,swing 最终会这样做。而且它可能不是一对一的。例如,多次调用 torepaint可能只会导致一次调用paintComponent. 您应该尝试编写代码,以便一次调用paintComponent将完全显示该组件。

为此,您可以使用g.drawImageBufferedImage 来显示。有关在 JPanel 中显示图像的更多信息,请参阅这篇文章。

于 2012-09-10T18:10:42.490 回答