有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java组件只是偶尔调用

我正在制作一个程序,它接受一个二维整数数组,并使用其数据按照数组中指定的排列在屏幕上绘制瓷砖。在不修改任何代码的情况下,程序将在5次中执行4次。其他时候,自定义JPanel不会显示任何内容。插入系统后。出来print()在不同的地方,我已经确定这是由于没有显示任何内容时没有调用paintComponent方法造成的。显然,当瓷砖完美显示时,它被称为。我似乎找不到这种矛盾的根源。为什么它大部分时间都有效,而不是偶尔有效

它被称为等厚面,因为它最终将以等距形式显示瓷砖。 0相当于水砖,1相当于沙砖

JPanel类

 public class IsoPanel extends JPanel
    {
    private ArrayList <BufferedImage> tiles;
    private int[][] leveldata = 
        {
             {0,0,0,0,0,0,0,0,0,0},
             {0,1,1,1,1,1,1,1,1,0},
             {0,1,1,1,1,1,1,1,1,0},
             {0,1,1,1,1,1,1,1,1,0},
             {0,1,1,1,1,1,1,1,1,0},
             {0,1,1,1,1,1,1,1,1,0},
             {0,1,1,1,1,1,1,1,1,0},
             {0,1,1,1,1,1,1,1,1,0},
             {0,1,1,1,1,1,1,1,1,0},
             {0,0,0,0,0,0,0,0,0,0}
        };
    public IsoPanel()
    {
        tiles = new ArrayList<BufferedImage>();
        tiles.add(Frame.loadImage("water.png"));
        tiles.add(Frame.loadImage("sand.png"));
    }

    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D)g;
        for (int i=0; i<10; i++) 
        {
             for (int j=0; j<10; j++)
             {
              int x = j * 50;
              int y = i * 50;
              int tileType = leveldata[i][j];
              placeTile(tileType, x, y, g);
             }
        }
    }

    public void placeTile (int tile,int x,int y, Graphics g)
    {
        Graphics2D g2 = (Graphics2D)g;
        g2.drawImage(tiles.get(tile), null, x, y);  
    }
}

和JFrame类:

public class Frame extends JFrame
    {
    public Frame()
    {
        super ("Iso");
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(0,0,screenSize.width, screenSize.height);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setVisible(true);           
        BorderLayout bord = new BorderLayout();
        setLayout(bord);            
        IsoPanel iso = new IsoPanel();
        add(iso,BorderLayout.CENTER);
        GridLayout grid = new GridLayout(1,1);
        iso.setLayout(grid);
        iso.setVisible(true);
    }

    public static BufferedImage loadImage(String filename)
    {
        {
            try
            {
            return ImageIO.read(new File(System.getProperty( "user.dir" )+"/src/"+filename));
            }
            catch(IOException e)
            {
            }
        }
        return null;
    }

    public static void main(String[] args)
    {
        Frame one = new Frame();
    }    
}

共 (1) 个答案

  1. # 1 楼答案

    主要问题是,在初始化子组件之前,您正在调用框架上的setVisible。这是框架如何准备状态的已知问题

    所以,不是

    public Frame()
    {
        /*...*/
        setVisible(true);
    
        /*...*/
        add(iso,BorderLayout.CENTER);
    }
    

    试试看

    public Frame()
    {
        /*...*/
        add(iso,BorderLayout.CENTER);
    
        /*...*/
        setVisible(true);
    }
    

    额外的

    • 你不应该抛弃你的例外。至少,您应该打印或记录异常
    • 在绘制图像时,应该使用ImageObsever。你应该尝试使用g2.drawImage(tiles.get(tile), x, y, this);,而不是g2.drawImage(tiles.get(tile), null, x, y);。图像并不总是处于立即渲染的状态,这为组件提供了一种方法,可以对图像状态的更改做出反应,并自动重新绘制它们自己
    • 即使您正在设置父框架的大小,您的IsoPanel组件也应该以覆盖getPreferredSize的形式提供布局提示,允许您简单地pack主窗口。这降低了在不同平台和外观设置上使用不同边框尺寸的可能性
    • 您可能希望了解一下Initial Threads以及使用EventQueue.invokeLater启动UI的重要性
    • System.getProperty( "user.dir" )+"/src/"+filename)看起来它应该引用一个嵌入式资源