首页 > 解决方案 > 如何将“正确”图像(不是图标)添加到我的 JFrame/JPanel/JComponents (Swing) (Kotlin)

问题描述

语言:Kotlin,GUI 库:Swing,IDE:IntelliJ IDEA

我知道有类似措辞的问题,但请注意,我想向包含其他组件的任何类型的 JComponent 添加多个图像,而不仅仅是一个图像。例如,我不关心将图像添加到 JLabel,我已经知道如何做到这一点。我想知道如何将图像添加到 JFrame、JPanel、Container 等;所有包含其他组件(并具有 add(Component) 功能)的东西。最后,我不希望您将图像添加到没有文本的 JLabel 然后将其添加到容器中的解决方法。我想只使用 Image 类或像 BufferedImage 或 URL 这样的子集。

我希望能够从 Container 类中调用 add() 方法,例如 jFrame.add(component),其中 component 是某种图像。我希望这会导致屏幕上显示图像。ImageIcon 类不是组件,因此不能单独输入。我想我必须创建某种从 Component 或 JComponent 扩展的自定义 Image 类,但我不知道当添加到另一个 JComponent 时我必须重写什么才能在屏幕上显示图像。对此有多种解决方案,但要澄清的是,我不想要某种“中间人”,在其中添加 JLabel 或 JButton 或仅包含图标的东西。我不想显示图标,我想在屏幕上的任何地方显示全尺寸图像。

class MyApp() {

    fun init() {
        var jFrame = JFrame()
        jFrame.add(Image("filepath/image.png"))
        //Some other JFrame boiler plate
        jFrame.isVisible = true
    }

}

fun main() {
    MyApp().init()
}

不清楚的部分是 Image 类,以及它是继承 JImage 的自定义类,还是一些我不知道的已经定义的类或方法。我知道 ImageIO 和 BufferedImage 和 ImageIcon,但它们都没有直接进入这个方法,因为它们不继承 Component 或 JComponent。

编辑:

我尝试使用 Camickr 的第二种解决方案,但没有奏效。我将发布代码以查看是否犯了一个简单的错误。

import java.awt.Image as AWTImage
import java.awt.Image.*
//Including these imports as I used name alias so I had to say what it was from.

open class JImage(var point: Point = Point(0, 0), image: AWTImage): JComponent() {
    var image: ImageIcon = ImageIcon(image)

    override fun paintComponent(g: Graphics?) {
        super.paint(g)
        g?.drawImage(image.image, point.x.toInt(), point.y.toInt(), null)
    }
}

class SplashScreen(image: JImage): Frame() {

    init {
        //jFrame.isUndecorated = true
        jFrame.add(image)
    }
}

class MyApp {

    fun init() {
        var jFrame = SplashScreen(JImage(image = ImageIO.read(Loader().getClassLoader().getResourceAsStream("resources/images/splashscreen/SplashScreen.png"))).getScaledInstance(Size(1000, 1000*3/5)))
        jFrame.isVisible = true
    }
}

fun main() {
    MyApp().init()
}

最终编辑:

好的,所以我在尝试此解决方案时确实犯了一个简单的错误。我覆盖了paintComponent(),但在其中,我调用了super.paint()。此外,我意识到我不必使用 ImageIcon 类,反正我也不想这样做。这是我想出的图像类。

open class JImage(var point: Point = Point(0, 0), var image: AWTImage): JComponent() {

    fun getScaledInstance(size: Size, scalingMethods: ScalingMethods = ScalingMethods.DEFAULT): JImage {
        val scale: Int = when(scalingMethods) {
            ScalingMethods.DEFAULT -> SCALE_DEFAULT
            ScalingMethods.FAST -> SCALE_FAST
            ScalingMethods.AREA_AVERAGING -> SCALE_AREA_AVERAGING
            ScalingMethods.REPLICATE -> SCALE_REPLICATE
            ScalingMethods.SMOOTH -> SCALE_SMOOTH
        }
        return JImage(point, image.getScaledInstance(size.width.toInt(), size.height.toInt(), scale))
    }

    override fun paintComponent(g: Graphics?) {
        super.paintComponent(g)
        g?.drawImage(image, point.x.toInt(), point.y.toInt(), null)
    }
}

标签: imageswingkotlinjcomponent

解决方案


我想知道如何将图像添加到 JFrame、JPanel、Container 等。

您不会将图像添加到 JFrame、JPanel 等。正如您所说,图像不是组件。您将图像添加到 JLabel 并将标签添加到面板。这是以实际大小显示图像的最简单、更直接的方法。

不知道 Kotlin 是否有任何不同,但另一种选择是进行自定义绘画并JPanel通过覆盖该paintComponent(…)方法并使用该Graphics.drawImage(…)方法在 a 上绘画图像,然后将面板添加到框架中。阅读关于自定义绘画的 Swing 教程以了解绘画基础知识。

您还可以查看背景面板以获取将图像绘制为面板背景的示例。图像可以是:

  1. 以真实尺寸绘制
  2. 缩放以填充面板
  3. 平铺以填充面板请注意,不应在 paintComponent() 方法中读取图像,因为绘画代码应该是有效的。

推荐阅读