Проблема с отображением Canvas и Panel на Frame для анимации - PullRequest
1 голос
/ 14 марта 2011

У меня проблема с холстом Jpanel и мне нужно оптимизированное решение я получил этот дизайн из одного сообщения на этом форуме.

У меня есть три класса:

один для анимации, которая представляет собой холст (BallPanel), один - для кадра (основной), а другой - панель для управления поворотом (ControlPanel)

Main выполняет рендеринг и Controlpanel, и BallPanel, , но в итоге я не вижу рендеринга drawworld () из BallPanel, но могу только ControlPanel .

Я не вижу анимацию и черный фон, кажется, что панель управления находится на рамке, а холст (черный фон) находится позади или под этим или где-то, но невидим

BallPanel:

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

        } catch (Exception e) {
            System.out.println("Exception: " + e);
        }
        box = new Box(0, 0, BOX_WIDTH, BOX_HEIGHT);
        setPreferredSize(new Dimension(800, 600));
        setIgnoreRepaint(true);

        // Wire up Events
//      MouseHandler mouseHandler = new MouseHandler();
//      addMouseMotionListener(mouseHandler);
//      addMouseListener(mouseHandler);
    }



public void drawworld() throws RemoteException {

        if (strategy == null || strategy.contentsLost())
        {
            // Create BufferStrategy for rendering/drawing
            this.createBufferStrategy(2);
            strategy = getBufferStrategy();
            Graphics g = strategy.getDrawGraphics();
            this.g2 = (Graphics2D) g;
        }

        // Turn on anti-aliasing
        this.g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    //  box.draw(this.g2); // this can be another but it's also not working

        // Render Background
        this.g2.setColor(Color.BLACK);
        this.g2.fillRect(0, 0, getWidth(), getHeight());

        serball = aBall.getState();// other version UNcomment this line

        for (int i = 0; i < currentNumBalls; i++) {
            this.g2.setColor(serball[i].getBallColor(velocity.getLength()));
            this.g2
                    .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()));

        }


public void mainLoop() {

        long previousTime = System.currentTimeMillis();
        long currentTime = previousTime;
        long elapsedTime;
        long totalElapsedTime = 0;
        int frameCount = 0;

        while (true) {
            currentTime = System.currentTimeMillis();
            elapsedTime = (currentTime - previousTime); // elapsed time in
            // seconds
            totalElapsedTime += elapsedTime;
            if (totalElapsedTime > 1000) {
                currentFrameRate = frameCount;
                frameCount = 0;
                totalElapsedTime = 0;
            }


                try {
                    drawworld();
                } catch (RemoteException e1) {
                    e1.printStackTrace();
                }


            try {
                Thread.sleep(5);
            } catch (Exception e) {
                e.printStackTrace();
            }

            previousTime = currentTime;
            frameCount++;

        }
    }


public void start()
    {
        mainLoop();
    }

Основной класс выше start () звонит отсюда:

public static void main(String[] args)
    {


                JFrame frame = new JFrame("BallBounce");

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.Y_AXIS));


                BallPanel ballCanvas = new BallPanel();

                ControlPanel controlPanel = new ControlPanel(ballCanvas);

                frame.getContentPane().add(ballCanvas);
                frame.getContentPane().add(controlPanel);
                frame.pack();
                frame.setVisible(true);

                ballCanvas.start();
        }

это панель управления, которая работает как контроллер:

public class ControlPanel extends JPanel {

    private BallPanel mainPanel;
    private JButton resetButton;

    public ControlPanel(BallPanel mainPanel)
    {
        this.setPreferredSize(new Dimension(200, 60));
        this.setMaximumSize(new Dimension(5000, 100));
        this.mainPanel = mainPanel;

....
..
..
private class ButtonHandler implements ActionListener
    {

        public void actionPerformed(ActionEvent e) 
        {
            JButton source = (JButton)e.getSource();

            if (source == resetButton)
            {
                mainPanel.clearBalls();
            }

Большое спасибо за любую помощь и за то, как мы справились с таким графическим интерфейсом с RMI-анимацией и управлением качанием для взаимодействия / управления этим Может кто-нибудь сказать, оптимизированный способ. Джибби Лала

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

кросс-пост: http://www.coderanch.com/forums/jforum?module=posts&action=edit&post_id=2406332&start=0

Я сделал это с таймером, но проблемы не исчезли, пожалуйста, помогите:

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();// other version UNcomment this line

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

            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);
            }   
        }

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

1 Ответ

1 голос
/ 14 марта 2011

Это похоже на проблему потока, поскольку мне кажется, что вы вызываете while (true) и Thread.sleep (...) в EDT, главном потоке Swing. Вы читали о Параллельности в Swing ? Если нет, проверьте статью, связанную с внутри. Также настоятельно рекомендуется использовать Swing Timer для управления анимацией вместо while (true) и Thread.sleep (...).

...