Доска отлично работает как отдельный сервер, так и как простой сервер-клиент. Проблема возникла, когда мы добавили слой аутентификации (имя пользователя, добавление его в список пользователей и т. Д.). Я просто получаю серую коробку вместо панели рисования. Белая доска, созданная на стороне клиента, отображается в виде серого прямоугольника, даже если она создается до получения данных для чертежей. В результате я не умею рисовать, и это ломается. Я хочу получить отзывчивую панель рисования и как ее исправить.
Пожалуйста, извините за большой объем кода, который здесь размещен. Я думаю, что это необходимо, так как я не знаю, откуда возникла проблема
Закрытие сокета сервера заставило его работать. Но это противоречит цели распределенной доски. Используя оператор print, я обнаружил, что он висит в in.readUTF () в receiveData () в классе WhiteBoard.
SERVER
</p>
<pre><code>public class CreateWhiteBoard {
static int port = 9090;
static int counter = 0;
static String userName = "Server";
volatile static ArrayList<drawings> sumDraw = new ArrayList<drawings>();
static ArrayList<Socket> clientList = new ArrayList<Socket>();
static WhiteBoard newPad;
public static void main(String args[]) throws ClassNotFoundException, IOException {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
newPad = new WhiteBoard(userName);
newPad.setTitle("Server Side");
newPad.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//SessionManger
SessionManagerPanel sessPanel;
sessPanel= new SessionManagerPanel(port);
sessPanel.setVisible(true);
}
});
ServerSocketFactory factory = ServerSocketFactory.getDefault();
try (ServerSocket server = factory.createServerSocket(port)) {
System.out.println("Waiting for client connection to port number: " + port);
// Wait for connections.
while (true) {
Socket client = null;
try {
client = server.accept();
} catch (IOException ex) {
ex.printStackTrace();
}
counter++;
System.out.println("Client " + counter + ": Applying for connection! in port num: " + client.getPort());
// Start a new thread for a connection
ServerThread t = new ServerThread(client);
t.start();
}
} catch (IOException e) {
System.out.println("Unable to setup server, try another port.");
// System.exit(1);
}
}
public void drawToClient(drawings newOb) throws IOException {
DataOutputStream os;
for(Socket client:clientList) {
os = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
// oos = new ObjectOutputStream(client.getOutputStream());
String data = newOb.x1 + "," + newOb.y1 + "," + newOb.x2 + "," + newOb.y2 + "," + newOb.R +
"," + newOb.G + "," + newOb.B + "," + newOb.stroke + "," + newOb.type + "," + newOb.s1 + "," + newOb.s2;
os.writeUTF(data);
os.flush();
}
}
static class ServerThread extends Thread {
// Client sends the query here and this thread will produce the responses to the client. In this case, client sends the drawings here
// And the drawings will be combined with other drawings then send back to the client.
Socket client;
DataInputStream is;
DataOutputStream os;
ObjectOutputStream oos;
ObjectInputStream ois;
BufferedReader in;
ServerThread(Socket client) {
this.client = client;
clientList.add(client);
}
public void run() {
String clientDrawing;
try {
System.out.println(1);
os = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
System.out.println(2);
oos = new ObjectOutputStream(client.getOutputStream());
System.out.println(3);
is = new DataInputStream(new BufferedInputStream(client.getInputStream()));
String clientUserName = is.readUTF();
System.out.println(clientUserName);
if(clientUserName !=null) {
System.out.println(4);
System.out.println(5);
JOptionPane.showConfirmDialog(null, clientUserName + " wants to join your session", "Do you authorise?",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
System.out.println(6);
if (JOptionPane.NO_OPTION==0) {
System.out.println(clientUserName + " quit!");
os.writeUTF("No");
os.flush();
} else if (JOptionPane.YES_OPTION==0) {
System.out.println(clientUserName + "join!");
System.out.println("login success: id = " + counter+" , " + this.client);
os.writeUTF("Yes");
os.flush();
}
}
int count = 0;
System.out.println("Starting graphics");
Graphics g = newPad.getGraphics();
while (true) {
System.out.println(is==null);
String test = is.readUTF();
System.out.println(is==null);
String[] data = test.split(",");
System.out.println("data");
if(data.length == 11) {
drawings newDraw = newPad.new drawings();
newDraw.x1 = Integer.parseInt(data[0]);
newDraw.y1 = Integer.parseInt(data[1]);
newDraw.x2 = Integer.parseInt(data[2]);
newDraw.y2 = Integer.parseInt(data[3]);
}
for(Socket client:clientList) {
os = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
// oos = new ObjectOutputStream(client.getOutputStream());
os.writeUTF(test);
os.flush();
}
}
} catch (IOException e) {
System.out.println("IOException");
e.printStackTrace();
}
}
}
}
КЛИЕНТ (Проблема может быть здесь)
</p>
<pre><code>public class JoinWhiteBoard extends JFrame {
int x1,x2,y1,y2,curchoice;
DataInputStream is;
DataOutputStream os;
Graphics g;
WhiteBoard newPad;
WhiteBoard.drawings nb;
String userName="Thanks";
Socket client;
static boolean outcome = false;
public static void main(String args[]) throws IOException, ClassNotFoundException {
JoinWhiteBoard CP = new JoinWhiteBoard();
CP.creat();
}
public void welcomeFrame() throws IOException, ClassNotFoundException{
boolean outcome;
JFrame welcomeFrame = new JFrame("Welcome to PowerPuff Paint");
// create a object of JTextField with 16 columns and a given initial text
JTextField welcomeText = new JTextField("Enter username",16);
// create a new button
//产生一个Socket类用于连接�务器,并得到输入�
public void creat() {
try {
System.out.println(1);
client =new Socket("localhost", 9090);
// is = new DataInputStream(new BufferedInputStream(client.getInputStream()));
System.out.println(2);
is = new DataInputStream(client.getInputStream()
);
System.out.println(3);
iss = new ObjectInputStream(client.getInputStream());
System.out.println(4);
os = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
// BufferedReader response = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
// BufferedWriter request = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
System.out.println(userName);
os.writeUTF(userName);
System.out.println(5);
os.flush();
System.out.println(6);
if(is.readUTF().equals("Yes")){
try{
ShowUI();
}catch (ClassNotFoundException e){
e.printStackTrace();
}
}else{
System.exit(0);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//æž„é€ å®¢æˆ·ç«¯ç•Œé�¢å¹¶å�¯åŠ¨çº¿ç¨‹
public void ShowUI() throws IOException, ClassNotFoundException {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(userName + client);
newPad = new WhiteBoard(userName, client);
}
}
WHITEBOARD (проблема может быть здесь)
</p>
<pre><code>public class WhiteBoard extends JFrame
{
CreateWhiteBoard serverPad = new CreateWhiteBoard();
private JButton choices[];
private String names[] = {
"New", "Open", "Save", "Pencil", "Line", "Rect", "fRect", "Oval", "fOval", "Circle",
"fCircle", "RoundRect", "frRect", "Rubber", "Color", "Stroke", "Word"};
private String styleNames[] = {
" 宋体 ", " 隶书 ", " Times New Roman ", " Serif ",
" Monospaced ", " SonsSerif ", " Garamond "
};
private Icon items[];
private Color color = Color.black;
private JLabel statusBar;
public DrawPanel drawingArea;
private ObjectInputStream input;
private ObjectOutputStream output;
private int width = 500, height = 500;
private volatile int currentChoice = 3;
private float stroke = 1.0f;
int R, G, B;
int genre1, genre2;
int index = 0;
String styleCur;
JToolBar buttonPanel;
JCheckBox bold, italic;
JComboBox<String> styles;
ArrayList<drawings> iArray = new ArrayList<drawings>();
DataOutputStream out;
DataInputStream in;
ObjectOutputStream oos;
ObjectInputStream ois;
int number = 0;
Socket client;
private static int counter = 0;
private static int port = 9090;
String userName;
volatile drawings newOb = null;
public WhiteBoard(String userName) {
super("Distributed WhiteBoard1");
this.userName = userName;
createWB();
}
public WhiteBoard(String userName, Socket client) throws IOException, ClassNotFoundException {
super(userName);
out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
oos = new ObjectOutputStream(client.getOutputStream());
in = new DataInputStream(new
BufferedInputStream(client.getInputStream()));
// ois = new ObjectInputStream(client.getInputStream());
this.userName = userName;
this.client = client;
createWB();
receiveData();
}
public void createWB()
items = new ImageIcon[names.length];
drawingArea = new DrawPanel();
choices = new JButton[names.length];
buttonPanel = new JToolBar(JToolBar.HORIZONTAL);
ButtonHandlerx handlerx = new ButtonHandlerx();
ButtonHandlery handlery = new ButtonHandlery();
for (int i = 0; i < choices.length; i++) {
items[i] = new ImageIcon("pic/" + names[i] + ".png");
choices[i] = new JButton("", items[i]);
choices[i].setToolTipText(tipText[i]);
buttonPanel.add(choices[i]);
}
for (int i = 3; i < choices.length - 3; i++) {
choices[i].addActionListener(handlery);
}
for (int i = 1; i < 4; i++) {
choices[choices.length - i].addActionListener(handlerx);
}
JPanel wordPanel = new JPanel();
buttonPanel.add(bold);
buttonPanel.add(italic);
buttonPanel.add(styles);
styles.setMinimumSize(new Dimension(80, 26));
styles.setMaximumSize(new Dimension(120, 26));
Container cont = getContentPane();
super.setJMenuBar(bar);
cont.add(buttonPanel, BorderLayout.NORTH);
cont.add(drawingArea, BorderLayout.CENTER);
cont.add(statusBar, BorderLayout.SOUTH);
createNewItem();
setSize(width, height);
setVisible(true);
}
public class ButtonHandlery implements ActionListener {
public void actionPerformed(ActionEvent e) {
for (int j = 3; j < choices.length - 3; j++) {
if (e.getSource() == choices[j]) {
currentChoice = j;
createNewItem();
repaint();
}
}
}
}
public class ButtonHandlerx implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == choices[choices.length - 3]) {
chooseColor();
}
if (e.getSource() == choices[choices.length - 2]) {
setStroke();
}
if (e.getSource() == choices[choices.length - 1]) {
JOptionPane.showMessageDialog(null,
"Please click the drawing pad to choose the word input position",
"Hint", JOptionPane.INFORMATION_MESSAGE);
currentChoice = 14;
createNewItem();
repaint();
}
}
}
class mouseEvent1 extends MouseAdapter{
public void mousePressed(MouseEvent e) {
statusBar.setText(" Mouse Pressed @:[" + e.getX() +
", " + e.getY() + "]");
iArray.get(index).x1 = iArray.get(index).x2 = e.getX();
iArray.get(index).y1 = iArray.get(index).y2 = e.getY();
if (currentChoice == 3 || currentChoice == 13) {
iArray.get(index).x1 = iArray.get(index).x2 = e.getX();
iArray.get(index).y1 = iArray.get(index).y2 = e.getY();
index++;
createNewItem();
}
if (currentChoice == 14) {
iArray.get(index).x1 = e.getX();
iArray.get(index).y1 = e.getY();
String input;
input = JOptionPane.showInputDialog(
"Please input the text you want!");
iArray.get(index).s1 = input;
iArray.get(index).x2 = genre1;
iArray.get(index).y2 = genre2;
iArray.get(index).s2 = styleCur;
index++;
createNewItem();
drawingArea.repaint();
}
}
public void mouseReleased(MouseEvent e) {
statusBar.setText(" Mouse Released @:[" + e.getX() +
", " + e.getY() + "]");
if (currentChoice == 3 || currentChoice == 13) {
iArray.get(index).x1 = e.getX();
iArray.get(index).y1 = e.getY();
}
iArray.get(index).x2 = e.getX();
iArray.get(index).y2 = e.getY();
newOb = iArray.get(index);
repaint();
index++;
createNewItem();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
\
}
}
class mouseEvent2 implements MouseMotionListener{
ObjectOutputStream oss;
public void mouseDragged(MouseEvent e) {
statusBar.setText(" Mouse Dragged @:[" + e.getX() +
", " + e.getY() + "]");
if (currentChoice == 3 || currentChoice == 13) {
iArray.get(index - 1).x1 = iArray.get(index).x2 = iArray.get(index).x1 = e.getX();
iArray.get(index - 1).y1 = iArray.get(index).y2 = iArray.get(index).y1 = e.getY();
newOb = iArray.get(index);
index++;
createNewItem();
} else {
iArray.get(index).x2 = e.getX();
iArray.get(index).y2 = e.getY();
}
try {
if (!userName.equals("Server")){
sendData(newOb);
}
else {
serverPad.drawToClient(newOb);
}
} catch (IOException e1) {
e1.printStackTrace();
System.out.println("IOException");
}
repaint();
}
public void mouseMoved(MouseEvent e) {
}
}
public void sendData(drawings newOb) throws IOException {
String data = newOb.x1 + "," + newOb.y1 + "," + newOb.x2 + "," + newOb.y2 + "," + newOb.R + "," + newOb.G + "," + newOb.B + "," + newOb.stroke + "," + newOb.type + "," + newOb.s1 + "," + newOb.s2;
out.writeUTF(data);
out.flush();
}
public void receiveData() throws IOException, ClassNotFoundException {
while (true) {
String test = in.readUTF();
String[] data = test.split(",");
System.out.println(3);
if(data.length == 11) {
drawings newDraw = new drawings();
newDraw.x1 = Integer.parseInt(data[0]);
newDraw.y1 = Integer.parseInt(data[1]);
newDraw.x2 = Integer.parseInt(data[2]);
newDraw.y2 = Integer.parseInt(data[3]);
newDraw.R = Integer.parseInt(data[4]);
newDraw.G = Integer.parseInt(data[5]);
newDraw.B = Integer.parseInt(data[6]);
newDraw.stroke = Float.parseFloat(data[7]);
newDraw.type = Integer.parseInt(data[8]);
newDraw.s1 = data[9];
newDraw.s1 = data[10];
createNewItemInClient(newDraw);
}
S
}
}
class DrawPanel extends JPanel {
public DrawPanel() {
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
setBackground(Color.white);
addMouseListener(new mouseEvent1());
addMouseMotionListener(new mouseEvent2());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int j = 0;
while (j <= index) {
draw(g2d, iArray.get(j));
j++;
}
}
void draw(Graphics2D g2d, drawings i) {
i.draw(g2d);
}
}
void createNewItem() {
if (currentChoice == 14)
{
drawingArea.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
} else {
drawingArea.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
switch (currentChoice) {
case 3:
iArray.add(index, new Pencil());
break;
case 4:
iArray.add(index, new Line());
break;
case 5:
iArray.add(index, new Rect());
break;
case 6:
iArray.add(index, new fillRect());
break;
case 7:
iArray.add(index, new Oval());
break;
case 8:
iArray.add(index, new fillOval());
break;
case 9:
iArray.add(index, new Circle());
break;
case 10:
iArray.add(index, new fillCircle());
break;
case 11:
iArray.add(index, new RoundRect());
break;
case 12:
iArray.add(index, new fillRoundRect());
break;
case 13:
iArray.add(index, new Rubber());
break;
case 14:
iArray.add(index, new Word());
break;
}
iArray.get(index).type = currentChoice;
System.out.println("Set index: "+index+" choice as "+currentChoice);
iArray.get(index).R = R;
iArray.get(index).G = G;
iArray.get(index).B = B;
iArray.get(index).stroke = stroke;
}
public void testClient() {
System.out.println("testtesttest: "+index);
index++;
}
public void createNewItemInClient(drawings infoOb) {
iArray.get(index).x1 = infoOb.x1;
iArray.get(index).y1 = infoOb.y1;
iArray.get(index).x2 = infoOb.x2;
iArray.get(index).y2 = infoOb.y2;
currentChoice = infoOb.type;
// ===== testing clause
if (index > 1){
if (currentChoice != iArray.get(index - 1).type) {
System.out.println("index:"+index+" currentChoice "+currentChoice+" index-1~choice: "+iArray.get(index - 1).type);
}
}
// =====
R = infoOb.R;
G = infoOb.G;
B = infoOb.B;
stroke = infoOb.stroke;
//System.out.println();
index ++;
repaint();
createNewItem();
}
public void setStroke() {
String input;
input = JOptionPane.showInputDialog(
"Please input the size of stroke!");
stroke = Float.parseFloat(input);
iArray.get(index).stroke = stroke;
}
public class drawings implements Serializable
{
public drawings () {}
public int x1, y1, x2, y2;
public int R, G, B;
public float stroke;
public int type;
public String s1;
public String s2;
void draw(Graphics2D g2d) {};
}
class Pencil extends drawings
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
g2d.drawLine(x1, y1, x2, y2);
}
}
class Line extends drawings
{
void draw(Graphics2D g2d) {
g2d.setPaint(new Color(R, G, B));
g2d.setStroke(new BasicStroke(stroke,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
g2d.drawLine(x1, y1, x2, y2);
}
}
}
СОПУТСТВУЮЩИЕ КЛАССЫ
МЕНЕДЖЕР СЕССИИ </p>
<pre><code>public class SessionManagerPanel extends JFrame{
/**
*
*/
private Container c = getContentPane();
private static final long serialVersionUID = 1L;
private int port;
private JPanel sessionPanel=new JPanel();
private JPanel sessionInfo;
private JLabel sessionText;
private JPanel userInfo;
@SuppressWarnings("rawtypes")
private JList userList;
private JPanel sessButtPnel;
private static SessionList sessList;
public SessionManagerPanel(int port) {
this.port=port;
String text = null;
sessList = new SessionList(new ArrayList<User>());
setTitle("Session Manager");
//Closing window event
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
try {
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
//aesthetics
JDialog.setDefaultLookAndFeelDecorated(true);
int response = JOptionPane.showConfirmDialog(null,
"Are you sure to exit?", "Exit",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (response == JOptionPane.NO_OPTION) {
} else if (response == JOptionPane.YES_OPTION) {
System.exit(1);
} else if (response == JOptionPane.CLOSED_OPTION) {
}
}
});
}catch (Exception e) {
JOptionPane.showMessageDialog(null, "Unkown Error", "warning",
JOptionPane.ERROR_MESSAGE);
}
System.out.println("Tile and window closing set");
//THis makes it adaptable to different monitor sizes
//THIS IS COPIED-OPTIONAL
Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
int width = 0;
int height = 0;
width = screen.width;
height = screen.height;
if (width < 1024 || height < 680) {
this.setSize(width, height);
this.setExtendedState(Frame.MAXIMIZED_BOTH);
} else {
this.setSize(600, 600);
this.setLocationRelativeTo(null);
}
//THIS IS COPIED- SME of this is OPTIONAL
//Setting up the list
sessionPanel.setLayout(new BorderLayout());
sessionInfo = new JPanel();
//This is not displayed-get rid of
this.sessionText = new JLabel("new server has been start on port <br>");
text = "Port:";
text += this.port;
this.sessionText.setText(text);
sessionInfo.add(sessionText);
sessionInfo.setLayout(new GridLayout(1, 0, 15, 15));
sessionInfo.setBounds(new Rectangle(0, 0, 100, 160));
sessionInfo.setBorder(new TitledBorder(null, "Server Info",
TitledBorder.LEFT, TitledBorder.TOP));
sessionPanel.add(sessionInfo, BorderLayout.NORTH);
userInfo = new JPanel();
userList = new JList(sessList);
userInfo.setLayout(new GridLayout(1, 0, 15, 15));
userInfo.setBounds(new Rectangle(0, 0, 100, 160));
userInfo.setBorder(new TitledBorder(null, "User List",
TitledBorder.LEFT, TitledBorder.TOP));
userList.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
userInfo.add(userList);
sessButtPnel = new JPanel();
JButton kick = new JButton("Kick");
JButton fresh = new JButton("Refresh");
//Kick function
kick.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sessList.removeElement(userList.getSelectedIndex());
System.out.println("Print something");
}
});
//Refresh function
fresh.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
sessList.refresh();
System.out.println("Print something");
}
});
userInfo.add(new JScrollPane(userList), BorderLayout.CENTER);
sessButtPnel.add(kick, BorderLayout.WEST);
sessButtPnel.add(fresh, BorderLayout.EAST);
sessionPanel.add(userInfo, BorderLayout.CENTER);
sessionPanel.add(sessButtPnel, BorderLayout.SOUTH);
c.add(sessionPanel);
}
public void update(User newUser) {
sessList.add(newUser);
}
}
СПИСОК СЕССИЙ </p>
<pre><code>public class SessionList extends AbstractListModel<Object> {
ArrayList<User> uList = new ArrayList<User>();
public void refresh() {
fireContentsChanged(this, 0, getSize());
}
public SessionList(ArrayList<User> users) {
this.uList = users;
fireContentsChanged(this, 0, getSize());
}
public void add(User element) {
if (uList.add(element)) {
fireContentsChanged(this, 0, getSize());
}
}
public void addAll(User elements[]) {
Collection<User> c = Arrays.asList(elements);
uList.addAll(c);
fireContentsChanged(this, 0, getSize());
}
public void clear() {
uList.clear();
fireContentsChanged(this, 0, getSize());
}
}
USER </p>
<pre><code>public class User implements Serializable {
String name = "Guest";
int id;
Socket socket;
public User(String myname) {
this.name= myname;
}
public User(int id, String name,Socket socket) {
this.name = name;
this.socket = socket;
this.id = id;
}
}
Нет ошибок. Появляется серый прямоугольник, и он висит в in.readUTF () после ввода receiveData ().