AWT Full-Screen Exclusive Mode

  • Themenstarter Themenstarter Guest2
  • Beginndatum Beginndatum
G

Guest2

Gast
Moin,

ich habe einen Anwendungsfall, bei dem ich im laufenden Betrieb nahtlos zwischen Fenster- und FSEM umschalten möchte. Mit reinem Swing stellt das auch kein Problem dar. Allerdings verwendet diese Anwendung eine AWT heavy weight Komponente. Sobald diese eingebunden ist, beleibt die gesamte Anwendung im FSEM schwarz.

Alternativ kann ich den gesamten Anwendungsfall aber auch mit reinem AWT abdecken, allerdings beleibt das Problem dabei bestehen. Ein schnell zusammengeschriebenes KSKB:

Java:
package fsem;

import java.awt.Choice;

public class FSEM {

    private final GraphicsDevice           device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    private final Map<String, DisplayMode> modes  = displayModesToHashMap(device.getDisplayModes(), device.getDisplayMode());
    private final DisplayMode              mode   = device.getDisplayMode();

    private Frame                          frame;
    private Choice                         choice;


    public FSEM() {

        initialize();

    }


    private void initialize() {

        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setLocationRelativeTo(null);

        choice = new Choice();

        for (final String key : modes.keySet())
            choice.add(key);

        choice.select("Window");

        choice.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(final ItemEvent e) {

                if (e.getStateChange() == ItemEvent.SELECTED)
                    setDisplayMode((String) e.getItemSelectable().getSelectedObjects()[0]);

            }
        });

        frame.add(choice);

    }


    private void setDisplayMode(final String key) {

        final DisplayMode dm = modes.get(key);

        if (dm != null)
            setFullScreenMode(dm);

        else
            setWindowMode();

    }


    private void setFullScreenMode(final DisplayMode dm) {

        try {

            frame.setVisible(false);
            frame.dispose();
            frame.setUndecorated(true);
            frame.setResizable(false);
            frame.setSize(dm.getWidth(), dm.getHeight());
            frame.pack();
            frame.setVisible(true);

            device.setFullScreenWindow(frame);
            device.setDisplayMode(dm);

        } catch (final Exception e) {

            e.printStackTrace();

            setWindowMode();

        }

    }


    private void setWindowMode() {

        device.setDisplayMode(mode);
        device.setFullScreenWindow(null);

        frame.setVisible(false);
        frame.dispose();
        frame.setUndecorated(false);
        frame.setResizable(true);
        frame.setSize(mode.getWidth() / 2, mode.getHeight() / 2);
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);

    }


    private Map<String, DisplayMode> displayModesToHashMap(final DisplayMode[] modes, final DisplayMode current) {

        final Map<String, DisplayMode> result = new TreeMap<String, DisplayMode>();

        result.put("Window", null);

        for (final DisplayMode mode : modes)
            if (mode.getRefreshRate() == current.getRefreshRate() && mode.getBitDepth() == current.getBitDepth()) {

                final String key = mode.getWidth() + "x" + mode.getHeight();
                final DisplayMode value = mode;

                result.put(key, value);

            }

        return result;

    }


    public static void main(final String[] args) {

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {

                try {

                    final FSEM window = new FSEM();
                    window.frame.setVisible(true);

                } catch (final Exception e) {

                    e.printStackTrace();

                }

            }

        });

    }

}

Der Monitor schaltet dabei auf die korrekte Auflösung um und in der Windows Vorschau sieht man auch das das Frame korrekt dargestellt wird. Im FSEM bleibt jedoch alles schwarz (außer dem Mauszeiger). Dasselbe Beispiel in Swing funktioniert problemlos.

Hat vielleicht jemand eine Idee was ich vergessen habe?

Viele Grüße,
Fancy
 
Ich ahne zwar die Antwort, aber trotzdem: Um was für eine AWT Komponente handelt es sich? Kann man diese nicht durch eine Swing Komponente ersetzen?
 
Technisch ist das lediglich ein AWT Canvas, auf dem allerdings einige native Funktionen aufgerufen werden (es ist ähnlich zum z.B. GLCanvas aus jogl). Wie schon vermutet, geht ein ersetzen mit einer Swing Komponente daher leider nicht.

Die Swing Version scheitert auch schon sobald irgendeine andere AWT Komponente verwendet wird, es liegt also leider auch nicht an meiner speziellen AWT Komponente.

Viele Grüße,
Fancy
 
Ok, zumindest lässt sich das Problem mit -Dsun.java2d.d3d=false umgehen. Dann geht bei mir sowohl die reine AWT Lösung als auch die Swing/AWT Version. Ist zwar nicht schön, aber immerhin geht’s und ich weis nun das meine AWT Komponente soweit in Ordnung ist.

Quelle, Bug report

Viele Grüße,
Fancy
 

Zurück
Oben