Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8中的Window.setFullScreenWindow导致应用程序挂起在alt选项卡上_Java_Jframe_Graphics2d_Java Threads - Fatal编程技术网

Java 8中的Window.setFullScreenWindow导致应用程序挂起在alt选项卡上

Java 8中的Window.setFullScreenWindow导致应用程序挂起在alt选项卡上,java,jframe,graphics2d,java-threads,Java,Jframe,Graphics2d,Java Threads,这是我在今天早些时候做的实验——模式本身很好,我的渲染循环很好(现在,直到我改进它),等等 当没有设置为全屏参考时,应用程序在我的计算机上移动时绝对没有问题。动画每秒钟都在滴答作响,没有出错 只有当我打电话时: device.setFullScreenWindow((Window) frame); 任何窗口焦点的丢失都会导致应用程序将自身最小化,然后在我返回时挂起。下面详细介绍了整个代码库(这是一个非常简单的项目)。CPU使用率从少量%(i5-3570K上约2%的使用率)上升到0% Loade

这是我在今天早些时候做的实验——模式本身很好,我的渲染循环很好(现在,直到我改进它),等等

当没有设置为全屏参考时,应用程序在我的计算机上移动时绝对没有问题。动画每秒钟都在滴答作响,没有出错

只有当我打电话时:

device.setFullScreenWindow((Window) frame);
任何窗口焦点的丢失都会导致应用程序将自身最小化,然后在我返回时挂起。下面详细介绍了整个代码库(这是一个非常简单的项目)。CPU使用率从少量%(i5-3570K上约2%的使用率)上升到0%

Loader.java

package loader;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.SplashScreen;

import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import gui.MainFrame;
import misc.Device;
import utils.VideoUtils;

public class Loader {

    private static final int SCREEN_CHOICE = 1;

    public static void main(String[] args) {
        System.setProperty("awt.useSystemAAFontSettings","on"); 
        System.setProperty("swing.aatext", "true");

        int PASSED_SCREEN_CHOICE = -1;
        if(args.length > 0) {
            PASSED_SCREEN_CHOICE = Integer.parseInt(args[0]);
        } else {
            PASSED_SCREEN_CHOICE = SCREEN_CHOICE;
        }

        SplashScreen splash = SplashScreen.getSplashScreen();
        Graphics2D g = null;
        if(null != splash) {
            g = splash.createGraphics();
            renderSplashFrame(g, 0);
            splash.update();
        }

        displayUI(g, splash, PASSED_SCREEN_CHOICE);
    }

    // TODO :: rework rendering to leverage SwingWorker and a target FPS
    private static void displayUI(final Graphics2D g, final SplashScreen splash, int SCREEN_CHOICE) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                setLookAndFeel();
                Device[] devices = null;
                if(null != g && null != splash) {
                    for(int i = 0; i < 265; i++) {
                        renderSplashFrame(g, i);
                        splash.update();
                        try {
                            Thread.sleep(7);
                        } catch(InterruptedException e) {
                            System.out.println("Thread sleep exception, on inner splashscreen timer!");
                        }
                    }

                    devices = VideoUtils.getMonitorDetails();
                    splash.close();
                } else {
                    // set up display devices anyhow
                    devices = VideoUtils.getMonitorDetails();
                }

                MainFrame.displayAndShowGUI(devices, SCREEN_CHOICE);
            }
        });
    }

    private static void renderSplashFrame(Graphics2D g, int frame) {
        final String[] comps = {
                "Initialising", 
                "Preparing UI", 
        "Finalising"};
        g.setComposite(AlphaComposite.Clear);
        g.fillRect(25, 190, 290, 45);
        g.setPaintMode();
        g.setColor(new Color(255, 255, 150, 190));
        g.drawString(comps[(frame / 90) % 3] + " . . ", 30, 230);
        g.drawLine(25, 195, 290, 195);      //  -------
        g.drawLine(25, 195, 25, 215);       // |
        g.drawLine(25, 215, 290, 215);      //  -------
        g.drawLine(290, 195, 290, 215);     //         |
        g.fillRect(25, 195, frame, 20);
    }

    private static void setLookAndFeel() {
        // sets the look and feel to be that of the operating system's
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | 
                InstantiationException | 
                IllegalAccessException | 
                UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
    }

}
package gui;

import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import misc.Device;
import utils.VideoUtils;

public class MainFrame {

    private static JFrame mainframe;
    private static JFrame debugframe;
    private static MainView mainview;

    private static Thread runner;

    public static void displayAndShowGUI(Device[] devices, int choice) {
        mainframe = new JFrame("Item-Driven Development");
        mainframe.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));

        Device chosenDevice;
        for(Device d : devices) {
            System.out.println(d.toString());
        }

        if(choice < devices.length) {
            chosenDevice = devices[choice];
        } else {
            // default to the only one you have
            chosenDevice = devices[0];
        }

        System.out.println("We have chosen device: " + chosenDevice.getDevice().getIDstring());

        mainview = new MainView(chosenDevice);
        mainframe.add(mainview);

        mainframe.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                exitApplication((JFrame) e.getSource());
            }
        });

        // let's centre this sucker
//      mainframe.setLocation(chosenDevice.getCentreX() - mainview.getSimDimension().width / 2, 
//              chosenDevice.getCentreY() - mainview.getSimDimension().height / 2);

        VideoUtils.setFullscreenResolution(mainframe, chosenDevice.getDevice(), chosenDevice.getDisplayMode());

        mainframe.pack();
        mainframe.setVisible(true);

        runner = new Thread(mainview);
        runner.start();
        mainview.requestFocusInWindow();
    }

    public static void exitApplication(JFrame mainframe) {
        int response = JOptionPane.showConfirmDialog(mainframe, 
                "Are you sure you want to exit?",
                "Exit application?",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE);
        if(response == JOptionPane.YES_OPTION) {
            mainframe.setVisible(false);
            mainframe.dispose();
            System.exit(0);
        }
    }

    public JFrame getMainframe() {
        return mainframe;
    }

    public JFrame getDebugframe() {
        return debugframe;
    }

    public Thread getRunner() {
        return runner;
    }
}
package gui;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Toolkit;

import javax.swing.JPanel;

import misc.Device;
import utils.ShaderUtils;

public class MainView extends JPanel implements Runnable {

    private static final long serialVersionUID = 1L;

    private Dimension simDimension;
    private final long TARGET_FRAMESPERSECOND;
    private long sleepInMillis;

    private long startInNanos = System.nanoTime();
    private long currentCycleInNanos = System.nanoTime() - startInNanos;
    private long lastCycleInNanos = 0;
    private long currentInSeconds = 0;
    private long currentFrame = 0;  

    private boolean gameRunning = true;
    private boolean gamePaused = false;

    public MainView(Device display) {
        simDimension = new Dimension(display.getDisplayMode().getWidth(), display.getDisplayMode().getHeight());
        setPreferredSize(simDimension);
        setBackground(Color.BLACK);

        if(!display.isRefreshUnknown()) {
            TARGET_FRAMESPERSECOND = display.getRefreshRate();
        } else {
            // default to 60
            TARGET_FRAMESPERSECOND = 60;
        }

        sleepInMillis = 1000 / TARGET_FRAMESPERSECOND;      
    }

    @Override
    public void run() {
        while(gameRunning) {            
            try {               
                long temp = currentCycleInNanos;
                currentCycleInNanos = System.nanoTime() - startInNanos;
                lastCycleInNanos = currentCycleInNanos - temp;
                if((currentCycleInNanos / 1000 / 1000 / 1000) > currentInSeconds) {
                    currentInSeconds = currentInSeconds + 1;
                    System.out.println(sleepInMillis + "ms sleep per frame (" + (sleepInMillis * TARGET_FRAMESPERSECOND) + "ms sleep in total per second)");
                    System.out.println("max frames per second at: " + currentInSeconds + " seconds: " + currentFrame + "FPS (" + currentCycleInNanos + " nanos)");
                    currentFrame = 0;
                }


                repaint();
                currentFrame = currentFrame + 1;
                long timeout = sleepInMillis; // - (lastCycleInNanos / 1000 / 1000)
                if(timeout < 0) timeout = 0;
                Thread.sleep(timeout);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        Toolkit.getDefaultToolkit().sync();
        super.paintComponent(g);
        doDrawing(g);
    }

    private void doDrawing(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        ShaderUtils.applyQualityRenderingHints(g2d);
        if(currentInSeconds % 2 == 0) {
            g2d.setColor(Color.RED);
        } else {
             g2d.setColor(Color.GREEN);
        }

        Composite original = g2d.getComposite();
        Composite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.35f);
        g2d.draw(new Rectangle(simDimension.width / 2 - (300 / 2), simDimension.height / 2 - (150 / 2), 300, 150));
    }

    public Dimension getSimDimension() {
        return simDimension;
    }

    public boolean isGameRunning() {
        return gameRunning;
    }

    public void setGameRunning(boolean gameRunning) {
        this.gameRunning = gameRunning;
    }

    public boolean isGamePaused() {
        return gamePaused;
    }

    public void setGamePaused(boolean gamePaused) {
        this.gamePaused = gamePaused;
    }

}
package misc;

import java.awt.DisplayMode;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Rectangle;
import java.awt.Window;

import utils.VideoUtils;

public class Device {

    private GraphicsDevice device;
    private DisplayMode displayMode;
    private DisplayMode[] availableModes;
    private GraphicsConfiguration graphicsConfig;

    private int bitDepth;
    private int supportedColours;
    private int refreshRate;
    private boolean refreshUnknown;
    private int acceleratedMemory;

    private boolean fullscreenSupport;

    private Rectangle bounds;

    private int centreX;
    private int centreY;

    public Device(GraphicsDevice device) {      
        displayMode = device.getDisplayMode();
        availableModes = device.getDisplayModes();
        graphicsConfig = device.getDefaultConfiguration();

        bitDepth = displayMode.getBitDepth();
        supportedColours = (int) Math.pow(2, bitDepth);
        refreshRate = displayMode.getRefreshRate();
        if(refreshRate == DisplayMode.REFRESH_RATE_UNKNOWN) {
            refreshUnknown = true;
        } else {
            refreshUnknown = false;
        }

        acceleratedMemory = device.getAvailableAcceleratedMemory();
        fullscreenSupport = device.isFullScreenSupported();

        bounds = device.getDefaultConfiguration().getBounds();
        centreX = bounds.x + ((int) bounds.getWidth() / 2);
        centreY = bounds.y + ((int) bounds.getHeight() / 2);

        this.device = device;
    }


    public GraphicsDevice getDevice() {
        return device;
    }

    public void setDevice(GraphicsDevice device) {
        this.device = device;
    }

    public DisplayMode getDisplayMode() {
        return displayMode;
    }

    public void setDisplayMode(DisplayMode displayMode) {
        this.displayMode = displayMode;
    }

    public DisplayMode[] getAvailableModes() {
        return availableModes;
    }

    public void setAvailableModes(DisplayMode[] availableModes) {
        this.availableModes = availableModes;
    }   

    public GraphicsConfiguration getGraphicsConfig() {
        return graphicsConfig;
    }

    public void setGraphicsConfig(GraphicsConfiguration graphicsConfig) {
        this.graphicsConfig = graphicsConfig;
    }

    public int getBitDepth() {
        return bitDepth;
    }

    public void setBitDepth(int bitDepth) {
        this.bitDepth = bitDepth;
    }

    public int getSupportedColours() {
        return supportedColours;
    }

    public void setSupportedColours(int supportedColours) {
        this.supportedColours = supportedColours;
    }

    public int getRefreshRate() {
        return refreshRate;
    }

    public void setRefreshRate(int refreshRate) {
        this.refreshRate = refreshRate;
    }

    public boolean isRefreshUnknown() {
        return refreshUnknown;
    }

    public void setRefreshUnknown(boolean refreshUnknown) {
        this.refreshUnknown = refreshUnknown;
    }

    public int getAcceleratedMemory() {
        return acceleratedMemory;
    }

    public void setAcceleratedMemory(int acceleratedMemory) {
        this.acceleratedMemory = acceleratedMemory;
    }

    public boolean isFullscreenSupport() {
        return fullscreenSupport;
    }

    public void setFullscreenSupport(boolean fullscreenSupport) {
        this.fullscreenSupport = fullscreenSupport;
    }

    public Rectangle getBounds() {
        return bounds;
    }

    public void setBounds(Rectangle bounds) {
        this.bounds = bounds;
    }

    public int getCentreX() {
        return centreX;
    }

    public void setCentreX(int centreX) {
        this.centreX = centreX;
    }

    public int getCentreY() {
        return centreY;
    }

    public void setCentreY(int centreY) {
        this.centreY = centreY;
    }

    @Override
    public String toString() {
        String result = "Device: ";
        result = result + device.getIDstring() + "\n\n";
        result = result + "\tDisplay Mode: " + VideoUtils.printDisplayModeDetails(displayMode) + "\n";
        result = result + "\t" + availableModes.length + " available display modes to choose from\n";
        result = result + "\tRefresh Rate: ";
        if(refreshUnknown) {
            result = result + "UNKNOWN\n";
        } else {
            result = result + refreshRate + "Hz\n";
        }

        double xBounds = (bounds.getX() + bounds.getMaxX());
        if(xBounds < 0) xBounds = 0 - xBounds;
        double yBounds = (bounds.getY() - bounds.getMaxY());
        if(yBounds < 0) yBounds = 0 - yBounds;
        result = result + "\tDefined Bounds: " + xBounds + " / " + yBounds + "\n\n";

        String fullscreenBool = fullscreenSupport ? "Yes" : "No";

        if(acceleratedMemory < 0) {
            result = result + "\tAvailable Accelerated Memory: n/a\n";
        } else {
            result = result + "\tAvailable Accelerated Memory: " + acceleratedMemory + "\n";
        }

        result = result + "\tSupports Fullscreen? " + fullscreenBool + "\n";
        result = result + "\tImage Capabilities (Accelerated): " + (graphicsConfig.getImageCapabilities().isAccelerated() ? "Yes" : "No") + "\n";
        result = result + "\tImage Capabilities (True Volatile): " + (graphicsConfig.getImageCapabilities().isTrueVolatile() ? "Yes" : "No") + "\n\n";
        result = result + "\tSupported Colours: " + supportedColours + "\n";
        result = result + "\tGraphics Configuration: " + graphicsConfig + "\n\n";
        result = result + "------------------------------------------------\n";
        return result;
    }

}
package utils;

import java.awt.DisplayMode;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Window;

import javax.swing.JFrame;

import misc.Device;

public class VideoUtils {

    public static Device[] getMonitorDetails() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
        Device[] result = new Device[ge.getScreenDevices().length];
        GraphicsDevice[] gds = ge.getScreenDevices();
        for(int n = 0; n < gds.length; n++) {
            result[n] = new Device(gds[n]);
        }

        return result;
    }

    public static void setFullscreenResolution(JFrame frame, GraphicsDevice device, DisplayMode displayMode) {
        frame.setUndecorated(true);
        frame.setResizable(false);
        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        if(device.isFullScreenSupported()) {
            device.setFullScreenWindow((Window) frame);
            if(device.isDisplayChangeSupported()) {
                try {
                    // bit redundant on first run, removed for now
                    // device.setDisplayMode(displayMode);
                } catch (IllegalArgumentException | UnsupportedOperationException e) {
                    if(e instanceof IllegalArgumentException) {
                        System.err.println("Illegal argument provided: " + printDisplayModeDetails(displayMode));
                    } else {
                        System.err.println("Unsupported Operation attempted!");
                    }

                    e.printStackTrace();
                }
            } else {
                System.err.println("Operation to set DisplayMode not supported by this device.");
            }
        } else {
            System.err.println("Fullscreen Window mode not supported by this device.");
        }
    }

    public static String printDisplayModeDetails(DisplayMode dm) {
        return dm.getWidth() + " * " + dm.getHeight() + " @ " + dm.getRefreshRate() + "Hz (" + dm.getBitDepth() + "-bit)";
    }

}
package utils;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

public class ShaderUtils {

    public static void applyQualityRenderingHints(Graphics2D g2d) {
        g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
    }

    // with thanks to http://stackoverflow.com/questions/21382966/colorize-a-picture-in-java/21385150#21385150
    public static BufferedImage applyShader(BufferedImage input, Color shader) {
        BufferedImage output = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = output.createGraphics();
        g.drawImage(input, 0, 0, null);
        g.setComposite(AlphaComposite.SrcAtop);
        g.setColor(shader);
        g.fillRect(0, 0, input.getWidth(), input.getHeight());
        g.dispose();

        return output;
    }

}