【问题标题】:JLabel Icon not showing after change更改后未显示 JLabel 图标
【发布时间】:2014-07-13 07:07:50
【问题描述】:

我尝试查找此问题,但大多数答案是文件路径错误,但很可能并非如此。该文件在我第一次使用时有效。

我正在制作战舰游戏,并使用 JLabels 在地图上显示战舰。我想制作一个按钮来将船从水平旋转到垂直,但是当我尝试更改它时它的图标消失了。

当我运行这个构造函数代码时:

public Ship(int size, String direction, boolean active, Client c,
        ClientGUI cg) {
    this.c = c;
    this.cg = cg;
    health = size;
    this.active = active;
    this.direction = direction;

    file = "img/" + Integer.toString(health) + direction + ".png";   // String
    try {
        System.out.println(file);
        tx = ImageIO.read(new File(file));    // BufferedImage
    } catch (IOException e) {

        e.printStackTrace();
    }
    texture = new JLabel(new ImageIcon(tx));
    if (direction.equals("v"))
        texture.setBounds(0, 0, 40, 40 * size);
    else
        texture.setBounds(0, 0, 40 * size, 40);
    texture.setVisible(true);

}

一切正常,我可以看到图像。

然后我尝试旋转它,使用几乎相同的代码:

void rotate() {
    if (direction.equals("h")) {
        direction = "v";
        file = "img/" + Integer.toString(health) + direction + ".png";
        try {
            System.out.println(file);
            tx = ImageIO.read(new File(file));
        } catch (IOException e) {

            e.printStackTrace();
        }
        texture.setBounds(0,0,40, 40 * size);
        texture.setIcon(new ImageIcon(tx));

    } else {
        direction = "h";
        file = "img/" + Integer.toString(health) + direction + ".png";
        try {
            System.out.println(file);
            tx = ImageIO.read(new File(file));
        } catch (IOException e) {

            e.printStackTrace();
        }
        texture.setIcon(new ImageIcon(tx));
        texture.setBounds(0,0,40 * size, 40);
    }

    cg.repaint();    // not sure if I need to do this
}

然后它就消失了……

我试过放置两艘船,一艘是旋转的,只是缺少 JLabel 或 JLabel 上的图标。

【问题讨论】:

  • 谷歌“我如何比较 Java 中的字符串”。我懒得链接了
  • 非常糟糕的字符串比较以这种方式direction == "h" 是错误的。
  • @Braj 好的,我已修复,但这与我的问题无关
  • 我怎么知道它没有引起问题?这是朝着解决这个问题迈出的重要一步。
  • 文件存储在哪里?它们是在 src 中还是在外部文件中

标签: java swing jlabel


【解决方案1】:

如果您通过调用更改其状态的方法来更新JLabel texture,则它可能会或可能不会立即更新,除非您调用texture.repaint()texture.paintAll(texture.getGraphics()) 或其他类似方法。

另外,我会考虑将LayoutManager 用于您用来保存 JLabels 网格的任何上层组件。如果您使用游戏板的GridLayout 并且:

  1. 使用texture.setPreferredSize(Dimension) 设置JLabel 的首选尺寸,并在设置游戏时调用一次frame.pack();或

  2. label.setSize(Dimension) 设置一次JLabel 的大小,不要打包你的JFrame

您只需要设置一次 JLabel 的大小,而不是每次都为标签设置一个新的 ImageIcon。因为,理想情况下,您的游戏不应该做任何不必要的额外工作,因此它的性能更快。

我还建议将每个可能的 ImageIcon 维护为类中的静态字段,而不是每次都从文件中访问它们。这样,你从静态初始化方法中读取一次,然后到达船可以在改变方向时直接访问。

【讨论】:

  • 第二个不是和我已经做过的一样吗?我确实有repaint() 也调用了我的整个窗口。我使用绝对布局。我每次都设置 JLabel 的大小,因为图像大小也会发生变化。
  • If you update the JLabel texture by calling a method which changes it's state, it may or may not be updated immediately unless you call - 每当您更改 Swing 组件的属性时,它都会对其自身调用 revalidate() 和 repaint(),您不需要手动调用 repaint。
【解决方案2】:

我想制作一个按钮来将船从水平旋转到垂直

您可以使用Rotated Icon 类为您进行轮换。

【讨论】:

  • 不能像我那样做吗?我实际上不需要旋转图像,因为我有单独的水平和垂直文件,我只想交换它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
相关资源
最近更新 更多