【问题标题】:JFrame repaint() and revalidate() only updating when window is resized on Mac osJFrame repaint() 和 revalidate() 仅在 Mac 操作系统上调整窗口大小时更新
【发布时间】:2017-03-04 01:37:03
【问题描述】:

我将此课程用于我的学校应用项目。这就是我设置应用程序的方式,它扩展了 JFrame 并实现了 Runnable。现在,每当我在学校的 Windows 计算机上使用它时,一切正常,屏幕更新,但在家里的 Mac 上却没有。我将 Eclipse neon 与 JDK 1.8.0_101 一起使用 请帮帮我,因为这个原因,我无法在家测试任何项目。

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

public abstract class GUIApplication extends JFrame implements Runnable{

    private Screen currentScreen;
    //no main, cant instentiate an abstract class
    public GUIApplication(){
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        int x=40;
        int y=40;
        int width=1000;
        int height=640;
        setBounds(x,y,width,height);
        initScreen();
        setVisible(true);
    }
    //this is a method for creating the starting screen
    protected abstract void initScreen();

    public void setScreen(Screen screen){
        //stop controls from previous screen
        removeListeners();

        setCurrentScreen(screen);
        //add new controls
        addListeners();
    }

    private void removeListeners(){
        if(getCurrentScreen() != null){
            if(getCurrentScreen().getMouseListener() != null)     removeMouseListener(getCurrentScreen().getMouseListener());
            if(getCurrentScreen().getMouseMotionListener() != null) removeMouseMotionListener(getCurrentScreen().getMouseMotionListener());
            if(getCurrentScreen().getKeyListener() != null) removeKeyListener(getCurrentScreen().getKeyListener());
        //      if(currentScreen.getMouseWheelListener() != null) removeMouseWheelListener(currentScreen.getMouseWheelListener());
        }
    }

    private void addListeners(){
        if(getCurrentScreen() != null){
            if(getCurrentScreen().getMouseListener() != null)addMouseListener(getCurrentScreen().getMouseListener());
            if(getCurrentScreen().getMouseMotionListener() != null) addMouseMotionListener(getCurrentScreen().getMouseMotionListener());
            if(getCurrentScreen().getKeyListener() != null){
                addKeyListener(getCurrentScreen().getKeyListener());
            }
        //      if(currentScreen.getMouseWheelListener() != null) addMouseWheelListener(currentScreen.getMouseWheelListener());
        }
    }

    public void paint(Graphics g){
        g.drawImage(getCurrentScreen().getImage(), 0, 0, null);
    }

    public void run(){
        while(true){
            getCurrentScreen().update();
            repaint();
            try {
                Thread.sleep(30);
                repaint();
                revalidate();

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public Screen getCurrentScreen() {
        return currentScreen;
    }
    public void setCurrentScreen(Screen currentScreen) {
        this.currentScreen = currentScreen;
    }

}

这就是游戏的开始方式:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;

import javax.swing.JFrame;


import game.mainScreenTeam.Dragon;
import game.mainScreenTeam.HomeScreen;
import game.miniGameTeam.GameInstructions;
import game.miniGameTeam.GameScreen;
import game.miniGameTeam.HighScoreScreen;
import game.shopScreen.BuyScreenWendy;
import game.shopScreen.HomeShopScreen;
import game.shopScreen.SellShopZheng;

import guiPractice.GUIApplication;
import guiPractice.Screen;
import guiPractice.components.AnimatedComponent;

/**
 * @author Kat
 *
 */
public class DragonLand extends GUIApplication {

    public static DragonLand game;
    public static int coins = 1500; 
    public static HomeScreen homeScreen;
    public static Screen shopMain; // shop 1
    public static Screen sellScreen; // shop 2
    public static Screen buyScreen; // shop 3
    public static Screen highscoreScreen; // high score
    public static GameScreen miniGameScreen; // minigame
    public static Screen gameInstructionsScreen;
    public static Screen HelpScreen;
    public static Color NAVY;
    public static Color BRIGHT_PINK;
    public static Color LIGHT_PINK;
    public static Color LIGHT_NUDE;
    public static Color DARKER_NUDE;


    /**
     * 
     */
//  public static void addDragon(AnimatedComponent a){
//      dragonList.add(a);
//  }
    public DragonLand() {

    }

    /* (non-Javadoc)
     * @see guiPractice.GUIApplication#initScreen()
     */
    @Override
    protected void initScreen() {
        initColors();


        miniGameScreen = new GameScreen(getWidth(),getHeight());
        shopMain = new HomeShopScreen(getWidth(),getHeight());
        sellScreen = new SellShopZheng(getWidth(),getHeight());
        homeScreen = new HomeScreen(getWidth(),getHeight());
        buyScreen = new BuyScreenWendy(getWidth(),getHeight());
        highscoreScreen = new HighScoreScreen(getWidth(),getHeight());
        HomeScreen.jenCode = new game.mainScreenTeam.HomeJenniber();
        gameInstructionsScreen = new GameInstructions(getWidth(), getHeight());

        setScreen(homeScreen);


    }
    private void initColors() {
        NAVY = new Color(62,74,99);
        BRIGHT_PINK = new Color(224,102,102);
        LIGHT_PINK = new Color(248,186,182);
        LIGHT_NUDE = new Color(244,215,183);
        DARKER_NUDE = new Color(230,195,147);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        game = new DragonLand();
        Thread go = new Thread(game);
        go.start();
    }

    //public coin getter + setter
        public void setCoins(int x){
            coins = x;
        }
        public int getCoins(){
            return coins;
        }

}

这是主屏幕

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.ImageIcon;

import game.DragonLand;
import guiPractice.ClickableScreen;
import guiPractice.components.Action;
import guiPractice.components.AnimatedComponent;
import guiPractice.components.Button;
import guiPractice.components.Graphic;
import guiPractice.components.TextLabel;
import guiPractice.components.Visible;
import guiPractice.sampleGames.MouseFollower;

/**
 * @author Kat 
 * @author Jenniber
 *
 */
public class HomeScreen extends ClickableScreen implements Runnable{

    private Graphic background;
    public static HomeJenniber jenCode;

    public HomeScreen(int width, int height) {
        super(width, height);
        Thread play = new Thread(this);
        play.start();

    }

    @Override
    public void initAllObjects(ArrayList<Visible> viewObjects) {

        background=new Graphic(0,0,getWidth(),getHeight(),"img/Grassland.png");
        viewObjects.add(background);
        HomeKat katCode=new HomeKat(viewObjects, getWidth(), getHeight());

    }


    @Override
    public void run() {
    }

}

katCode 将按钮添加到屏幕和图像动画

【问题讨论】:

  • 有什么异常或问题?
  • 没有异常或问题,除非我手动调整窗口大小,否则屏幕不会更新

标签: java macos swing jframe repaint


【解决方案1】:
public void paint(Graphics g){
    g.drawImage(getCurrentScreen().getImage(), 0, 0, null);
}

不要在 JFrame 上覆盖paint()。

进行自定义绘画的正确方法是在JPanel(或JComponent)上覆盖paintComponent(...),然后您可以将框架的内容窗格设置为此面板。并且不要忘记调用super.paintComponent(...) 作为方法中的第一条语句。阅读 Custom Painting 上的 Swing 教程部分,了解更多信息和工作示例。

但是,如果您确实变得懒惰,那么您至少需要调用 super.paint(...) 作为 paint(...) 方法中的第一条语句。

另外,我怀疑您是否需要 revalidate(),因为您似乎没有在框架中添加/删除组件。

但一般来说顺序应该是:

revalidate(); // to invoke the layout manager
repaint(); // paint components in new location.

我也不知道你为什么要调用 update() 方法。这似乎是您在 Swing 中不使用的旧 AWT 代码。我建议您查看我提供给您的教程链接,并查看其他 Swing 基础知识的目录。

【讨论】:

  • update() 方法适用于屏幕,因为需要调用该方法。我还尝试按照您的建议添加 super.paint() ,但似乎没有用。事实上,现在屏幕根本没有显示任何东西。另外,我正在学习 AP Java,所以这个特定的课程是我的老师在课堂上制作的
  • @Ksemenova,我们不知道 Screen 类的作用。我只知道你的代码是错误的。如果您覆盖paint(),那么super.paint() 应该是第一个语句,否则您将失去Swing 功能,因为您没有调用某些绘画逻辑。我们也不知道您如何启动应用程序或启动线程。向许多未知数提供具体帮助。
  • 感谢您的帮助,抱歉我没有把帖子说得更清楚,我只是在上面添加了屏幕代码和创建游戏代码。如果你看到任何东西,请告诉我。奇怪的是,在 Mac 上它还没有在 PC 上运行。
  • @Ksemenova,您的代码有太多自定义类,我无法了解您在做什么。 It is just strange that on a mac it doesn't run yet on a PC it does. - 不,这并不奇怪。通过不调用 super.paint(...),您打破了 Swing 绘画惯例。 paint() 方法负责缓冲等。你可能会在不同的平台上得到不同的结果,因为每个平台的绘制可能略有不同。因此,当您违反规则时,您会得到随机结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
  • 2023-02-10
  • 2012-05-16
  • 2013-04-14
相关资源
最近更新 更多