【问题标题】:importing images causes rendering issues导入图像会导致渲染问题
【发布时间】:2019-12-04 23:51:55
【问题描述】:

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

数据.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();
    }

}

每当我尝试在此处引用图像时: buttonImage[btn] = new ImageIcon(Frame.class.getResource("/game/SelectionButton.png")); 如果它是错误的,那么它只会给我一个 NullPointerException,但如果图像名称是正确的,那么包含所有内容的整个面板都会消失,我使用的所有对象都在单独的 Data.java 类中正确声明,我知道它是正确实例化,但我不知道为什么当线条到达图像位置时一切都没有渲染。

【问题讨论】:

  • new File("src/game/PixelFont.ttf")); 是你的第一个问题,永远不要在你的代码中引用src
  • uiPanelMenu.setLayout(null); ????你想知道为什么你有问题。另外,请考虑使用ImageIO.read 而不是ImageIcon
  • 我意识到这两个都是不好的形式,我相对较新,所以我肯定会犯错误,但我知道这两个都不是问题,一切正常,直到我添加这一行:@ 987654330@ 一切都在渲染,直到它尝试使用图像,但是如果我使用这个:buttonImage[btn] = new ImageIcon(Frame.class.getResource("/game/-----.png")); 其他一切正常,它只是给了我一个空指针异常,所以我知道这条线是问题的根源,我只是不知道如何修复它
  • 如果没有minimal reproducible example,我不能再说什么了
  • 可以重现吗?你只需要任何 ttf 文件作为字体和任何名为 SelectionButton 的 png

标签: java image rendering


【解决方案1】:

所以你的代码提出了很多问题,这并不好笑。但是,您的基本问题归结为对基本 Swing API 的工作原理缺乏了解。

Swing 是懒惰的。当您从容器中添加/删除组件时,它不会更新 UI,这取决于您。

所以,您的基本代码目前看起来像......

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

问题是,一旦使窗口可见,您就要负责触发布局和绘制通道。

你可以通过添加来解决基本问题

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

frame.getContentPane().add(uiPanelMenu); 之后或在frame.getContentPane().add(uiPanelMenu); 之后移动frame.setVisible(true);,这可能会产生更理想的结果。

我知道您认为使用 null 布局让您的生活更轻松,但您没有,也没有考虑到文本在不同平台/硬件上呈现方式的所有差异。

不使用布局管理 API 对自己造成了极大的伤害(最终将不得不自己复制其大部分功能)。

相反,请花时间了解有关可用布局管理器的更多信息 - Laying Out Components Within a Container

【讨论】:

  • 谢谢,我会尽量找到适合我项目的布局。
猜你喜欢
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 2015-04-04
  • 2014-06-03
相关资源
最近更新 更多