2014-10-22 7 views
0

Я пытаюсь инициализировать глобальную переменную paintcall объекту ballGUI, который уже существует. Я должен сделать это, чтобы иметь возможность вызвать метод repaint в моей функции запуска для multithreadng так, чтобы не был создан новый GUI, который каждый отдельный шар. Импорт оставлен в космос.Инициализация существующего объекта

import java.awt.Color; 

public class BallT extends Thread implements Runnable { 

    private static int xcord, ycord, ychange, xchange; 
    private static boolean xUp; 
    private static boolean yUp; 
    private Color color; 
    private BallGUI paintcall=//? existing object BallGUI ; 

    public BallT(int x, int y) { 
    yUp = false; 
    xUp = false; 
    xcord = x; 
    ycord = y; 
    color = new Color((int) Math.random(), (int) Math.random(), 
     (int) Math.random()); 
    } 

    public Color getColor() { 
    return color; 
    } 

    public int getX() { 
    return xcord; 
    } 

    public int getY() { 
    return ycord; 
    } 

    public void run() { 
    while (true) { 
     try { 
     Thread.sleep(50); 
     } catch (InterruptedException e) { 
     } 
     if (xUp == true) { 
     xcord = xcord + xchange; 
     } else { 
     xcord = xcord - xchange; 
     } 
     if (yUp == true) { 
     ycord = ycord + ychange; 
     } else { 
     ycord = ycord - ychange; 
     } 
     if (xcord <= 0) { 
     xUp = true; 
     xchange = (int) Math.random() * 5; 
     } else if (xcord > 340) { 
     xUp = false; 
     xchange = (int) Math.random() * 5; 
     } 
     if (ycord <= 0) { 
     yUp = true; 
     ychange = (int) Math.random() * 5; 
     } else if (ycord > 340) { 
     yUp = false; 
     ychange = (int) Math.random() * 5; 
     } 
     paintcall.repaint(); 
    } 

    } 

} 



@SuppressWarnings("serial") 
public class BallGUI extends JFrame { 

    public JPanel ballappear; 
    private final int maxBalls = 20; 
    private BallT[] balls; 
    private int count; 
    private ExecutorService threadPool = Executors.newCachedThreadPool(); 

    public BallGUI() { 
    super("Bouncing"); 
    ballappear = new JPanel(); 
    count = 0; 
    balls = new BallT[20]; 
    addMouseListener(new MouseAdapter() { 
     public void mousePressed(MouseEvent e) { 
     makeBall(e); 
     } 
    }); 
    add(ballappear); 

    } 

    private void makeBall(MouseEvent e) { 
    if (count < maxBalls - 1) { 
     int x = e.getX(); 
     int y = e.getY(); 
     balls[count] = new BallT(x, y); 
     threadPool.execute(balls[count]); 
     count++; 
    } 

    } 

    @Override 
    public void paint(Graphics g) { 
    super.paint(g); 
    for (int i = 0; i < count; i++) { 
     g.setColor(Color.BLACK); 
     g.fillOval(balls[i].getX(), 340, 10, 10); 
     g.setColor(balls[i].getColor()); 
     g.fillOval(balls[i].getX(), balls[i].getY(), 10, 10); 
    } 
    } 

} 
+0

Вам понадобится конструктор, который взял экземпляр этого класса. И я не понимаю, зачем вам это нужно. Если это глобальный, у вас может быть только один мяч. –

+0

Один мяч за нить, проблема заключается в том, что метод repaint перерисовывает новый BallGUI, а не существующий, на котором шар существует. –

+0

Вы не должны подклассы Thread, если вы не хотите внедрять пользовательский поток! Реализация Runnable достаточна в вашем случае! – isnot2bad

ответ

0

Во-первых, простое решение - изменить конструктор BallT взять экземпляр BallGUI:

public BallT(int x, int y, BallGUI ballGUI) { 
    this.paintcall = ballGUI; 
    yUp = false; 
    //... 

Далее, проходят в случае, во время строительства на объекте GUI:

private void makeBall(MouseEvent e) { 
    if (count < maxBalls - 1) { 
     // ... 
     balls[count] = new BallT(x, y, this); 
    } 
} 

Однако , это возвращается к началу в соответствии с хорошей практикой проектирования Model-View-Controller (MVC). Как правило, представление (BallGUI) должно знать о модели (BallT), но модель должна быть не осведомлена о представлении. Ваш BallGUI уже поддерживает список BallT, который, по-видимому, запрашивает в методе paint(). Я бы подумал, что у контроллера есть ответственность за вызов метода updatePosition() на каждом BallT по очереди, а затем вызов функции repaint() в графическом интерфейсе. Это также будет иметь то преимущество, что вы не создаете новый поток для каждого шара, а просто нужен один поток контроллера.

+0

Это сработало, спасибо вам большое. Мои прыгающие шары работают чудесно сейчас :) –