我打算制作游戏并希望窗口有3种不同的模式:800 x 500的小窗口,最大化的窗口和全屏窗口。我计划使用有效渲染将图形绘制到jframe
中的paint
和components
中的layeredpane
。我正在使用带有2个缓冲区的bufferstrategy
。为了解决将已经可见的屏幕设置为全屏的问题,每当窗口的尺寸发生变化时(窗口本身不能通过程序中的按钮调整尺寸),就会创建一个新的jframe
,给定适当的大小,并将jpanel
包含paint
的组件添加到frame
。出于某种原因,每当我用bufferstrategy
的图形绘制一些东西时,都会有一个偏移(在0,0处绘制一些东西,会出现在-3,-20左右,我不知道为什么。当我使用图形绘制或使用图形调用绘图组件(在当前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;
}
}
}
答案 0 :(得分:1)
出于某种原因,每次我用图形绘制一些东西 bufferstrategy,有一个偏移(在0,0画一些东西, 会出现在-3,-20左右,我不知道为什么。
只是一个狂野的猜测...也许你不是从(0,0)绘画而是通过帧边界为零,因为(-3,-20)点似乎是窗口零坐标(小边界@左和~20px窗口标题)?
如果您实际上是从(0,0)绘制但坐标移动到(-3,-20)并且这实际上是一个窗口边框 - 您可以在paint方法的开头添加一个小补丁:
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 );
// ...
}
但我仍无法解释为何会发生这种情况。也许你在窗口和全屏模式之间切换时保存零坐标,这会导致这样的问题......