我现在已经花了几个小时,但没有取得任何进展。
我有一个非常简单的应用程序,它从磁盘加载一个大的(2000x2500px)图像。
它加载到一个JPanel,它由JScrollPanel包含,而JScrollPanel又包含在最外层的JPanel中。
此代码在Scala中,但对于Java开发人员来说应该很容易阅读。
当我移动滚动条时,应用程序会打印出正在重新绘制的指示,但图像会部分留空。当我调整应用程序窗格的大小时,一切都正确绘制。
这是一个错误还是我错过了一些非常基本的东西?
import java.awt._
import java.util.Date
import javax.imageio.ImageIO
import javax.swing._
object DisplayAnImage {
def main(args: Array[String]) = {
val rackStream = DisplayAnImage.getClass.getResourceAsStream("racks.jpg")
val bi = ImageIO.read(rackStream)
val outerMost = new JFrame("Image display")
outerMost.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
outerMost.setLayout(new BorderLayout())
val imagePane = new JPanel(true) {
val c = new Canvas() {
override def paint(g: Graphics): Unit = {
println(s"drawing the image ${new Date()}")
g.drawImage(bi, 0, 0, null)
}
}
c.setSize(bi.getWidth, bi.getHeight)
this.add(c)
}
val scroller = new JScrollPane(imagePane)
scroller.setAutoscrolls(true)
outerMost.add(scroller, BorderLayout.CENTER)
outerMost.pack()
outerMost.setSize(300, 300)
outerMost.setVisible(true)
}
}
感谢camackr - 我将代码修改为以下代码,它更简单,效果更好。
import java.awt._
import javax.imageio.ImageIO
import javax.swing._
object DisplayAnImage {
def main(args: Array[String]) = {
val rackStream = DisplayAnImage.getClass.getResourceAsStream("racks.jpg")
val bi = ImageIO.read(rackStream)
val outerMost = new JFrame("Image display")
outerMost.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
outerMost.setLayout(new BorderLayout())
val imagePane = new JPanel(true) {
val jl = new JLabel() {
override def paintComponent(g: Graphics): Unit = {
g.drawImage(bi, 0, 0, null)
}
this.setPreferredSize(new Dimension(bi.getWidth,bi.getHeight))
}
this.add(jl)
}
val scroller = new JScrollPane(imagePane)
scroller.setAutoscrolls(true)
outerMost.add(scroller, BorderLayout.CENTER)
outerMost.pack()
outerMost.setSize(300, 300)
outerMost.setVisible(true)
}
}
答案 0 :(得分:2)
滚动窗格的工作原理基于添加到滚动窗格的组件的首选大小。您正在进行自定义绘制,但未为组件提供首选大小。
你为什么要做自定义绘画?你为什么要使用Canvas?为什么要覆盖paint(),自定义绘制是通过在使用Swing时覆盖paintComponent()来完成的。
无论如何,只需使用JLabel显示图像并将标签添加到滚动窗格。标签将根据图像的大小自动确定其自身的首选大小。