2017-11-19 2 views
1

저는 캔버스가있는 JFrame을 만들었고 그 캔버스에 그리기를 원합니다. 나중에 캔버스가 여러 번 업데이트 될 것이므로 버퍼링 전략을 사용하고 있습니다. 여기에 코드입니다 :버퍼 전략을 사용하여 그릴 그래픽 객체 받기

package mainPackage; 

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.image.BufferStrategy; 

import javax.swing.JFrame; 

public class TickPainter { 
    //just some presets for a window. 
    public static JFrame makeWindow(String title, int width, int height) { 
     JFrame mainWindow = new JFrame(); 
     mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainWindow.setSize(width, height); 
     mainWindow.setVisible(true); 
     mainWindow.setLocationRelativeTo(null); 
     mainWindow.setTitle(title); 

     return mainWindow;  
    } 

    public static void main(String[] args) { 

     JFrame mainWindow = makeWindow("Practice", 800, 600); 
     Canvas mainCanvas = new Canvas(); 
     mainWindow.add(mainCanvas); 
     mainCanvas.setSize(mainWindow.getWidth(), mainWindow.getHeight()); 
     mainCanvas.setBackground(Color.white); 
     mainCanvas.createBufferStrategy(3); 
     BufferStrategy bufferStrat = mainCanvas.getBufferStrategy(); 

     Graphics g = bufferStrat.getDrawGraphics(); 
     g.setColor(Color.black); 
     g.fillRect(250, 250, 250, 250); 
     g.dispose(); 
     bufferStrat.show(); 
    } 
} 

의도 한대로, 내가 정말 여기 분명 뭔가를 놓친 나는 단지 그것을 볼 수없는 것 같은 느낌 검은 사각형을 그립니다하지 않는 프로그램. 현재이 프로그램은 그냥 빈 흰색 캔버스를 만듭니다. 문제의 일부인 것처럼 느낄 수있는 것은 버퍼가 사각형보다 빨리 프레임을 전달한다는 것입니다.하지만이 프레임을로드 할 프레임이 없으므로이 작업을 수행하는 이유를 알 수 없습니다.

+0

먼저 [JavaDocs] (https://docs.oracle.com/javase/8/docs/api/java/awt/image/BufferStrategy.html)와 [tutorial] (https : // docs. oracle.com/javase/tutorial/extra/fullscreen/bufferstrategy.html), 그들은 어떻게 여러분이'BufferStrategy'를 어떻게 사용하는지에 대한 귀중한 예를 제공합니다. – MadProgrammer

답변

1

BufferStrategy에는 렌더링 할 수 있어야하는 몇 가지 초기 요구 사항이 있습니다. 또한 작동 방식의 특성으로 인해 실제로 하드웨어 레이어에서 허용하기 전에 페인트 단계를 여러 번 반복해야 할 수도 있습니다.

나는 JavaDocstutorial 통과하는 것을 권장합니다, 그들은 당신이 BufferStrategy

다음 예제를 사용하는 가정하고 방법에 귀중한 예를 제공은 기본 구성 요소로 Canvas를 사용하고 사용자 정의 내에서 렌더링 루프를 설정 Thread. 그것은

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.image.BufferStrategy; 
import java.util.concurrent.atomic.AtomicBoolean; 
import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       TestCanvas canvas = new TestCanvas(); 

       JFrame frame = new JFrame(); 
       frame.add(canvas); 
       frame.setTitle("Test"); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       canvas.start(); 
      } 
     }); 
    } 

    public class TestCanvas extends Canvas { 

     private Thread thread; 
     private AtomicBoolean keepRendering = new AtomicBoolean(true); 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     public void stop() { 
      if (thread != null) { 
       keepRendering.set(false); 
       try { 
        thread.join(); 
       } catch (InterruptedException ex) { 
        ex.printStackTrace(); 
       } 
      } 
     } 

     public void start() { 
      if (thread != null) { 
       stop(); 
      } 

      keepRendering.set(true); 
      thread = new Thread(new Runnable() { 
       @Override 
       public void run() { 

        createBufferStrategy(3); 

        do { 
         BufferStrategy bs = getBufferStrategy(); 
         while (bs == null) { 
          System.out.println("get buffer"); 
          bs = getBufferStrategy(); 
         } 
         do { 
          // The following loop ensures that the contents of the drawing buffer 
          // are consistent in case the underlying surface was recreated 
          do { 
           // Get a new graphics context every time through the loop 
           // to make sure the strategy is validated 
           System.out.println("draw"); 
           Graphics graphics = bs.getDrawGraphics(); 

           // Render to graphics 
           // ... 
           graphics.setColor(Color.RED); 
           graphics.fillRect(0, 0, 100, 100); 
           // Dispose the graphics 
           graphics.dispose(); 

           // Repeat the rendering if the drawing buffer contents 
           // were restored 
          } while (bs.contentsRestored()); 

          System.out.println("show"); 
          // Display the buffer 
          bs.show(); 

          // Repeat the rendering if the drawing buffer was lost 
         } while (bs.contentsLost()); 
         System.out.println("done"); 
         try { 
          Thread.sleep(100); 
         } catch (InterruptedException ex) { 
          ex.printStackTrace(); 
         } 
        } while (keepRendering.get()); 
       } 
      }); 
      thread.start(); 
     } 

    } 

} 

BufferStrategy의 요점은 당신에게 도장 공정을 완벽하게 제어를 제공하는 것입니다, 기억, 그래서 정상적인 도장 공정 밖에서 작동합니다 ... 아주 기본적인,하지만 당신이 구현해야 할 것 기본 개념을 보여줍니다 AWT와 Swing이 일반적으로 구현합니다.

"캔버스가 나중에 여러 번 업데이트 될 것이므로 버퍼링 전략을 사용하고 있습니다." - "직접 하드웨어"솔루션을 사용하기 전에, d 스윙 Timer과 일반적인 페인팅 프로세스를 사용하여 작동 원리를 확인하십시오.