Java 使用活动呈现创建screenmanager类

Java 使用活动呈现创建screenmanager类,java,swing,Java,Swing,我正在计划制作一个游戏,希望窗口有3种不同的模式:一个800 x 500的小窗口、一个最大化窗口和一个全屏窗口。我计划使用活动渲染将图形绘制到jframe中,并在分层窗格中绘制组件。我使用的是一种带有两个缓冲区的缓冲策略。为了解决将已经可见的屏幕设置为全屏的问题,每次窗口的尺寸发生变化时(窗口本身无法调整大小,只能通过程序中的按钮调整大小),都会创建一个新的jframe,给定适当的大小,将包含要绘制的组件的jpanel添加到框架中。出于某种原因,每次我使用缓冲策略中的图形绘制某个对象时,都会有一

我正在计划制作一个游戏,希望窗口有3种不同的模式:一个800 x 500的小窗口、一个最大化窗口和一个全屏窗口。我计划使用活动渲染将图形绘制到
jframe
中,并在
分层窗格中
绘制
组件。我使用的是一种带有两个缓冲区的
缓冲策略
。为了解决将已经可见的屏幕设置为全屏的问题,每次窗口的尺寸发生变化时(窗口本身无法调整大小,只能通过程序中的按钮调整大小),都会创建一个新的
jframe
,给定适当的大小,将包含要绘制的组件的
jpanel
添加到
框架中。出于某种原因,每次我使用
缓冲策略
中的图形绘制某个对象时,都会有一个偏移量(在0,0处绘制某个对象时,会显示在-3,-20左右,我不知道为什么。当我仅使用图形绘制或使用图形调用绘制组件(在当前jframe的分层面板上)时会发生这种情况。如果您能提供任何帮助,我们将不胜感激。
在此处输入代码

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;  
    }
}
}
出于某种原因,每次我用来自 在缓冲策略中,有一个偏移量(在0,0处绘制某物, 会在-3,-20左右出现,我不知道为什么

这只是一个粗略的猜测……也许您不是从(0,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,0处绘制某物, 会在-3,-20左右出现,我不知道为什么

这只是一个粗略的猜测……也许您不是从(0,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 );

    // ...
}

但我仍然无法解释为什么会发生这种情况。也许在窗口和全屏模式之间切换时,您正在保存零坐标,这会导致这样的问题…

不,我没有保存坐标,我同意,我不确定为什么会发生这种情况,特别是因为我对这种东西还没有真正的经验,但我能够做到这一点她用你给我的观点给出了一个解决方案,非常感谢!不,我没有保存坐标,我同意,我不知道为什么会发生这种情况,特别是因为我对这些东西还没有真正的经验,但我能够用你给我的观点拼凑出一个解决方案,非常感谢!