0

I'm trying to set up a multiThreaded server where a graphical-object is created for each thread.

The problem I have now is that I don't know how to map that graphical-object to "it's" thread.

Basically what I'm trying to do in the function addBallToThread is to call the class Graphics which is responsible for creating a ball. I want to map this ball to that specific thread, and then eventually remove the ball when the thread is closed.

If anyone could show me an example of this or help me with my existing code that would be very appreciated.

ClientThread:

public class ClientThread extends Thread{


    private static int numberOfClients = 0;
    protected static   ArrayList<ClientThread> allClients = new ArrayList<ClientThread>();
    //Create instance of this class for each new client^
    private final int  clientNumber = ++numberOfClients;
    private final      Socket socket;
    private final      BufferedReader in;
    private final      BufferedWriter out;
    private static     ArrayList<Graphics> Balls = new ArrayList<Graphics>();

    public ClientThread(Socket s) throws IOException {
        socket = s;
        in     = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out    = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        System.out.println("Thread Created For Client: "+clientNumber+"");
        System.out.println("Welcome client nr: #"+clientNumber+"");
        synchronized (this) {

            allClients.add(this); //add thread to new instance of class
            addBallToThread();    //connecting ball to thread?
        }

        start(); //starts thread, calls run
    }
    //###################### HERE ########################
    public void addBallToThread(){ 
        int totalClients = clientNumber;
        for(int i=1;i<=totalClients; ++i) {
            Balls.add((Graphics) allClients.iterator());
            //Creating one Graphics Object for every Client?
        }
    }

    public void run() {
        try {
            while (true) {
                String inline = in.readLine();
                System.out.println("BALL NR:"+Balls.size()+"CONNECTED TO: "+clientNumber);
                System.out.println("Client thread " + clientNumber + " received: " + inline);
                if (inline == null || inline.equals("quit")) break;
                System.out.println("You said :" + inline + ".");
                Iterator<ClientThread> i = allClients.iterator();
                    while (i.hasNext()) {
                        ClientThread t = i.next();
                        if (t != this)
                            System.out.print("From client " + clientNumber + ": " + inline);
                    }    
                } //while, while

            //############# IGNORE, not necessary ########### 
            System.out.println("Client thread " + clientNumber + ": exiting...");
        }
        catch(IOException e) {
            System.out.println("Client thread " + clientNumber + ": I/O error");
        }
        finally {
            try { socket.close(); }
            catch(IOException e) {
                System.out.println("Client thread " + clientNumber + ": Socket not closed!");
            }
            synchronized(this) {
                allClients.remove(allClients.indexOf(this));
            }
        } //finally
    } //run
}

Graphics:

public class Graphics{
    public ObservableList<Ball> balls = FXCollections.observableArrayList(); //add all created ball-objs to the array
    private static final Color[] COLORS = new Color[] { RED, BLUE };

    public Graphics() {
        //Creating a new Object every time Class is called?
        createBalls(1,10,20,10,20,0,0);
    }


    public void createBalls(int numBalls, double minRadius, double maxRadius, double minSpeed, double maxSpeed,
            double initialX, double initialY) {
        final Random rng = new Random();
        for (int i = 0; i < numBalls; i++) {
            double radius = minRadius + (maxRadius - minRadius) * rng.nextDouble();
            double mass = Math.pow((radius / 40), 3);

            final double speed = minSpeed + (maxSpeed - minSpeed) * rng.nextDouble();
            final double angle = 2 * PI * rng.nextDouble();
            Ball ball = new Ball(initialX, initialY, radius, speed * cos(angle), speed * sin(angle), mass);
            ball.getView().setFill(COLORS[i % COLORS.length]);
            // ball.getView().setFill(i==0 ? RED : TRANSPARENT);

            getBalls().add(ball); //add to FXCollection
        }
    }

    public ObservableList<Ball> getBalls() {
        return balls;
    }

    public void setBalls(ObservableList<Ball> balls) {
        this.balls = balls;
    }

} 
Joel
  • 5,732
  • 4
  • 37
  • 65
  • If you want to lookup by thread or by ball, you might want to take a look at http://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/BidiMap.html – falcon Nov 20 '17 at 19:53
  • 1
    Can you just add one more private field for ball in `ClientThread` class? – Mikita Harbacheuski Nov 20 '17 at 20:13
  • @NikitaGorbachevski yes, what did you have in mind? – Joel Nov 20 '17 at 20:14
  • 1
    I mean does it make sense just to create a field for ball and initialize it in `ClientThread` constructor . Then you have mapping between a ball and a `ClientThread`. – Mikita Harbacheuski Nov 20 '17 at 20:33
  • @NikitaGorbachevski hmm, could you perhaps write down what you mean as an example? Thanks – Joel Nov 20 '17 at 20:50
  • @Joel, please do not extend the `Thread` class; instead, consider introducing the implementation of the `Runnable` interface. Please refer to the [Defining and Starting a Thread (The Java™ Tutorials > Essential Classes > Concurrency)](https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html) article. – Sergey Vyacheslavovich Brunov Nov 21 '17 at 12:16
  • @SergeyBrunov "the `Thread` class itself implements `Runnable`, though its run method does nothing. An application can subclass Thread, providing its own implementation of run." – Joel Nov 21 '17 at 15:15
  • @Joel, yes. But, long story short, please prefer the first way mentioned in the article. The general (not article) keywords: separation of concerns, the single-responsibility principle, prefer composition over inheritance. You may want to know what other people think on this: [java - "implements Runnable" vs. "extends Thread"](https://stackoverflow.com/questions/541487). – Sergey Vyacheslavovich Brunov Nov 21 '17 at 15:37
  • 1
    I am not sure of what you are trying to achieve. Please explain your context a bit more. maybe paste all the code you have? – suenda Nov 21 '17 at 23:20
  • Completely agree with @suenda. Joel, could you please provide the description of the high-level (conceptual) goal that you are going to accomplish? – Sergey Vyacheslavovich Brunov Nov 24 '17 at 13:00

0 Answers0