我如何为我的JFrameJPanelJComponents(Swing)(Kotlin)添加 "正确的 "图像(而不是图标)

问题描述 投票:0回答:1

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

我知道有类似的问题,但请注意,我想在任何类型的JComponent中添加多个图像,而不仅仅是一个,该JComponent拥有其他组件。例如,我并不关心向一个JLabel添加图像,我已经知道如何做到这一点。我想知道如何将图像添加到一个JFrame、JPanel、Container等;所有持有其他组件的东西(并且有一个add(Component)函数)。最后,我不想要那种将图像添加到一个没有文本的JLabel中,然后再将其添加到容器中的变通方法。我想只使用Image类或像BufferedImage或URL这样的子集。

我希望能够从容器类中调用add()方法,例如jFrame.add(component),其中component是某种图像。我希望这样做的结果是在屏幕上显示一个图像。ImageIcon类不是一个Component,所以这不能单独输入。我想我必须创建某种从Component或JComponent中扩展出来的自定义Image类,但我不知道我必须覆盖什么才能让它在添加到另一个JComponent中时在屏幕上显示图像。有多种解决方案,但要说明的是,我不想要某种 "中间人",在那里我添加一个JLabel或JButton或其他只包含一个Icon的东西。反正我不想显示图标,我想在屏幕的任何地方显示全尺寸的图像。我将提供一个可能的例子,说明我希望最终的结果是什么样子的。

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。

EDIT:

我试着用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类,反正我也不想这么做。这就是我想出的Image类。

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)
    }
}
image swing kotlin jcomponent
1个回答
1
投票

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

你不能将图像添加到JFrame、JPanel等。正如你所说,图像不是一个组件。你将图像添加到JLabel中,然后将标签添加到面板中。这是最简单、最直接的显示图片实际大小的方法。

不知道Kotlin是否有什么不同,但另一种选择是进行自定义绘画,并将图像画在一个 JPanel 凌驾于 paintComponent(…) 方法,并使用 Graphics.drawImage(…) 方法,然后将面板添加到框架中。阅读Swing教程 定制涂装 的绘画基础知识。

你也可以查看 背景板 的例子,将图像作为面板的背景。该图像可以

  1. 以其真实大小绘制
  2. 缩放以填充面板
  3. tiled来填充面板Just note that the image should NOT be read in the paintComponent() method as painting code should be efficient.
© www.soinside.com 2019 - 2024. All rights reserved.