2012-04-16 25 views
1

我打算製作遊戲,並希望窗口具有3種不同的模式:小型800 x 500窗口,最大化窗口和全屏窗口。我計劃使用主動渲染將圖形繪製到jframe中,並在layeredpane中將圖形繪製爲paintcomponents。我正在使用帶有2個緩衝區的bufferstrategy。爲了解決將已經可見的屏幕設置爲全屏的問題,每當窗口尺寸發生變化時(窗口本身不能調整大小,僅通過程序內的按鈕),會創建一個新的jframe,只要尺寸合適,並且包含paint的組件的jpanel被添加到frame。出於某種原因,每次我使用bufferstrategy的圖形繪製某些東西時,都會有一個偏移量(繪製0,0,0,3時會顯示出來,並且我不知道爲什麼。要麼只是與圖形繪製或致電與圖形油漆成分(當前Jframe的分層面板)。任何幫助您能給將不勝感激。enter code here使用主動渲染製作屏幕​​管理員類

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class ScreenManager { 

private GraphicsDevice device; 
private JFrame window; 
private int sizeState; 
private JPanel contentPane; 
private String title; 
private Rectangle maxBounds;  

public static final int SMALL_WINDOW = 1; 
public static final int MAXIMIZED_WINDOW = 2; 
public static final int FULLSCREEN_WINDOW = 3; 

private static final int SMALL_WIDTH = 800; 
private static final int SMALL_HEIGHT = 500; 

public ScreenManager(String s){  
    NullRepaintManager.install(); 
    title = s;  
    GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();   
    maxBounds = environment.getMaximumWindowBounds(); 
    device = environment.getDefaultScreenDevice(); 
    contentPane = new JPanel();    
    resetJFrame();  
    setSmallWindow();  
} 

public JPanel getPanel(){ 
    return contentPane; 
} 

public Graphics2D getGraphics(){ 
    while(true){ 
     if(window != null){  
    try{ 
    return (Graphics2D) window.getBufferStrategy().getDrawGraphics(); 
    }catch(Exception e){} 
    }  
} 
} 
public void update(){ 
    if(window != null && !window.getBufferStrategy().contentsLost()){ 
     window.getBufferStrategy().show(); 
    } 

    Toolkit.getDefaultToolkit().sync(); 
} 

public int getWidth(){ 
    if(window != null){ 
     return contentPane.getWidth(); 
    } 
    return 0; 
} 

public int getHeight(){ 
    if(window != null){ 
     return contentPane.getHeight(); 
    } 
    return 0; 
} 

public void paintComponents(Graphics2D g){  
     if(window != null){ 
      contentPane.paintComponents(g); 
       } 
     } 

public void closeWindow(){   
    System.exit(0); 
} 

public void setSmallWindow(){ 
    if(window != null && sizeState != ScreenManager.SMALL_WINDOW){ 
    resetJFrame();  
    window.setSize(ScreenManager.SMALL_WIDTH, ScreenManager.SMALL_HEIGHT);  
    contentPane.setSize(ScreenManager.SMALL_WIDTH, ScreenManager.SMALL_HEIGHT); 
    window.setLocationRelativeTo(null);   
    window.setVisible(true);   
    window.createBufferStrategy(2);   
    sizeState = ScreenManager.SMALL_WINDOW;  
} 
} 

public void setMaximizedWindow(){ 
    if(window != null && sizeState != ScreenManager.MAXIMIZED_WINDOW){ 
    resetJFrame(); 
    window.setSize((int) maxBounds.getWidth(), (int) maxBounds.getHeight());  
    contentPane.setSize(window.getWidth(), window.getHeight()); 
    window.setLocation(0,0); 
    window.setVisible(true);   
    window.createBufferStrategy(2);  
    sizeState = ScreenManager.MAXIMIZED_WINDOW;  
} 
} 

public void setFullScreenWindow(){ 
    if(window != null && sizeState != ScreenManager.FULLSCREEN_WINDOW){ 
     resetJFrame();  
     window.setUndecorated(true); 
     device.setFullScreenWindow(window); 
     contentPane.setSize(window.getWidth(), window.getHeight()); 
     window.createBufferStrategy(2); 
     sizeState = ScreenManager.FULLSCREEN_WINDOW;    
    } 
} 

private void resetJFrame(){ 
    if(sizeState == ScreenManager.FULLSCREEN_WINDOW){ 
     device.setFullScreenWindow(null); 
    } 

    if(window != null){ 
     window.dispose(); 
     window = null; 
    } 

    window = new JFrame(title);   
    window.setResizable(false);   
    window.setIgnoreRepaint(true); 
    window.addWindowListener(new WindowExitAdapter()); 
    window.add(contentPane);    
    contentPane.setOpaque(false);  
} 

private class WindowExitAdapter extends WindowAdapter{ 

    public void windowClosing(WindowEvent 
e){      
     closeWindow(); 
    }    
} 
} 

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class ScreenManagerTest implements ActionListener{ 

private ScreenManager sm; 
private JButton fullscreenButton; 
private JButton smallScreenButton; 
private JButton maxScreenButton; 
private JButton quitButton; 
private boolean isRunning = true; 

private int sizeState = 1; 


public static void main(String[] args) { 
    new ScreenManagerTest().go();  
} 

public void go(){ 
    sm = new ScreenManager("Nertz! Solitaire"); 
    sm.getPanel().setLayout(new BorderLayout()); 
    fullscreenButton = new JButton("Set Fullscreen");  
    sm.getPanel().add(fullscreenButton, BorderLayout.CENTER); 
    smallScreenButton = new JButton("Set Small Screen");   
    sm.getPanel().add(smallScreenButton, BorderLayout.WEST); 
    maxScreenButton = new JButton("Set Max Screen");   
    sm.getPanel().add(maxScreenButton, BorderLayout.EAST); 
    quitButton = new JButton("Exit Program");  
    sm.getPanel().add(quitButton, BorderLayout.SOUTH); 
    fullscreenButton.addActionListener(this); 
    smallScreenButton.addActionListener(this); 
    maxScreenButton.addActionListener(this); 
    quitButton.addActionListener(this); 

    while(isRunning == true){   
     switch(sizeState){ 

     case ScreenManager.FULLSCREEN_WINDOW: 
      sm.setFullScreenWindow(); 
      break; 
     case ScreenManager.MAXIMIZED_WINDOW: 
      sm.setMaximizedWindow(); 
      break; 
     case ScreenManager.SMALL_WINDOW: 
      sm.setSmallWindow(); 
      break; 
     } 
     draw(sm.getGraphics());   
     try{ 
      Thread.sleep(20); 
     }catch(Exception e){} 
    } 
    sm.closeWindow(); 
} 

public void draw(Graphics2D g){ 
    sm.paintComponents(g); 
    sm.update(); 

    g.dispose(); 
} 

public void actionPerformed(ActionEvent event){ 
    if(event.getSource() == fullscreenButton){ 
     sm.setFullScreenWindow(); 
     sizeState = ScreenManager.FULLSCREEN_WINDOW; 
    } 
    if(event.getSource() == smallScreenButton){ 
     sm.setSmallWindow(); 
     sizeState = ScreenManager.SMALL_WINDOW; 
    } 
    if(event.getSource() == maxScreenButton){ 
     sm.setMaximizedWindow();  
     sizeState = ScreenManager.MAXIMIZED_WINDOW; 
    } 
    if(event.getSource() == quitButton){ 
     isRunning = false; 
    } 
} 
} 
+1

'NullRepaintManager'? – trashgod 2012-04-16 06:13:30

回答

1

出於某種原因,每次我畫的東西時與 緩衝策略的圖形,有一個偏移量(繪畫0,0, 將顯示-3,20左右,我不知道爲什麼。)

只是一個瘋狂的猜測...也許你不是從(0,0)繪畫,而是通過框邊界爲零,因爲(-3,-20)點似乎是窗口零點座標(小邊框@左和〜20px窗口標題)?

如果你實際上是從(0,0)中繪製,但座標移動到(-3,-20)並且這實際上是一個窗口邊框 - 你可以在繪製方法開始時添加一個小補丁:

protected void paintComponent (Graphics g) 
{ 
    Point wl = SwingUtilities.getWindowAncestor (this).getLocationOnScreen(); 
    Point los = this.getLocationOnScreen(); 
    Point zero = new Point (los.x-wl.x, los.y-wl.y); 
    g.translate (zero.x, zero.y); 

    // ... 
} 

但我仍無法解釋爲什麼會發生這種情況。也許你在窗口模式和全屏模式之間切換時會保存零座標,導致這樣的問題...

+0

不,我不保存座標,我同意,我不知道爲什麼會發生這種情況,尤其是因爲我還沒有真正有過這種東西的經驗,但是我能夠用這個想法拼湊出一個解決方案你給我這麼感謝! – abalis3 2012-04-17 00:01:55