1

So I'm trying to change the background on a full screen game I'm making from a tutorial, I'm trying to change the background to green, but it stays black, what's wrong with the code?

Screen.java

package debels;

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

public class Screen {
    private GraphicsDevice vc;

    public Screen(){
        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
        vc = env.getDefaultScreenDevice();
    }

    public void setFullScreen(DisplayMode dm, JFrame window){
        window.setUndecorated(true);
        window.setResizable(false);
        vc.setFullScreenWindow(window);

        if (dm != null && vc.isDisplayChangeSupported()){
            try{
                vc.setDisplayMode(dm);
            }catch (Exception e){}
        }
    }

    public Window getFullScreen(){
        return vc.getFullScreenWindow();
    }

    public void restoreScreen(){
        Window w = vc.getFullScreenWindow();
        if (w != null){
            w.dispose();
        }
        vc.setFullScreenWindow(null);
    }
}

Main.java

package debels;

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

public class Main extends JFrame{
    private static final long serialVersionUID = -7498470134154894036L;

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

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

        Screen s = new Screen();
        try{
            s.setFullScreen(dm, this);
            try{
                Thread.sleep(5000);
            }catch(Exception e){}
        }finally{
            s.restoreScreen();
        }
    }

    public void paint(Graphics g){
        g.drawString("Hello",  200, 200);
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Debels
  • 167
  • 1
  • 3
  • 15
  • I would start by saying, I don't think the `Thread.sleep` is doing you any favours, nor is the `paint` method. – MadProgrammer Aug 30 '13 at 06:49
  • The Thread.sleep is just to see the fullscreen, the paint method doesn't seem to conflict, since it works as expected – Debels Aug 30 '13 at 06:51
  • *"paint method doesn't seem to conflict, since it works as expected"* - That's the problem, it isn't working as it should, see my answer for more details ;) – MadProgrammer Aug 30 '13 at 06:53

3 Answers3

5

Your first problem is going to be your paint method...

public void paint(Graphics g){
    g.drawString("Hello",  200, 200);
}

Part of the responsibility of the paint method is to paint...the background. But since you're not calling super.paint this can't happen.

You should avoid overriding paint on top level containers, like JFrame and instead use a custom component, like JPanel for example, and override their paintComponent method (not forgetting to call super.paintComponent).

Another area of potential issue is the use of Thread.sleep, this could be causing the Event Dispatching Thread to be halted, preventing from processing new paint requests. A better solution might be to use a javax.swing.Timer, which will pause in the background and provide notification (via a ActionListener) within the context of the EDT...

For example

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestFullScreen {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());

                final Screen s = new Screen();
                DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN);
                s.setFullScreen(dm, frame);

                Timer timer = new Timer(5000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        s.restoreScreen();
                    }
                });
                timer.start();
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setBackground(Color.GREEN);
            setForeground(Color.WHITE);
            setFont(new Font("Arial", Font.PLAIN, 24));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int width = getWidth();
            int height = getHeight();
            FontMetrics fm = g2d.getFontMetrics();
            String text = "It's not easy to be green";
            int x = (width - fm.stringWidth(text)) / 2;
            int y = ((height - fm.getHeight()) / 2) + fm.getAscent();
            System.out.println(width + "x" + height);
            System.out.println(x + "x" + y);
            g2d.drawString(text, x, y);
            g2d.dispose();
        }
    }

    public class Screen {

        private GraphicsDevice vc;

        public Screen() {
            GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
            vc = env.getDefaultScreenDevice();
        }

        public void setFullScreen(DisplayMode dm, JFrame window) {
            window.setUndecorated(true);
            window.setResizable(false);
            vc.setFullScreenWindow(window);

            if (dm != null && vc.isDisplayChangeSupported()) {
                try {
                    vc.setDisplayMode(dm);
                } catch (Exception e) {
                }
            }
        }

        public Window getFullScreen() {
            return vc.getFullScreenWindow();
        }

        public void restoreScreen() {
            Window w = vc.getFullScreenWindow();
            if (w != null) {
                w.dispose();
            }
            vc.setFullScreenWindow(null);
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I'm quite confused at the moment, I'm quite new to the graphical part on Java, how would I go with writing a string on the screen or an image without replacing paint? – Debels Aug 30 '13 at 06:59
  • You're on the right track. But what you've done is replaced all the work that `paint` was doing with your text drawing... – MadProgrammer Aug 30 '13 at 07:00
  • I tried changing the background, foreground and font change to the paint method, but it doesn't seem to do much difference, I still get the black screen :/ – Debels Aug 30 '13 at 07:10
  • Check my example. You need to allow the `paint` method to do it's job and THEN add your extra work on top... – MadProgrammer Aug 30 '13 at 07:16
  • Well I just changed from JFrame to JPanel and added the JPanel to the JFrame and it worked. Thanks a lot for the help. – Debels Aug 30 '13 at 07:48
1

This is what I did to overcome the challenge. I removed the setBackground, setForeground, and setFont from the run method in the Main class and added them to the setFullScreen method in the Screen class:

    window.getContentPane().setBackground(Color.PINK);
    window.setForeground(Color.BLUE);
    window.setFont(new Font ("Arial", Font.PLAIN, 24));

Thereafter, I added "super.paint(g);" as the first line of the paint method in the Main class

0

You just need to make 3 little changes and it will work. Follow these steps:

Step-1:Add getContentPane() to setBackgroud() which is present in the run() method

getContentPane().setBackground(Color.GREEN);

Step-2: Cut & paste below lines from run() method to paint() method.

getContentPane().setBackground(Color.GREEN);
setForeground(Color.BLUE);
setFont(new Font("Arial", Font.PLAIN, 24));

step-3: Add super.paint(g) in the starting of paint() method. the whole paint() method will look like this;

public void paint(Graphics g){
        super.paint(g);
        getContentPane().setBackground(Color.GREEN);
        setForeground(Color.BLUE);
        setFont(new Font("Arial", Font.PLAIN, 24));
        g.drawString("Hello",  200, 200);
       }

if it still doesn't work let me know in the comment! #YNWA

Akshay Ashok
  • 107
  • 2
  • 9