【问题标题】:If I already have a JLabel with an ImageIcon, If I change the ImageIcon and then pack the frame, it doesn't pack如果我已经有一个带有 ImageIcon 的 JLabel,如果我更改 ImageIcon 然后打包框架,它不会打包
【发布时间】:2017-09-24 08:48:32
【问题描述】:

这是我的代码:

/**
 * Opens file and gives a warning if non image.
 */
private void openFile() {
    final int returnVal = myFileChooser.showOpenDialog(null);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
        myFile = myFileChooser.getSelectedFile();
        try {
            myImage = PixelImage.load(myFile);
            myImageIcon = new ImageIcon(myImage);
            myImageLabel.setIcon(myImageIcon);

            this.pack();
            this.setMinimumSize(this.getSize());
            enableButtons();  
        } catch (final IOException exception) {
            JOptionPane.showMessageDialog(null, 
                        "The selected file did not contain an image!");
        }
    } else {
        System.out.println("ERROR FILE"); //PLACEHOLDER
    }
}

所以我想做什么:

  1. 加载 PixelImage (myImage)
  2. 将 ImageIcon (myImageIcon) 设置为 PixelImage (myImage)
  3. 将 JLabel (myImageLabel) 设置为 ImageIcon (myImageIcon)
  4. 将框架打包为围绕图像的适当大小,并设置框架的最小尺寸以满足加载图像后框架的尺寸。

除了我尝试加载新图像时,这四个步骤都可以正常工作。 我遇到的问题是,当我在现有图像上加载新图像时,它会擦除​​旧图像(如预期的那样),然后当它在新图像周围打包框架(比如较小的图像)时,它会保留帧的最小尺寸要求基于旧图像而不是设置最小尺寸 (this.setMinimumSize(this.getSize()))。如果我加载较小的图像,我希望我的框架调整大小以满足这些较小图像的高度和宽度,而不是基于旧图像。

【问题讨论】:

  • 加载更大的图像时打包是否有效?

标签: java


【解决方案1】:

也许可以试试:

this.setMinimumSize(null);
this.pack();
this.setMinimumSize(this.getSize());

所以 pack() 方法不限于之前的最小值?如果 null 不起作用,则使用 (0, 0) 的 Dimension。

【讨论】:

  • 谢谢。我没有意识到 pack() 考虑了最低限度。
【解决方案2】:

虽然有 Java 类来表示 Windows,但 Window 是一种系统资源,Java 在很大程度上无法控制它。 (所有 Frames 和 JFrames 当然都是 Windows。)

当您调用pack()时,系统会响应调整窗口大小的请求,但可能不会立即生效。因此,不能保证在对 pack() 的调用完成时窗口的大小会发生变化。

这在documentation of the Window class中有描述:

… 顶层窗口(包括Windows、Frames、Dialogs)的位置和大小由桌面的窗口管理系统控制。对setLocationsetSizesetBounds 的调用是转发到窗口管理系统的请求(不是指令)。将尽一切努力满足此类要求。但是,在某些情况下,窗口管理系统可能会忽略此类请求,或修改请求的几何图形,以便以更接近桌面设置的方式放置和调整 Window

由于本机事件处理的异步特性,getBoundsgetLocationgetLocationOnScreengetSize 返回的结果可能无法反映屏幕上窗口的实际几何形状,直到最后一个请求完成处理。在处理后续请求期间,这些值可能会在窗口管理系统满足请求时相应更改。

通常,这可以通过使用invokeLater来解决:

this.pack();
EventQueue.invokeLater(() -> {
    this.setMinimumSize(this.getSize());
    enableButtons();  
});

【讨论】:

    猜你喜欢
    • 2014-09-28
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多