DoubleBuffering в Java - PullRequest
       19

DoubleBuffering в Java

1 голос
/ 16 мая 2010

У меня возникли проблемы с внедрением DoubleBuffer в мою программу. Прежде чем упасть в обморок от стены текста, вы должны знать, что многое из этого есть на тот случай, если вам нужно это знать. Фактическое место, где я думаю, что у меня проблемы, - это один метод.

Недавно я посмотрел учебник по gpwiki о двойной буферизации и решил попробовать внедрить код, который у них был, в код, который я пытаюсь реализовать в Doublebuffer. Я получаю следующую ошибку: " java.lang.IllegalStateException: у компонента должен быть допустимый одноранговый узел ".

Я не знаю, имеет ли это какое-то значение, если вы это знаете или нет, но ниже приведен код с методом main. Это просто фрейм, в котором отображается класс ChronosDisplay. Я опустил нерелевантный код с "..."

public class CDM extends JFrame
{
    public CDM(String str)
    {
        super("CD:M - "+str);
        try
        {
            ...
            ChronosDisplay theGame = new ChronosDisplay(str);
            ((Component)theGame).setFocusable(true);
            add(theGame);
        }
        catch(Exception e)
        {
            System.out.println("CDM ERROR: " +e);
        }
    }
    public static void main( String args[] )
    {
        CDM run = new CDM("DP_Mini");
    }
}

Вот код, в котором, я думаю, проблема заключается (я думаю, что проблема в методе paint ()). Этот класс отображается в классе CDM

public class ChronosDisplay extends Canvas implements  Runnable
{
    String mapName;
    public ChronosDisplay (String str)
    {
        mapName = str;
        new Thread(this).start();
        setVisible(true);
        createBufferStrategy(2);
    }
    public void paint( Graphics window )
    {
        BufferStrategy b = getBufferStrategy();
        Graphics g = null; 
        window.setColor(Color.white);
        try
        {
             g = b.getDrawGraphics();
            paintMap(g);
            paintUnits(g);
            paintBullets(g);
        }
        finally
        { g.dispose(); }
        b.show();
        Toolkit.getDefaultToolkit().sync(); 
    }
    public void paintMap( Graphics window )
    {
        TowerMap m = new TowerMap();
        try
        {
            m = new TowerMap(mapName);
            for(int x=0; x<m.getRows()*50; x+=50)
            {
                for(int y = 0; y<m.getCols()*50; y+=50)
                    {
                        int tileType = m.getLocation(x/50,y/50);
                        Image img;
                        if(tileType == 0)
                        {
                            Tile0 t = new Tile0(x,y);
                            t.draw(window);
                        }
                        ...// More similar if statements for other integers
            }
            catch(Exception e) ...
    }
    ...// Additional methods not shown here
    public void run()
    {
        try
        {
            while(true)
            {
                Thread.currentThread().sleep(20);
                repaint();
            }
        }
        catch(Exception e) ...
    }
}

Если вам интересно (я сомневаюсь, что это важно), метод draw () в классе Tile0:

public void draw( Graphics window )
{
    window.drawImage(img,getX(),getY(),50,50,null);
}

Любые указатели, советы или решения приветствуются. Спасибо за ваше время! : D

Ответы [ 3 ]

1 голос
/ 16 мая 2010

По умолчанию Swing имеет двойную буферизацию, поэтому вам не нужно реализовывать его самостоятельно.

Вы не должны использовать класс Canvas в приложении Swing. То есть не смешивайте компоненты AWT и Swing.

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

1 голос
/ 11 июня 2010

Переопределите addNotify() и создайте BufferStrategy оттуда:

public ChronosDisplay (String str)
{
    mapName = str;
    new Thread(this).start();
    // Note: no createBufferStrategy() or setVisible()
}

public void addNotify() {
    super.addNotify();
    createBufferStrategy(2);
}
0 голосов
/ 16 мая 2010

Обычно эта ошибка в отношении двойной буферизации означает, что цель еще не видна. Попробуйте нажать начало потока после того, как окно станет видимым и стратегия двойного буфера будет создана

...