1

所以我正在尝试更改我从教程制作的全屏游戏的背景,我正在尝试将背景更改为绿色,但它保持黑色,代码有什么问题?

屏幕.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);
    }
}

主.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);
    }
}
4

3 回答 3

5

你的第一个问题将是你的paint方法......

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

该方法的部分职责paint是绘制……背景。但既然你没有打电话,super.paint这不可能发生。

您应该避免覆盖paint顶级容器,例如JFrame使用自定义组件,JPanel并覆盖它们的paintComponent方法(不要忘记调用super.paintComponent)。

另一个潜在问题的领域是使用Thread.sleep,这可能会导致事件调度线程停止,从而阻止处理新的绘制请求。更好的解决方案可能是使用 a javax.swing.Timer,它将在后台暂停并ActionListener在 EDT 的上下文中提供通知(通过 a )......

例如

在此处输入图像描述

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);
        }
    }
}
于 2013-08-30T06:51:06.390 回答
1

这就是我为克服挑战所做的。我从 Main 类的 run 方法中删除了 setBackground、setForeground 和 setFont,并将它们添加到 Screen 类的 setFullScreen 方法中:

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

此后,我添加了“super.paint(g);” 作为Main类中paint方法的第一行

于 2016-02-16T09:54:45.770 回答
0

您只需要进行 3 次小改动,它就会起作用。按着这些次序:

步骤 1:将 getContentPane() 添加到 run() 方法中存在的 setBackgroud()

getContentPane().setBackground(Color.GREEN);

第 2 步:从 run() 方法到 paint() 方法的以下行剪切并粘贴。

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

step-3:在paint() 方法的开头添加super.paint(g)。整个paint() 方法看起来像这样;

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);
       }

如果它仍然不起作用,请在评论中告诉我!#YNWA

于 2020-05-31T14:29:27.960 回答