我必须开发一个白板应用程序,本地用户和远程用户都应该是able to draw simultaneously
,这可能吗?如果可能那么任何逻辑?
我已经开发了一个代码,但我无法做到这一点,当远程用户开始绘制我正在绘制的形状正在被他的形状和坐标所取代。 只有当两者同时绘制时才会出现此问题。
任何想法的人?
这是我的代码
class Paper extends JPanel implements MouseListener,MouseMotionListener,ActionListener
{
static BufferedImage image;
int bpressed;
Color color;
Point start;
Point end;
Point mp;
Button elipse=new Button("elipse");
Button rectangle=new Button("rect");
Button line=new Button("line");
Button empty=new Button("");
JButton save=new JButton("Save");
JButton erase=new JButton("Erase");
String selected;
int ex,ey;//eraser
DatagramSocket dataSocket;
JButton button = new JButton("test");
Client client;
Point p=new Point();
int w,h;
public Paper(DatagramSocket dataSocket)
{
this.dataSocket=dataSocket;
client=new Client(dataSocket);
System.out.println("paper");
setBackground(Color.white);
addMouseListener(this);
addMouseMotionListener(this);
color = Color.black;
setBorder(BorderFactory.createLineBorder(Color.black));
//save.setPreferredSize(new Dimension(100,20));
save.setMaximumSize(new Dimension(75,27));
erase.setMaximumSize(new Dimension(75,27));
}
public void paintComponent(Graphics g)
{
try
{
g.drawImage(image, 0, 0, this);
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(Color.black);
if(selected==("elipse"))
g2.drawOval(start.x, start.y,(end.x-start.x),(end.y-start.y));
else if(selected==("rect"))
g2.drawRect(start.x, start.y, (end.x-start.x),(end.y-start.y));
else if(selected==("line"))
g2.drawLine(start.x,start.y,end.x,end.y);
}
catch(Exception e)
{}
}
//Function to draw the shape on image
public void draw()
{
Graphics2D g2 = image.createGraphics();
g2.setPaint(color);
if(selected=="line")
g2.drawLine(start.x, start.y, end.x, end.y);
if(selected=="elipse")
g2.drawOval(start.x, start.y, (end.x-start.x),(end.y-start.y));
if(selected=="rect")
g2.drawRect(start.x, start.y, (end.x-start.x),(end.y-start.y));
repaint();
g2.dispose();
start=null;
}
//To add the point to the board which is broadcasted by the server
public synchronized void addPoint(Point ps,String varname,String shape,String event)
{
try
{
if(end==null)
end = new Point();
if(start==null)
start = new Point();
if(shape.equals("elipse"))
selected="elipse";
else if(shape.equals("line"))
selected="line";
else if(shape.equals("rect"))
selected="rect";
else if(shape.equals("erase"))
{
selected="erase";
erase();
}
if(end!=null && start!=null)
{
if(varname.equals("end"))
end=ps;
if(varname.equals("mp"))
mp=ps;
if(varname.equals("start"))
start=ps;
if(event.equals("drag"))
repaint();
else if(event.equals("release"))
draw();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
//To set the size of the image
public void setWidth(int x,int y)
{
System.out.println("("+x+","+y+")");
w=x;
h=y;
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
g2.setPaint(Color.white);
g2.fillRect(0,0,w,h);
g2.dispose();
}
//Function which provides the erase functionality
public void erase()
{
Graphics2D pic=(Graphics2D) image.getGraphics();
pic.setPaint(Color.white);
pic.fillRect(start.x, start.y, 10, 10);
}
//Function to add buttons into the panel, calling this function returns a panel
public JPanel addButtons()
{
JPanel buttonpanel=new JPanel();
JPanel row1=new JPanel();
JPanel row2=new JPanel();
JPanel row3=new JPanel();
JPanel row4=new JPanel();
buttonpanel.setPreferredSize(new Dimension(80,80));
//buttonpanel.setMinimumSize(new Dimension(150,150));
row1.setLayout(new BoxLayout(row1,BoxLayout.X_AXIS));
row1.setPreferredSize(new Dimension(150,150));
row2.setLayout(new BoxLayout(row2,BoxLayout.X_AXIS));
row3.setLayout(new BoxLayout(row3,BoxLayout.X_AXIS));
row4.setLayout(new BoxLayout(row4,BoxLayout.X_AXIS));
buttonpanel.setLayout(new BoxLayout(buttonpanel,BoxLayout.Y_AXIS));
elipse.addActionListener(this);
rectangle.addActionListener(this);
line.addActionListener( this);
save.addActionListener( this);
erase.addActionListener( this);
buttonpanel.add(Box.createRigidArea(new Dimension(10,10)));
row1.add(elipse);
row1.add(Box.createRigidArea(new Dimension(5,0)));
row1.add(rectangle);
buttonpanel.add(row1);
buttonpanel.add(Box.createRigidArea(new Dimension(10,10)));
row2.add(line);
row2.add(Box.createRigidArea(new Dimension(5,0)));
row2.add(empty);
buttonpanel.add(row2);
buttonpanel.add(Box.createRigidArea(new Dimension(10,10)));
row3.add(save);
buttonpanel.add(row3);
buttonpanel.add(Box.createRigidArea(new Dimension(10,10)));
row4.add(erase);
buttonpanel.add(row4);
return buttonpanel;
}
//To save the image drawn
public void save()
{
try
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
JFileChooser fc = new JFileChooser();
fc.showSaveDialog(this);
encoder.encode(image);
byte[] jpgData = bos.toByteArray();
FileOutputStream fos = new FileOutputStream(fc.getSelectedFile()+".jpeg");
fos.write(jpgData);
fos.close();
//add replce confirmation here
}
catch (IOException e)
{
System.out.println(e);
}
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent e)
{
if(selected=="line"||selected=="erase")
{
start=e.getPoint();
client.broadcast(start,"start", selected,"press");
}
else if(selected=="elipse"||selected=="rect")
{
mp = e.getPoint();
client.broadcast(mp,"mp", selected,"press");
}
}
public void mouseReleased(MouseEvent e)
{
if(start!=null)
{
if(selected=="line")
{
end=e.getPoint();
client.broadcast(end,"end", selected,"release");
}
else if(selected=="elipse"||selected=="rect")
{
end.x = Math.max(mp.x,e.getX());
end.y = Math.max(mp.y,e.getY());
client.broadcast(end,"end", selected,"release");
}
draw();
}
//start=null;
}
public void mouseDragged(MouseEvent e)
{
if(end==null)
end = new Point();
if(start==null)
start = new Point();
if(selected=="line")
{
end=e.getPoint();
client.broadcast(end,"end", selected,"drag");
}
else if(selected=="erase")
{
start=e.getPoint();
erase();
client.broadcast(start,"start", selected,"drag");
}
else if(selected=="elipse"||selected=="rect")
{
start.x = Math.min(mp.x,e.getX());
start.y = Math.min(mp.y,e.getY());
end.x = Math.max(mp.x,e.getX());
end.y = Math.max(mp.y,e.getY());
client.broadcast(start,"start", selected,"drag");
client.broadcast(end,"end", selected,"drag");
}
repaint();
}
@Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==elipse)
selected="elipse";
if(e.getSource()==line)
selected="line";
if(e.getSource()==rectangle)
selected="rect";
if(e.getSource()==save)
save();
if(e.getSource()==erase)
{
selected="erase";
erase();
}
}
}
class Button extends JButton
{
String name;
public Button(String name)
{
this.name=name;
Dimension buttonSize = new Dimension(35,35);
setMaximumSize(buttonSize);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//g2.setStroke(new BasicStroke(1.2f));
if (name == "line") g.drawLine(5,5,30,30);
if (name == "elipse") g.drawOval(5,7,25,20);
if (name== "rect") g.drawRect(5,5,25,23);
}
}
答案 0 :(得分:4)
尝试为每个用户维护一个面板,并将它们叠加在一起。只要背景是透明的,你应该看得很清楚。
修改:要实现图层,您可以尝试JLayeredPane。
答案 1 :(得分:1)
我没有看到任何处理来自客户端的请求的代码。假设在后台线程上发生这种情况,请确保使用SwingUtilities.invokeLater
在EDT上进行更改。从任何地方更新UI组件,但EDT将导致不可预测的行为。另请参阅Concurrency in Swing
此外,这种事情无法发挥作用:
if (name == "line") g.drawLine(5,5,30,30);
在Java中,==
运算符执行身份比较。如果name
和"line"
是同一个对象,则计算结果为true。如果它们引用不同的对象,它将评估为false,即使它们都具有相同的值。要比较相等性,您需要使用.equals()
方法。