2017-10-06 57 views
0

使用JFrame的此測試代碼按預期工作(10秒後關閉)。使用Windows時的灰色屏幕,但JFrames很好

// **** Imports **** 
import java.awt.*; 
import javax.swing.JFrame; 




public class TestDisplay extends JFrame { 

// **** Constructor **** 

public static void main(String[] args) 
{ 
    DisplayMode dm = 
      new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN); 

    TestDisplay td = new TestDisplay(); 
    td.run(dm); 
} 

// **** Methods **** 

public void run(DisplayMode dm) 
{ 
    getContentPane().setBackground(Color.PINK); 
    setForeground(Color.WHITE); 
    setFont(new Font("Arial", Font.PLAIN, 24)); 

    Screen s = new Screen(); 
    try{ 
     s.setFullScreen(dm, this); 
     try{ 
      Thread.sleep(10000); // Delay before restoring screen (10 secs) 
     }catch(Exception ex){} 

    }finally{s.restoreScreen();} 

} 

public void paint(Graphics g) // JFrame calls paint method automatically 
{ 
    super.paint(g); 

    if(g instanceof Graphics2D) 
    { 
     System.out.println("It is Graphics2D"); 

     Graphics2D g2 = (Graphics2D)g; 
     g2.setRenderingHint // Turn on antialiasing for text 
    (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    } 

    g.drawString("This will be really cool", 200, 200); 
} 

} 

但是,當使用Windows時,我的灰屏問題仍然存在。 在TestDisplay> paint方法中,如果我刪除了「super.paint(g);」,我遇到了同樣的問題線。 這些是包含我的代碼,但不能正確呈現,但它正確運行的以下塊。 (按ESC鍵關閉窗口)

KeyTest類:

// **** Imports **** 
import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

public class KeyTest extends Core implements KeyListener{ 

// **** Variables **** 
private String mess = ""; 


// **** Constructor **** 
public static void main(String[] args) 
{ 
    new KeyTest().run(); 
} 

// **** Methods **** 

//init also call init from superclass 
public void init() 
{ 
    super.init(); 
    Window w = s.getFullScreenWindow(); 
    w.setFocusTraversalKeysEnabled(false); //make wierd buttons not wierd 
    w.addKeyListener(this); 
    mess = "Press escape to exit!"; 
} 

//key pressed 
public void keyPressed(KeyEvent e) 
{ 
    int keyCode = e.getKeyCode(); 
    if(keyCode == KeyEvent.VK_ESCAPE) 
    { 
     stop(); 
    } 
    else 
    { 
     mess = "Pressed : " + KeyEvent.getKeyText(keyCode); 
     e.consume(); //prevents button combinations (ex. alt + F = get file) 
    } 
} 

//key released 
public void keyReleased(KeyEvent e) 
{ 
    int keyCode = e.getKeyCode(); 
    mess = "Released : " + KeyEvent.getKeyText(keyCode); 
    e.consume(); //prevents button combinations (ex. alt + F = get file) 
} 

//last method from interface 
public void keyTyped(KeyEvent e) 
{ 
    e.consume(); 
} 

//draw 
public synchronized void draw(Graphics2D g) 
{ 
    Window w = s.getFullScreenWindow(); 

    g.setColor(w.getBackground()); 
    g.fillRect(0, 0, s.getWidth(), s.getHeight()); 
    g.drawString(mess, 30, 30); 

} 
} 

核心抽象類:

// **** Imports **** 
import java.awt.*; 
import javax.swing.*; 

public abstract class Core { 

// **** Variables **** 
private static final DisplayMode[] modes1 = 
{ 
    new DisplayMode(1920, 1080, 64, 0), 
    new DisplayMode(1920, 1080, 32, 0), 
    new DisplayMode(800, 600, 32, 0), 
    new DisplayMode(800, 600, 24, 0), 
    new DisplayMode(800, 600, 26, 0), 
    new DisplayMode(640, 480, 32, 0), 
    new DisplayMode(640, 480, 24, 0), 
    new DisplayMode(640, 480, 16, 0), 
}; 

private boolean running; 
protected ScreenManager s; 

// **** Constructor **** 

// **** Methods **** 

//Stop method 
public void stop() 
{ 
    running = false; 
} 

//call init and gameloop 
public void run() 
{ 
    try{ 
     init(); 
     gameLoop(); 
    }finally{s.restoreScreen();} 

} 

//set to full screen 
public void init(){ 
    s = new ScreenManager(); 
    DisplayMode dm = s.findFirstCompatibleMode(modes1); 
    s.setFullScreen(dm); 
    Window w = s.getFullScreenWindow(); 
    w.setFont(new Font("Arial", Font.PLAIN, 20)); 
    w.setForeground(Color.RED); 
    w.setForeground(Color.WHITE); 
    running = true; 
} 

//main gameloop 
public void gameLoop() 
{ 
    long startTime = System.currentTimeMillis(); 
    long cTime = startTime; 

    while(running) 
    { 
     long timePassed = System.currentTimeMillis(); 
     cTime = cTime + timePassed; 

     update(timePassed); 

     Graphics2D g = s.getGraphics(); 
     draw(g); 
     g.dispose(); 
     s.update(); 

     try{ 
      Thread.sleep(20); 
     }catch(Exception ex){} 
    } 
} 

//update animation 
public void update(long timePassed){} 

//draws to the screen 
public abstract void draw(Graphics2D g); 
} 

的ScreenManager類:

// **** Imports **** 
import java.awt.*; 
import java.awt.image.BufferStrategy; 
import java.awt.image.BufferedImage; 
import java.lang.reflect.InvocationTargetException; 
import javax.swing.JFrame; 


public class ScreenManager { 

// **** Variables **** 

private GraphicsDevice vc; 

// **** Constructor **** 

public ScreenManager() 
{ 
    //give vc access to monitor screen 
    GraphicsEnvironment e = 
      GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    vc = e.getDefaultScreenDevice(); 
} 

// **** Methods **** 

// ____ Handle Display Modes ____ 

//get all compatible display modes 
public DisplayMode[] getCompatibleDiplayModes(){ 
    return vc.getDisplayModes(); 
} 

//compares display modes passed into vc and checks for a match 
public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) 
{ 
    DisplayMode goodModes[] = vc.getDisplayModes(); 
    for(int x=0; x<modes.length;x++) 
    { 
     for(int y=0;y<goodModes.length;y++) 
     { 
      if(displayModesMatch(modes[x], goodModes[y])) 
      { 
       return modes[x]; 
      } 
     } 
    } 
    return null; 
} 

//get current display mode 
public DisplayMode getCurrentDisplayMode() 
{ 
    return vc.getDisplayMode(); 
} 

//check if two modes match 
public boolean displayModesMatch(DisplayMode m1, DisplayMode m2) 
{ 
    //test if resolution match (if not match, false) 
    if(m1.getWidth() != m2.getWidth() || m1.getHeight() != m2.getHeight()) 
    { 
     return false; 
    } 
    //test if bit depth match ((if not match, false) 
    if(m1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI 
      && m2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI 
      && m1.getBitDepth() != m2.getBitDepth()) 
    { 
     return false; 
    } 
    //test if refresh rate match (if not match, false) 
    if(m1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN 
      && m2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN 
      && m1.getRefreshRate() != m2.getRefreshRate()) 
    { 
     return false; 
    } 

    return true; 
} 

// ____ Handle Graphics ____ 

//make jframe full screen 
public void setFullScreen(DisplayMode dm) 
{ 
    //Frame f = new Frame(); 
    JFrame f = new JFrame(); 

    f.setUndecorated(true); 
    f.setIgnoreRepaint(true); 
    f.setResizable(false); 
    vc.setFullScreenWindow(f); 

    if(dm != null && vc.isDisplayChangeSupported()) 
    { 
     try{ 
      vc.setDisplayMode(dm); 
     }catch(Exception ex){} 
    } 
    f.createBufferStrategy(2); 
} 

// ??? important magic ??? 
public Graphics2D getGraphics(){ 
    Window w = vc.getFullScreenWindow(); 
    if (w != null) 
    { 
     BufferStrategy s = w.getBufferStrategy(); 
     return (Graphics2D)s.getDrawGraphics(); 
    } 
    else 
    { 
     return null; 
    } 
} 

//updates display 
public void update() 
{ 
    Window w = vc.getFullScreenWindow(); 
    if(w != null) 
    { 
     BufferStrategy s = w.getBufferStrategy(); 

     //only display new frame when it is ready 
     if(!s.contentsLost()) 
     { 
      s.show(); 
     } 
    } 
} 

//returns full screen window 
public Window getFullScreenWindow() 
{ 
    return vc.getFullScreenWindow(); 
} 

//get Width of window 
public int getWidth() 
{ 
    Window w = vc.getFullScreenWindow(); 
    if(w != null) 
    { 
     return w.getWidth(); 
    } 
    else 
    { 
     return 0; 
    } 
} 

//get Height of window 
public int getHeight() 
{ 
    Window w = vc.getFullScreenWindow(); 
    if(w != null) 
    { 
     return w.getHeight(); 
    } 
    else 
    { 
     return 0; 
    } 
} 

//get out of fullscreen 
public void restoreScreen() 
{ 
    Window w = vc.getFullScreenWindow(); 
    if (w != null) 
    { 
     w.dispose(); 
    } 
    vc.setFullScreenWindow(null); 
} 

//create image compatible with monitor (width, height, transparency) 
public BufferedImage createCompatibleImage(int w, int h, int t) 
{ 
    Window win = vc.getFullScreenWindow(); 
    if(win != null) 
    { 
     GraphicsConfiguration gc = win.getGraphicsConfiguration(); 
     return gc.createCompatibleImage(w, h, t); 
    } 
    return null; 
} 


} 

我將不勝感激的任何想法,你傢伙可能會解決這個問題。

+0

你可以減少代碼的重要部分?但總的來說,將SWING與AWT合併不是一個好主意,因爲它可能會導致許多不同的問題。 –

+0

因此,有很多東西會讓人浮想聯翩 - 不建議通常重寫'JFrame'等頂級容器的'paint',但它可能會使全屏獨佔模式變得更糟。雖然我不是100%肯定的,但是從我所做的有限的滅絕中,在FSEM中使用的窗口並不是您開始使用的窗口。你的代碼也沒有正確使用'BufferStrategy' - 你應該閱讀關於這個主題的JavaDocs和教程,它突出了一個常見的使用模式 – MadProgrammer

+0

我的第一個建議是讓BufferStrategy工作 - 我建議你開始通過創建一個基於'java.awt.Canvas'的類而不是依賴'Window'。一旦你可以開始工作,開始考慮讓FSEM工作 – MadProgrammer

回答

1

我的第一個建議是讓每個部分單獨工作,然後嘗試將它們綁定在一起。儘管解耦代碼是一個好主意,但最好先了解它是如何首先一起工作的;)

因此,以下內容基於來自JavaDocs for BufferStrategyBufferStrategy and BufferCapabilities的信息。這是很基本的,它的目的是一旦你的工作與使用BufferStrategy

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.DisplayMode; 
import java.awt.EventQueue; 
import java.awt.Graphics2D; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.Rectangle; 
import java.awt.image.BufferStrategy; 
import java.util.concurrent.atomic.AtomicBoolean; 
import javax.swing.JFrame; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

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

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       TestPane tp = new TestPane(); 
       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(tp); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       new Thread(tp).start(); 
      } 
     }); 
    } 

    public class TestPane extends Canvas implements Runnable { 

     private AtomicBoolean allIsAwesome = new AtomicBoolean(true); 

     public TestPane() { 
     } 

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

     public void stop() { 
      allIsAwesome.set(false); 
     } 

     private Rectangle box = new Rectangle(0, 50, 100, 100); 
     private int delta = 2; 

     public void run() { 
      createBufferStrategy(2); 
      while (allIsAwesome.get()) { 
       // Catch the time we started... 
       update(); 
       render(); 
       // Calculate the time it took 
       // Subtract that from the time we would like to "wait" 
       // Thus creating a "stable" FPS 
       try { 
        Thread.sleep(10); 
       } catch (InterruptedException ex) { 
       } 
      } 
     } 

     protected void update() { 
      box.x += delta; 
      if (box.x + box.width > getWidth()) { 
       box.x = getWidth() - box.width; 
       delta *= -1; 
      } else if (box.x < 0) { 
       box.x = 0; 
       delta *= -1; 
      } 
     } 

     protected void render() { 
      BufferStrategy strategy = getBufferStrategy(); 
      do { 
       do { 
        Graphics2D g2d = (Graphics2D) strategy.getDrawGraphics(); 
        g2d.setColor(Color.LIGHT_GRAY); 
        g2d.fillRect(0, 0, getWidth(), getHeight()); 
        g2d.setColor(Color.RED); 
        g2d.fill(box); 
        g2d.dispose(); 
       } while (strategy.contentsLost()); 
       strategy.show(); 
      } while (strategy.contentsLost()); 
     } 

    } 

} 

試驗(並有合理的理解它是如何工作的),那麼我建議在基本FSEM測試

我以前GraphicsDevice#getDisplayModes列出了我的默認GraphicsDevice兼容的顯示模式,所以你需要配置你自己

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.DisplayMode; 
import java.awt.EventQueue; 
import java.awt.Graphics2D; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.Rectangle; 
import java.awt.image.BufferStrategy; 
import java.util.concurrent.atomic.AtomicBoolean; 
import javax.swing.JFrame; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

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

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       DisplayMode mode = new DisplayMode(2560, 1600, 32, 30); 

       TestPane tp = new TestPane(); 
       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(tp); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
//    frame.setVisible(true); 

       GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
       GraphicsDevice device = env.getDefaultScreenDevice(); 
       device.setFullScreenWindow(frame); 

       new Thread(tp).start(); 
      } 
     }); 
    } 

    public class TestPane extends Canvas implements Runnable { 

     private AtomicBoolean allIsAwesome = new AtomicBoolean(true); 

     public TestPane() { 
     } 

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

     public void stop() { 
      allIsAwesome.set(false); 
     } 

     private Rectangle box = new Rectangle(0, 50, 100, 100); 
     private int delta = 2; 

     public void run() { 
      createBufferStrategy(2); 
      while (allIsAwesome.get()) { 
       // Catch the time we started... 
       update(); 
       render(); 
       // Calculate the time it took 
       // Subtract that from the time we would like to "wait" 
       // Thus creating a "stable" FPS 
       try { 
        Thread.sleep(10); 
       } catch (InterruptedException ex) { 
       } 
      } 
     } 

     protected void update() { 
      box.x += delta; 
      if (box.x + box.width > getWidth()) { 
       box.x = getWidth() - box.width; 
       delta *= -1; 
      } else if (box.x < 0) { 
       box.x = 0; 
       delta *= -1; 
      } 
     } 

     protected void render() { 
      BufferStrategy strategy = getBufferStrategy(); 
      do { 
       do { 
        Graphics2D g2d = (Graphics2D) strategy.getDrawGraphics(); 
        g2d.setColor(Color.LIGHT_GRAY); 
        g2d.fillRect(0, 0, getWidth(), getHeight()); 
        g2d.setColor(Color.RED); 
        g2d.fill(box); 
        g2d.dispose(); 
       } while (strategy.contentsLost()); 
       strategy.show(); 
      } while (strategy.contentsLost()); 
     } 

    } 

} 

我跑這使用Java 8在MacOS塞拉利昂10.12.6,並能夠得到它渲染。