简体   繁体   English

JFrame repaint()和revalidate()仅在Mac OS上调整窗口大小时更新

[英]JFrame repaint() and revalidate() only updating when window is resized on Mac os

I use this class for my school app projects. 我将此类用于我的学校应用程序项目。 It is how I set the application up and it extends JFrame and implements Runnable. 这就是我设置应用程序的方式,它扩展了JFrame并实现了Runnable。 Now whenever I use this in school on a Windows computer and everything works and the screen updates, but at home on a Mac it doesn't. 现在,每当我在Windows计算机上的学校中使用此功能,一切正常且屏幕更新时,但在Mac上却无法使用。 I use Eclipse neon with JDK 1.8.0_101 Please help me out, I can't test any projects at home cause of this. 我在JDK 1.8.0_101上使用Eclipse neon。请帮帮我,由于这个原因,我无法在家测试任何项目。

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

}

This is how a game would start: 游戏开始的方式如下:

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

}

This is the home screen 这是主屏幕

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 adds buttons to the screen and image annimations katCode将按钮添加到屏幕和图像动画

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

Don't override paint() on a JFrame. 不要在JFrame上覆盖paint()。

The proper way to do custom painting is to override paintComponent(...) on a JPanel (or JComponent) and then you can set the content pane of the frame to this panel. 进行自定义绘制的正确方法是重写JPanel (或JComponent)上的paintComponent(...) ),然后可以将框架的内容窗格设置为此面板。 And don't forget to invoke super.paintComponent(...) as the first statement in the method. 并且不要忘记调用super.paintComponent(...)作为方法中的第一条语句。 Read the section from the Swing tutorial on Custom Painting for more information and working examples. 阅读有关定制绘画的Swing教程中的部分,以获取更多信息和工作示例。

However if you do get lazy, then at minimum you need to invoke super.paint (...) as the first statement in the paint(...) method. 但是,如果您确实懒惰,则至少需要调用super.paint (...)作为paint(...)方法中的第一条语句。

Also, I doubt you need the revalidate(), since you don't appear to be adding/removing components from the frame. 另外,我怀疑您是否需要revalidate(),因为您似乎没有在框架中添加/删除组件。

But in general the order should be: 但一般而言,顺序应为:

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

I also don't know why you are invoking the update() method. 我也不知道您为什么要调用update()方法。 That seems like old AWT code which you don't use in Swing. 似乎是旧的AWT代码,您没有在Swing中使用它。 I suggest you take a look at the tutorial link I gave you and look at the table of contents for other Swing basics. 我建议您看一下我给您的教程链接,并查看其他Swing基础知识的目录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM