我正在爲我的遊戲設置一個屏幕管理器,它不能按我的需要工作。我開發了在全屏和在傳遞給該屏幕管理器的JFrame上進行窗口切換的方法,但它給了我不應該出現的錯誤。爲了獲得獨佔全屏,我想通過setUndecorated
刪除框架上的裝飾,這需要框架不可見。所以我在setUndecorated
之前申請setVisible(false)
,但它沒有效果。當打印輸出清楚地顯示框架不可見時,SetUndecorated仍然抱怨可見性。Java ScreenManager,setVisible不工作,bufferstrategy全屏丟失
編輯:在與下面的有用評論者討論時,我發現當切換到全屏時,我的bufferstrategys內容完全丟失,您如何避免這種情況?
Called from fullscreen before toggle, visible? false
Called from fullscreen after toogle, visible? false
Called from windowed before toggle, visible? true
Exception in thread "main" java.awt.IllegalComponentStateException:
The frame is displayable.
at java.awt.Frame.setUndecorated(Unknown Source)
at gfx.ScreenManager.setWindowed(ScreenManager.java:100)
at gfx.ScreenManager.main(ScreenManager.java:145)
Called from windowed after toggle before decorated, visible? false
我的屏幕管理器的當前迭代:
package gfx;
import java.awt.DisplayMode;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class ScreenManager {
private JFrame frame;
private GraphicsDevice gd;
private DisplayMode defaultMode;
private DisplayMode[] supportedModes;
// Use with frame from elsewhere
public ScreenManager(JFrame frame) {
this();
this.frame = frame;
}
// Used with a frame that is tied to instance
public ScreenManager() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
this.gd = ge.getDefaultScreenDevice();
this.defaultMode = new DisplayMode(800, 600, 16, 60);
this.setSupportedModes();
this.frame = new JFrame();
}
// Get the supported displayrates from current graphicsdevice
private void setSupportedModes() {
this.supportedModes = gd.getDisplayModes();
}
// Check if the supplied displaymode is supported by current device
public boolean isSupportedDisplayMode(DisplayMode odm) {
for (DisplayMode dm : this.supportedModes) {
if (dm.getHeight() == odm.getHeight()
&& dm.getWidth() == odm.getWidth()
&& dm.getBitDepth() == odm.getBitDepth()
|| odm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI
&& dm.getRefreshRate() == odm.getBitDepth()
|| odm.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN)
return true;
}
return false;
}
public void setFullScreen(DisplayMode displayMode) {
this.setFullScreen(displayMode, frame);
}
// Set fullscreen if supported displaymode, else default displaymode
public void setFullScreen(DisplayMode displayMode, JFrame frame) {
if (gd.isFullScreenSupported()) {
// Fullscreen on visible frame not allowed
System.out
.println("Called from fullscreen before toggle, visible? "
+ frame.isVisible());
frame.setVisible(false);
System.out.println("Called from fullscreen after toogle, visible? "
+ frame.isVisible());
// Remove decoration and unresiable
frame.setUndecorated(true);
frame.setResizable(false);
frame.setIgnoreRepaint(true);
// Set frame as fullscreenwindow
gd.setFullScreenWindow(frame);
// Set default if requested not supported or null
if (displayMode == null || !isSupportedDisplayMode(displayMode))
gd.setDisplayMode(defaultMode);
else
gd.setDisplayMode(displayMode);
// Create bufferstrategy
frame.createBufferStrategy(2);
}
}
// Make windowed
public void setWindowed() {
// Windowed from fullscreen if fullscreen, otherwise we are probably
// windowed already
if (gd.getFullScreenWindow() != null) {
System.out.println("Called from windowed before toggle, visible? "
+ frame.isVisible());
frame.setVisible(false);
System.out
.println("Called from windowed after toggle before decorated, visible? "
+ frame.isVisible());
frame.setUndecorated(false);
frame.setVisible(true);
frame.setIgnoreRepaint(false);
gd.setFullScreenWindow(null);
// gd.getFullScreenWindow().dispose(); < Clears frame, you lose all
// info, da fuck is the point of this except on gamexit from
// fullscreen?
}
}
// Get the drawing graphics of this ScreenManagers bufferstrategy
public Graphics2D getGraphics() {
Window frame = gd.getFullScreenWindow();
if (frame != null) {
BufferStrategy bufferStrategy = frame.getBufferStrategy();
return (Graphics2D) bufferStrategy.getDrawGraphics();
}
return null;
}
public void update() {
Window frame = gd.getFullScreenWindow();
if (frame != null) {
BufferStrategy bufferStrategy = frame.getBufferStrategy();
if (!bufferStrategy.contentsLost())
bufferStrategy.show();
}
Toolkit.getDefaultToolkit().sync();
}
// Display in readable format, eg [email protected]
public String displayModeToString(DisplayMode dm) {
return dm.getWidth() + "x" + dm.getHeight() + "x" + dm.getBitDepth()
+ "@" + dm.getRefreshRate();
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame();
frame.setSize(800, 600);
ScreenManager sm = new ScreenManager(frame);
sm.setFullScreen(new DisplayMode(1680, 1050, 32, 60));
Thread.sleep(3000);
sm.setWindowed();
}
有趣的方法setWindowed和setFullScreen。
編輯:下面的評論,這個新的主畫一個串上全屏緩衝,顯示它,那麼當現有全屏它完全消失了,這是不用設置,而不是擔心裝飾品。這很奇怪,考慮到我首先進入全屏,全屏方法創建了一個連接到JFrame的緩衝區,所以即使我離開全屏,JFrame現在也有一個緩衝區策略附加到它。所以buffercontent丟失的轉變之間的某種原因..
// Make windowed
public void setWindowed() {
// Windowed from fullscreen if fullscreen, otherwise we are probably
// windowed already
if (gd.getFullScreenWindow() != null) {
// gd.getFullScreenWindow().dispose();
gd.setFullScreenWindow(null);
// frame.setUndecorated(false);
frame.setVisible(true);
}
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame();
frame.setSize(800, 600);
ScreenManager sm = new ScreenManager(frame);
sm.setFullScreen(new DisplayMode(1680, 1050, 32, 60));
Graphics2D g2d = sm.getGraphics();
g2d.setColor(Color.red);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Font font = new Font("Serif", Font.PLAIN, 96);
g2d.setFont(font);
g2d.drawString("jade", 40, 120);
g2d.dispose();
sm.update();
Thread.sleep(3000);
sm.setWindowed();
}
[@see](http://stackoverflow.com/ a/15363570/714968) – mKorbel 2013-03-19 14:27:27
當退出全屏時完全清除緩衝區,在全屏過程中顯示的所有內容都將消失,該幀將僅爲空白。 – arynaq 2013-03-19 15:23:46
然後JFrame不能被顯示 – mKorbel 2013-03-19 15:28:24