Search code examples
javaimagerendering

importing images causes rendering issues


Modifiers.java

package game;
import java.awt.*;
import java.io.*;
import javax.swing.*;

public class Modifiers  extends Data{
    public static void setupJcomponents(){

        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        try{
            PixelFont = Font.createFont(Font.TRUETYPE_FONT, new File("src/game/PixelFont.ttf"));
            ge.registerFont(PixelFont);
        } catch (IOException | FontFormatException e) {
            PixelFont = new Font("OCR A Extended", Font.PLAIN, heightUnits*2);
            ge.registerFont(PixelFont);
        }

        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setUndecorated(true);
        frame.setSize(MW,MH);
        frame.setResizable(false);
        frame.setVisible(true);
        frame.setLayout(null);

        uiPanelMenu.setLayout(null);
        uiPanelMenu.setVisible(true);
        uiPanelMenu.setBounds(0,0,MW,MH);
        uiPanelMenu.setOpaque(false);
        for(int btn=0; btn<4; btn++) {
            try {
              buttonImage[btn] = new ImageIcon(Frame.class.getResource("/game/SelectionButton.png"));
            } catch (Exception e) {
                e.printStackTrace();
            }
            buttons[btn] = new JPanel();
            buttonLabel[btn] = new JLabel("",SwingConstants.CENTER);
            buttonLabel[btn].setIcon(buttonImage[btn]);
            buttons[btn].setBounds(widthUnits*15,(heightUnits*13)+(heightUnits*3*btn),widthUnits*15,heightUnits*3);
            buttonLabel[btn].setBounds(0,0,buttons[btn].getWidth(),buttons[btn].getHeight());
            buttons[btn].setLayout(null);
            uiPanelMenu.add(buttons[btn]);
            buttons[btn].add(buttonLabel[btn]);
            buttonLabel[btn].setForeground(Color.black);
            buttons[btn].setBackground(Color.white);
            buttonLabel[btn].setText("Button "+(btn+1));
            buttonLabel[btn].setFont(new Font("PixelFont", Font.PLAIN, heightUnits*2));
            buttons[btn].setVisible(true);
            buttonLabel[btn].setVisible(true);
        }


        menuBackground.setBounds(0,0,MW,MH);
        menuBackground.setBackground(Color.black);
        menuBackground.setVisible(true);
        uiPanelMenu.add(menuBackground);

        healthIndicator.setText(String.valueOf(healthValue));
        healthIndicator.setFont(new Font("PixelFont", Font.PLAIN, heightUnits*2));
        healthIndicator.setBounds(widthUnits*20,heightUnits*20,widthUnits*5,heightUnits*2);
        healthIndicator.setVisible(true);
        healthIndicator.setOpaque(false);
        healthIndicator.setForeground(Color.blue);
        uiPanelFight.add(healthIndicator);

        frame.getContentPane().add(uiPanelMenu);
    }
}

data.java

package game;

import java.awt.*;

import javax.swing.*;

public class Data { 

        // this is where I will declare and alter all variable that will be used
        public static JFrame frame = new JFrame();
        public static JLabel healthIndicator = new JLabel("",SwingConstants.CENTER); 
        public static JPanel buttons[] = new JPanel[5];
        public static JLabel buttonLabel[] = new JLabel[5];
        public static JPanel menuBackground = new JPanel();
        public static JPanel title = new JPanel();
        public static JPanel uiPanelMenu = new JPanel();
        public static JPanel uiPanelFight = new JPanel();
        public static ImageIcon buttonImage[] = new ImageIcon[5];

        public static final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        public static final int MW = (int) screenSize.getWidth();
        public static final int MH = (int) screenSize.getHeight();
        public static final int widthUnits = MW/45;
        public static final int heightUnits = MH/25;

        public static Font PixelFont;

        public static int maxHealth = 100;
        public static int healthValue = maxHealth;

}

frame.java

package game;

public class Frame {

    public static void main(String[] args) {
        Modifiers.setupJcomponents();
    }

}

whenever i try to reference the image here: buttonImage[btn] = new ImageIcon(Frame.class.getResource("/game/SelectionButton.png")); if it is wrong then it will just give me a NullPointerException, but if the image name is correct then the entire panel that holds everything disappears, all of the objects i used are properly declared in a separate Data.java class, i know it is instantiated correctly but i dont know why everything is not rendering when the line hits the image location.


Solution

  • So your code raises so many questions it's not funny. However, your basic problem(s) come down to lack of understanding in how the basic Swing API works.

    Swing is lazy. It won't update the UI when you add/remove components from containers, that's up to you.

    So, your basic code currently looks like...

    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    //frame.setUndecorated(true);
    frame.setSize(MW, MH);
    //frame.setResizable(false);
    frame.setVisible(true);
    // ?? Why ?? Besides, it's not doing what you think it is
    frame.setLayout(null);
    
    // Add all the stuff to uiPanelMenu ...
    
    frame.getContentPane().add(uiPanelMenu);
    

    The problem is, once you make the window visible, you are responsible for triggering layout and paint passes.

    You can fix the basic problem by adding

    frame.getContentPane().revalidate();
    frame.getContentPane().repaint();
    

    after frame.getContentPane().add(uiPanelMenu); or moving frame.setVisible(true); after frame.getContentPane().add(uiPanelMenu); which will probably produce a more desirable result.

    I know you think you're making your life easier by using null layouts, but your not, nor are you taking into considerations all the differences in how text is rendered on different platforms/hardware.

    You're doing yourself a massive disservice by not making use of the layout management API (and will end up having to replicate much of its functionality yourself).

    Instead, take the time learn more about the available layout managers - Laying Out Components Within a Container