greatly reduce flickering

This commit is contained in:
downthecrop 2024-10-26 09:06:23 -07:00
parent 15deb6216f
commit 71afb2b385
4 changed files with 131 additions and 80 deletions

View file

@ -7,9 +7,7 @@ import KondoKit.Helpers.formatHtmlLabelText
import KondoKit.Helpers.getSpriteId
import KondoKit.Helpers.showToast
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
import KondoKit.plugin.Companion.POPUP_BACKGROUND
import KondoKit.plugin.Companion.POPUP_FOREGROUND
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
import KondoKit.plugin.Companion.WIDGET_COLOR
@ -112,7 +110,9 @@ object HiscoresView {
} else {
text += e.keyChar
}
repaint()
SwingUtilities.invokeLater {
repaint()
}
}
override fun keyPressed(e: KeyEvent) {
if (e.isControlDown) {
@ -125,7 +125,9 @@ object HiscoresView {
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
val pasteText = clipboard.getData(DataFlavor.stringFlavor) as String
text += pasteText
repaint()
SwingUtilities.invokeLater {
repaint()
}
}
}
}
@ -136,7 +138,9 @@ object HiscoresView {
override fun mouseClicked(e: MouseEvent) {
if (e.x > width - 20 && e.y < 20) {
text = ""
repaint()
SwingUtilities.invokeLater {
repaint()
}
}
}
})
@ -144,7 +148,9 @@ object HiscoresView {
Timer(500) {
cursorVisible = !cursorVisible
if(focusedView == VIEW_NAME)
repaint()
SwingUtilities.invokeLater {
repaint()
}
}.start()
}

View file

@ -9,6 +9,7 @@ import java.awt.Rectangle
import java.awt.event.*
import java.util.*
import javax.swing.JPanel
import javax.swing.SwingUtilities
class ScrollablePanel(private val content: JPanel) : JPanel() {
private var lastMouseY = 0
@ -80,20 +81,22 @@ class ScrollablePanel(private val content: JPanel) : JPanel() {
}
private fun handleResize() {
// Ensure the ScrollablePanel resizes with the frame
bounds = Rectangle(0, 0, 242, frame.height)
SwingUtilities.invokeLater{
// Ensure the ScrollablePanel resizes with the frame
bounds = Rectangle(0, 0, 242, frame.height)
// Dynamically update content bounds and scrollbar on frame resize with buffer
content.bounds = Rectangle(0, 0, 242, content.preferredSize.height.coerceAtLeast(frame.height + viewBuffer))
showScrollbar = content.height > frame.height
// Dynamically update content bounds and scrollbar on frame resize with buffer
content.bounds = Rectangle(0, 0, 242, content.preferredSize.height.coerceAtLeast(frame.height + viewBuffer))
showScrollbar = content.height > frame.height
currentOffsetY = 0
currentOffsetY = 0
content.setLocation(0, currentOffsetY)
updateScrollbar()
content.setLocation(0, currentOffsetY)
updateScrollbar()
revalidate()
repaint()
revalidate()
repaint()
}
}
private fun scrollContent(deltaY: Int) {
@ -102,40 +105,41 @@ class ScrollablePanel(private val content: JPanel) : JPanel() {
content.setLocation(0, currentOffsetY)
return
}
SwingUtilities.invokeLater {
currentOffsetY += deltaY
currentOffsetY += deltaY
// Apply buffer to maxOffset
val maxOffset = (frame.height - content.height + viewBuffer).coerceAtMost(0)
currentOffsetY = currentOffsetY.coerceAtMost(0).coerceAtLeast(maxOffset)
// Apply buffer to maxOffset
val maxOffset = (frame.height - content.height + viewBuffer).coerceAtMost(0)
currentOffsetY = currentOffsetY.coerceAtMost(0).coerceAtLeast(maxOffset)
content.setLocation(0, currentOffsetY)
content.setLocation(0, currentOffsetY)
val contentHeight = content.height
val viewHeight = frame.height + viewBuffer
val scrollableRatio = viewHeight.toDouble() / contentHeight
scrollbarY = ((-currentOffsetY / contentHeight.toDouble()) * viewHeight).toInt()
scrollbarHeight = (viewHeight * scrollableRatio).toInt().coerceAtLeast(20)
repaint()
}
private fun updateScrollbar() {
showScrollbar = content.height > frame.height
val contentHeight = content.height
val viewHeight = frame.height + viewBuffer
if (showScrollbar) {
val contentHeight = content.height
val viewHeight = frame.height + viewBuffer
val scrollableRatio = viewHeight.toDouble() / contentHeight
scrollbarY = ((-currentOffsetY / contentHeight.toDouble()) * viewHeight).toInt()
scrollbarHeight = (viewHeight * scrollableRatio).toInt().coerceAtLeast(20)
} else {
scrollbarY = 0
scrollbarHeight = 0
repaint()
}
}
repaint()
private fun updateScrollbar() {
SwingUtilities.invokeLater {
showScrollbar = content.height > frame.height
val contentHeight = content.height
val viewHeight = frame.height + viewBuffer
if (showScrollbar) {
val scrollableRatio = viewHeight.toDouble() / contentHeight
scrollbarY = ((-currentOffsetY / contentHeight.toDouble()) * viewHeight).toInt()
scrollbarHeight = (viewHeight * scrollableRatio).toInt().coerceAtLeast(20)
} else {
scrollbarY = 0
scrollbarHeight = 0
}
repaint()
}
}
override fun paintComponent(g: Graphics) {

View file

@ -147,7 +147,8 @@ class plugin : Plugin() {
}
lastLogin = Player.usernameInput.toString()
}
class AltCanvas() : JPanel() {
class AltCanvas : Canvas() {
private var gameImage: VolatileImage? = null
private var scaleX = 1.0
private var scaleY = 1.0
@ -207,15 +208,19 @@ class plugin : Plugin() {
requestFocusInWindow()
}
override fun update(g: Graphics) {
paint(g)
}
private fun validateGameImage() {
val gc = GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice.defaultConfiguration
if (gameImage == null) {
gameImage = gc.createCompatibleVolatileImage(765, 503, Transparency.TRANSLUCENT)
gameImage = gc.createCompatibleVolatileImage(765, 503, Transparency.OPAQUE)
renderGameImage()
} else {
val status = gameImage!!.validate(gc)
if (status == VolatileImage.IMAGE_INCOMPATIBLE) {
gameImage = gc.createCompatibleVolatileImage(765, 503, Transparency.TRANSLUCENT)
gameImage = gc.createCompatibleVolatileImage(765, 503, Transparency.OPAQUE)
renderGameImage()
} else if (status == VolatileImage.IMAGE_RESTORED) {
renderGameImage()
@ -237,20 +242,35 @@ class plugin : Plugin() {
}
}
override fun paintComponent(g: Graphics) {
super.paintComponent(g)
override fun paint(g: Graphics) {
val g2d = g as Graphics2D
// Set the desired background fill color here
g2d.color = Color.BLACK
g2d.fillRect(0, 0, width, height)
validateGameImage()
// Validate image within paint to ensure compatibility with GraphicsConfiguration
var valid = false
do {
val gc = GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice.defaultConfiguration
if (gameImage == null) {
gameImage = gc.createCompatibleVolatileImage(765, 503, Transparency.OPAQUE)
renderGameImage()
} else {
val status = gameImage!!.validate(gc)
when (status) {
VolatileImage.IMAGE_INCOMPATIBLE -> {
gameImage = gc.createCompatibleVolatileImage(765, 503, Transparency.OPAQUE)
renderGameImage()
}
VolatileImage.IMAGE_RESTORED -> renderGameImage()
VolatileImage.IMAGE_OK -> valid = true
}
}
} while (!valid)
// Continue with rendering the image
gameImage?.let { image ->
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR)
// Calculate aspect-ratio-preserving scale
// Scaling and centering
val imageAspect = image.width.toDouble() / image.height.toDouble()
val panelAspect = width.toDouble() / height.toDouble()
@ -289,7 +309,6 @@ class plugin : Plugin() {
canvas, e.id, e.`when`, e.modifiersEx,
originalX, originalY, e.clickCount, e.isPopupTrigger, e.button
)
canvas.dispatchEvent(newEvent)
}
@ -383,8 +402,11 @@ class plugin : Plugin() {
}
}
rightPanelWrapper?.preferredSize = Dimension(currentScrollPaneWidth, frame.height)
rightPanelWrapper?.let { it.isDoubleBuffered = true }
rightPanelWrapper?.revalidate()
rightPanelWrapper?.repaint()
SwingUtilities.invokeLater {
rightPanelWrapper?.repaint()
}
}
fun OnKondoValueUpdated(){
@ -446,9 +468,7 @@ class plugin : Plugin() {
frame.remove(rightPanelWrapper)
frame.layout = BorderLayout()
frame.add(rightPanelWrapper, BorderLayout.EAST)
frame.revalidate()
frame.repaint()
pluginsReloaded = true
reloadInterfaces = true
return true
@ -476,7 +496,9 @@ class plugin : Plugin() {
xpTrackerView?.revalidate()
if(focusedView == XPTrackerView.VIEW_NAME)
xpTrackerView?.repaint()
SwingUtilities.invokeLater {
xpTrackerView?.repaint()
}
updateWidget(xpWidget, xp)
}
@ -522,22 +544,35 @@ class plugin : Plugin() {
}
override fun LateDraw(timeDelta: Long){
// Clear original canvas for scaled
if(!initialized) return
SwingUtilities.invokeLater {
var p = Point(-1000,-1000)
if (GetWindowMode() == WindowMode.FIXED) {
if (canvas.location != p) {
println("Moving canvas offscreen");
canvas.location = p;
if (canvas.parent !== hiddenFrame?.contentPane) {
println("Moving canvas to hidden frame")
initializeHiddenFrame()
frame.remove(canvas) // Remove from main frame if necessary
hiddenFrame?.contentPane?.add(canvas)
hiddenFrame?.pack()
}
} else {
}
}
altCanvas?.updateGameImage()
altCanvas?.updateGameImage() // Update the game image as needed
}
private var hiddenFrame: JFrame? = null
fun initializeHiddenFrame() {
if (hiddenFrame == null) {
hiddenFrame = JFrame().apply {
isUndecorated = true
isVisible = false // Keep it hidden
setSize(1, 1) // Minimal size
defaultCloseOperation = JFrame.DO_NOTHING_ON_CLOSE
}
}
}
private fun initKondoUI(){
DrawText(FontType.LARGE, fromColor(Color(16777215)), TextModifier.CENTER, "KondoKit Loading Sprites...", GameShell.canvasWidth/2, GameShell.canvasHeight/2)
if(!allSpritesLoaded()) return;
@ -683,7 +718,9 @@ class plugin : Plugin() {
val formattedXpPerHour = formatNumber(xpPerHour)
xpWidget.xpPerHourLabel.text =
formatHtmlLabelText("XP /hr: ", primaryColor, formattedXpPerHour, secondaryColor)
xpWidget.container.repaint()
SwingUtilities.invokeLater{
xpWidget.container.repaint()
}
}
totalXP?.let { totalXPWidget ->
@ -692,7 +729,9 @@ class plugin : Plugin() {
val formattedTotalXpPerHour = formatNumber(totalXPPerHour)
totalXPWidget.xpPerHourLabel.text =
formatHtmlLabelText("XP /hr: ", primaryColor, formattedTotalXpPerHour, secondaryColor)
totalXPWidget.container.repaint()
SwingUtilities.invokeLater{
totalXPWidget.container.repaint()
}
}
}
@ -717,11 +756,14 @@ class plugin : Plugin() {
// Revalidate and repaint necessary panels
mainContentPanel.revalidate()
mainContentPanel.repaint()
rightPanelWrapper?.revalidate()
rightPanelWrapper?.repaint()
frame?.revalidate()
frame?.repaint()
SwingUtilities.invokeLater{
mainContentPanel.repaint()
rightPanelWrapper?.repaint()
frame?.repaint()
}
focusedView = viewName
}
@ -784,15 +826,20 @@ class plugin : Plugin() {
override fun mouseEntered(e: MouseEvent?) {
background = WIDGET_COLOR.darker()
imageCanvas.fillColor = WIDGET_COLOR.darker()
imageCanvas.repaint()
repaint()
SwingUtilities.invokeLater{
imageCanvas.repaint()
repaint()
}
}
override fun mouseExited(e: MouseEvent?) {
background = WIDGET_COLOR
imageCanvas.fillColor = WIDGET_COLOR
imageCanvas.repaint()
repaint()
SwingUtilities.invokeLater{
imageCanvas.repaint()
repaint()
}
}
override fun mouseClicked(e: MouseEvent?) {