如何将 "proper" 图像(不是图标)添加到我的 JFrame/JPanel/JComponents (Swing) (Kotlin)
How can I add "proper" images (not Icons) to my JFrame/JPanel/JComponents (Swing) (Kotlin)
语言:科特林,
GUI 库:Swing,
IDE:IntelliJ IDEA
我知道有类似措辞的问题,但请注意,我想向包含其他组件的任何类型的 JComponent 添加多张图像,而不仅仅是一张图像。例如,我不关心将图像添加到 JLabel,我已经知道该怎么做。我想知道如何将图像添加到 JFrame、JPanel、Container 等;所有包含其他组件(并具有 add(Component) 功能)的东西。最后,我不希望将图像添加到没有文本的 JLabel,然后将其添加到容器中。我只想使用图像 class 或像 BufferedImage 或 URL.
这样的子集
我希望能够从 Container class、jFrame.add(component) 调用 add() 方法,例如,其中 component 是某种图像。我希望这会导致图像显示在屏幕上。
ImageIcon class 不是组件,因此不能单独输入。我想我必须创建某种从 Component 或 JComponent 扩展的自定义图像 class,但我不知道我必须重写什么才能在添加到另一个 JComponent 时在屏幕上显示图像.对此有多种解决方案,但需要澄清的是,我不希望在我添加 JLabel 或 JButton 或仅包含图标的地方使用某种 "middle man"。反正我不想显示图标,我想在屏幕上的任何地方显示全尺寸图像。我将提供一个可能的示例,说明我希望最终结果是什么样子。
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()
}
不清楚的部分是图像 class,以及它是否是继承 JImage 的自定义 class,或者一些已经定义的 class 或我不知道的方法。我知道 ImageIO 和 BufferedImage 和 ImageIcon,但是 none 它们直接进入这个方法,因为它们不继承 Component 或 JComponent。
编辑:
我尝试使用 Camickr 的第二种解决方案,但没有用。我将 post 代码看是否犯了一个简单的错误。
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 class,反正我也不想这样做。这是我想出的图像 class。
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)
}
}
I want to know how to add an image to a JFrame, JPanel, Container, etc.
您不会将图像添加到 JFrame、JPanel 等。正如您所说,图像不是组件。您将图像添加到 JLabel 并将标签添加到面板。这是以实际大小显示图像的最简单、更直接的方法。
不知道 Kotlin 是否有任何不同,但另一种选择是通过覆盖 paintComponent(…)
方法并使用 Graphics.drawImage(…)
方法,然后将面板添加到框架中。阅读 Custom Painting 上的 Swing 教程,了解绘画基础知识。
您还可以查看 Background Panel 将图像绘制为面板背景的示例。图片可以是:
- 按实际尺寸绘制
- 缩放以填充面板
- 平铺填充面板
请注意,不应在 paintComponent() 方法中读取图像,因为绘画代码应该是高效的。
语言:科特林, GUI 库:Swing, IDE:IntelliJ IDEA
我知道有类似措辞的问题,但请注意,我想向包含其他组件的任何类型的 JComponent 添加多张图像,而不仅仅是一张图像。例如,我不关心将图像添加到 JLabel,我已经知道该怎么做。我想知道如何将图像添加到 JFrame、JPanel、Container 等;所有包含其他组件(并具有 add(Component) 功能)的东西。最后,我不希望将图像添加到没有文本的 JLabel,然后将其添加到容器中。我只想使用图像 class 或像 BufferedImage 或 URL.
这样的子集我希望能够从 Container class、jFrame.add(component) 调用 add() 方法,例如,其中 component 是某种图像。我希望这会导致图像显示在屏幕上。 ImageIcon class 不是组件,因此不能单独输入。我想我必须创建某种从 Component 或 JComponent 扩展的自定义图像 class,但我不知道我必须重写什么才能在添加到另一个 JComponent 时在屏幕上显示图像.对此有多种解决方案,但需要澄清的是,我不希望在我添加 JLabel 或 JButton 或仅包含图标的地方使用某种 "middle man"。反正我不想显示图标,我想在屏幕上的任何地方显示全尺寸图像。我将提供一个可能的示例,说明我希望最终结果是什么样子。
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()
}
不清楚的部分是图像 class,以及它是否是继承 JImage 的自定义 class,或者一些已经定义的 class 或我不知道的方法。我知道 ImageIO 和 BufferedImage 和 ImageIcon,但是 none 它们直接进入这个方法,因为它们不继承 Component 或 JComponent。
编辑:
我尝试使用 Camickr 的第二种解决方案,但没有用。我将 post 代码看是否犯了一个简单的错误。
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 class,反正我也不想这样做。这是我想出的图像 class。
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)
}
}
I want to know how to add an image to a JFrame, JPanel, Container, etc.
您不会将图像添加到 JFrame、JPanel 等。正如您所说,图像不是组件。您将图像添加到 JLabel 并将标签添加到面板。这是以实际大小显示图像的最简单、更直接的方法。
不知道 Kotlin 是否有任何不同,但另一种选择是通过覆盖 paintComponent(…)
方法并使用 Graphics.drawImage(…)
方法,然后将面板添加到框架中。阅读 Custom Painting 上的 Swing 教程,了解绘画基础知识。
您还可以查看 Background Panel 将图像绘制为面板背景的示例。图片可以是:
- 按实际尺寸绘制
- 缩放以填充面板
- 平铺填充面板 请注意,不应在 paintComponent() 方法中读取图像,因为绘画代码应该是高效的。