使用 JPanel 在 java 中绘图
Drawing in java with JPanel
我正在制作一个程序,其中有一个服务器和一个客户端,想法是在客户端 jpanel 上绘图,然后将坐标发送到服务器,这将有点模仿绘图.我已经做到了,但现在的问题是,我的绘图机制很糟糕。现在我只是使用一个在鼠标坐标上一遍又一遍绘制的椭圆,如果你移动鼠标太快,有时会在椭圆之间留下空间。
为了更好地说明,这是一个 SS:http://gyazo.com/6ed1017e9efd6beaa4b5d56052fda260
如您所见,只有当鼠标移动速度相对较慢时,它才会保持一致,但是一旦移动速度稍快,就会留下空格。
如何防止这种情况发生?
现在客户端只发送 x 和 y 坐标,所以这是服务器端代码:
package com.company;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends JPanel{
static MouseData mouseReceive;
static Draw draw;
static int x;
static int y;
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Server server = new Server();
JFrame frame = new JFrame("Server");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(server);
frame.setSize(1024, 600);
frame.setVisible(true);
draw = new Draw(x,y);
ServerSocket serverSock = new ServerSocket(1234);
Socket s = serverSock.accept();
ObjectInputStream in = new ObjectInputStream(s.getInputStream());
while(true) {
mouseReceive = (MouseData) in.readObject();
draw = new Draw(mouseReceive.mouseX,mouseReceive.mouseY);
}
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
draw.display(g);
repaint();
}
}
这是我的抽奖 class:
package com.company;
import java.awt.*;
/**
* Created by John on 21/04/2015.
*/
public class Draw {
int xLoc;
int yLoc;
Draw(int x, int y){
xLoc = x;
yLoc = y;
}
public void display(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.fillOval(xLoc,yLoc,7,7);
}
}
我试着通过搜索功能在这个网站上找到其他有同样问题的人,但我没有找到运气 :( 如果我错过了,请引导我到那个主题!
如果有人可以帮助我,我将不胜感激!祝你有美好的一天:)
假设客户端正在使用 MouseListener(或 MouseMotionListener):MouseListener 只能在一定间隔内触发。例如,当鼠标不断移动时,您的侦听器将在每个时间间隔而不是每个像素收到一个 MouseEvent。因此,快速移动鼠标可能会导致绘制的项目彼此不相邻。 AFAIK,你不能提高速度,但你可以在两个连续的点之间画线,使它们看起来连续(例如,通过使用每个事件位置的列表并在每个事件位置上使用 g.drawLine列表中的两个相邻点)。
其他说明:
- 您应该覆盖 paintComponent 而不是 paint 方法。
- 我建议在此方法中调用 super.paintComponent。这将清除组件(因此您的代码将只绘制最后一个点 - 请参阅 (3))
- 我建议保留一个用于绘图的位置列表,您可以对其进行迭代并绘制每个圆(或在相邻点之间画一条线)
- 不要在您的绘画方法中调用重绘。这里的思路是,当从Client接收到一个新item时,将其添加到(3)中的List中,然后调用repaint。
我正在制作一个程序,其中有一个服务器和一个客户端,想法是在客户端 jpanel 上绘图,然后将坐标发送到服务器,这将有点模仿绘图.我已经做到了,但现在的问题是,我的绘图机制很糟糕。现在我只是使用一个在鼠标坐标上一遍又一遍绘制的椭圆,如果你移动鼠标太快,有时会在椭圆之间留下空间。
为了更好地说明,这是一个 SS:http://gyazo.com/6ed1017e9efd6beaa4b5d56052fda260
如您所见,只有当鼠标移动速度相对较慢时,它才会保持一致,但是一旦移动速度稍快,就会留下空格。
如何防止这种情况发生?
现在客户端只发送 x 和 y 坐标,所以这是服务器端代码:
package com.company;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends JPanel{
static MouseData mouseReceive;
static Draw draw;
static int x;
static int y;
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Server server = new Server();
JFrame frame = new JFrame("Server");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(server);
frame.setSize(1024, 600);
frame.setVisible(true);
draw = new Draw(x,y);
ServerSocket serverSock = new ServerSocket(1234);
Socket s = serverSock.accept();
ObjectInputStream in = new ObjectInputStream(s.getInputStream());
while(true) {
mouseReceive = (MouseData) in.readObject();
draw = new Draw(mouseReceive.mouseX,mouseReceive.mouseY);
}
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
draw.display(g);
repaint();
}
}
这是我的抽奖 class:
package com.company;
import java.awt.*;
/**
* Created by John on 21/04/2015.
*/
public class Draw {
int xLoc;
int yLoc;
Draw(int x, int y){
xLoc = x;
yLoc = y;
}
public void display(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.fillOval(xLoc,yLoc,7,7);
}
}
我试着通过搜索功能在这个网站上找到其他有同样问题的人,但我没有找到运气 :( 如果我错过了,请引导我到那个主题! 如果有人可以帮助我,我将不胜感激!祝你有美好的一天:)
假设客户端正在使用 MouseListener(或 MouseMotionListener):MouseListener 只能在一定间隔内触发。例如,当鼠标不断移动时,您的侦听器将在每个时间间隔而不是每个像素收到一个 MouseEvent。因此,快速移动鼠标可能会导致绘制的项目彼此不相邻。 AFAIK,你不能提高速度,但你可以在两个连续的点之间画线,使它们看起来连续(例如,通过使用每个事件位置的列表并在每个事件位置上使用 g.drawLine列表中的两个相邻点)。
其他说明:
- 您应该覆盖 paintComponent 而不是 paint 方法。
- 我建议在此方法中调用 super.paintComponent。这将清除组件(因此您的代码将只绘制最后一个点 - 请参阅 (3))
- 我建议保留一个用于绘图的位置列表,您可以对其进行迭代并绘制每个圆(或在相邻点之间画一条线)
- 不要在您的绘画方法中调用重绘。这里的思路是,当从Client接收到一个新item时,将其添加到(3)中的List中,然后调用repaint。