Рисование с помощью холста и таймера - PullRequest
0 голосов
/ 02 апреля 2011

У меня проблема с холстом. Я хотел показать несколько движущихся шаров на холсте (анимация), но ничего не вижу, кроме черного фона.

Может кто-нибудь сказать мне ошибку в этом коде и как это будет работать, пожалуйста.

public CopyOfCleanBallPanel2() throws IOException, InterruptedException {

        frame = new JFrame("simple gaming loop in java");
        frame.setSize(BOX_WIDTH, BOX_WIDTH);
        frame.setResizable(false);

        displayCanvas = new CustomCanvas();
        displayCanvas.setLocation(0, 0);
        displayCanvas.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
        displayCanvas.setBackground(Color.BLACK);
        displayCanvas.setFont(new Font("Arial", Font.BOLD, 14));
        displayCanvas.setPreferredSize(new Dimension(CANVAS_WIDTH,CANVAS_HEIGHT));

        frame.add(displayCanvas);
        displayCanvas.requestFocus();

        frame.setLocationRelativeTo(null);

        try {
            this.aBall = (BallServer) Naming
                    .lookup("rmi://localhost/BouncingBalls");

        } catch (Exception e) {
            System.out.println("Exception: " + e);
        }


        frame.pack();
        frame.setVisible(true);

        aBall.start();
        startFrameTimer();  
    }

    /*
     * Initializes the frame (also game update) timer.
     */
    private void startFrameTimer() {
        frameTimer.schedule(new FrameTimerTask(), 1, GAME_TIMER_COOLDOWN);
    }

    public void updateSimulation() throws RemoteException {
        repaintCanvas();
    }
    /*
     * This method gets called by the timer. It updates the game simulation and
     * redraws it.
     */
    private void onFrameTimer() throws RemoteException {
        updateSimulation();
    }

    /*
     * Causes the whole canvas to get repainted.
     */
    private final void repaintCanvas() throws RemoteException  {
        Graphics g =  displayCanvas.getGraphics();
        drawworld(g);
    }

    private class FrameTimerTask extends TimerTask {
        public void run() {
            try {
                onFrameTimer();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }
    /*
     * This custom canvas overrides the paint method thus allowing for a custom
     * painting on the component.
     */
    private class CustomCanvas extends Canvas {
        @Override
        public void paint(Graphics g) {
            // Currently the game message gets drawn over the inner border
            // of the canvas so we have to repaint the whole thing.
            try {
                repaintCanvas();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }   
    public void drawworld(Graphics g) throws RemoteException {
            g.setColor(Color.BLACK);
             g.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

            System.out.println("i m in drawworld ");

            serBall = aBall.getState1(); ***// here it is remote call and there is thread going on suspension*** 

            for (int i = 0; i < currentNumBalls; i++) {
                g.setColor(serBall[i].getBallColor(velocity.getLength()));
                g
                        .fillOval((int) (serBall[i].position.getX() - serBall[i]
                                .getRadius()),
                                (int) (serBall[i].position.getY() - serBall[i]
                                        .getRadius()), (int) (2 * serBall[i]
                                        .getRadius()), (int) (2 * serBall[i]
                                        .getRadius()));

                // Draw our framerate and ball count
                g.setColor(Color.WHITE);
                g.drawString("FPS: " + currentFrameRate + " Balls: "
                        + currentNumBalls, 15, 15);
            }   
        }

P.S .: Я думал, что есть какая-то проблема с потоком, когда я вызываю удаленный метод и отрисовываю drawworld, либо поток находится в приостановленном состоянии, либо заблокирован

Пожалуйста, помогите.

Джибби Лала

Ответы [ 2 ]

3 голосов
/ 02 апреля 2011

При использовании Swing пользовательское рисование выполняется путем переопределения метода paintComponent () для JPanel (или JComponent), а не для Canvas.Canvas является компонентом AWT и не должен использоваться с Swing.См. Учебник Swing по Custom Painting для получения дополнительной информации и примеров.

Анимация должна выполняться с использованием таймера Swing, чтобы код выполнялся на EDT.В руководстве по Swing также есть раздел «Как использовать Swing Timers» и «Concurrency», который помогает объяснить эти концепции.

Метод repaintCanvas () не нужен.Чтобы перекрасить компонент, вы просто вызываете repaint () для компонента.Вы никогда не должны использовать метод getGraphics ().Все методы рисования уже получают класс Graphics в качестве параметра.Это объект Grapphics, который вы должны использовать для рисования.

2 голосов
/ 02 апреля 2011

Выглядит так, как будто вы смешиваете тяжелые и легкие компоненты , что требует некоторой осторожности. Кроме того, вы можете сравнить свой код с этим примером .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...