Skip to content

Commit c874bdf

Browse files
authored
Fix SwingPanel size not scaling according to LocalDensity (#3033)
1 parent 4e4c5c0 commit c874bdf

2 files changed

Lines changed: 54 additions & 3 deletions

File tree

compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/viewinterop/SwingInteropViewHolder.desktop.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import androidx.compose.ui.layout.findRootCoordinates
3333
import androidx.compose.ui.unit.Density
3434
import androidx.compose.ui.unit.IntRect
3535
import androidx.compose.ui.util.fastForEach
36+
import androidx.compose.ui.window.density
3637
import java.awt.Component
3738
import java.awt.event.FocusEvent
3839
import java.awt.event.FocusListener
@@ -89,13 +90,13 @@ internal class SwingInteropViewHolder<T : Component>(
8990
override fun layoutAccordingTo(layoutCoordinates: LayoutCoordinates) {
9091
val rootCoordinates = layoutCoordinates.findRootCoordinates()
9192

93+
val awtToComposeScale = container.root.density
9294
val clippedBounds = rootCoordinates
9395
.localBoundingBoxOf(layoutCoordinates, clipBounds = true)
94-
.round(density)
95-
96+
.round(awtToComposeScale)
9697
val bounds = rootCoordinates
9798
.localBoundingBoxOf(layoutCoordinates, clipBounds = false)
98-
.round(density)
99+
.round(awtToComposeScale)
99100

100101
clipBounds = clippedBounds // Clipping area for skia canvas
101102

compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/SwingPanelTest.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ import androidx.compose.foundation.layout.height
2424
import androidx.compose.foundation.layout.offset
2525
import androidx.compose.foundation.layout.size
2626
import androidx.compose.foundation.verticalScroll
27+
import androidx.compose.runtime.CompositionLocalProvider
28+
import androidx.compose.runtime.getValue
29+
import androidx.compose.runtime.mutableFloatStateOf
30+
import androidx.compose.runtime.setValue
31+
import androidx.compose.ui.Alignment
2732
import androidx.compose.ui.Modifier
2833
import androidx.compose.ui.layout.LayoutBoundsHolder
2934
import androidx.compose.ui.layout.layoutBounds
@@ -37,13 +42,16 @@ import androidx.compose.ui.unit.DpSize
3742
import androidx.compose.ui.unit.dp
3843
import androidx.compose.ui.window.Window
3944
import androidx.compose.ui.window.WindowState
45+
import androidx.compose.ui.window.roundToDimension
4046
import androidx.compose.ui.window.runApplicationTest
4147
import java.awt.BorderLayout
4248
import java.awt.Dimension
49+
import java.awt.Graphics
4350
import java.awt.Point
4451
import java.awt.event.MouseAdapter
4552
import java.awt.event.MouseEvent
4653
import java.awt.event.MouseWheelEvent
54+
import javax.swing.JComponent
4755
import javax.swing.JLabel
4856
import javax.swing.JPanel
4957
import javax.swing.SwingUtilities
@@ -208,4 +216,46 @@ class SwingPanelTest {
208216
awaitIdle()
209217
assertTrue(scrollState.value > 0, "Compose did not scroll; SwingPanel blocked the event")
210218
}
219+
220+
@Test
221+
fun swingPanelRespondsToDensityChange() = runApplicationTest {
222+
val swingComponent = object: JComponent() {
223+
override fun paint(g: Graphics) {
224+
g.color = java.awt.Color.RED
225+
g.fillRect(0, 0, width, height)
226+
}
227+
}
228+
val swingElementSize = DpSize(200.dp, 200.dp)
229+
230+
var densityScale by mutableFloatStateOf(1f)
231+
launchTestWindowApplication(
232+
state = WindowState(size = DpSize(500.dp, 500.dp))
233+
) {
234+
Box(
235+
modifier = Modifier.fillMaxSize(),
236+
contentAlignment = Alignment.Center
237+
) {
238+
val density = LocalDensity.current.density
239+
CompositionLocalProvider(LocalDensity provides Density(densityScale * density)) {
240+
SwingPanel(
241+
modifier = Modifier.size(swingElementSize),
242+
factory = { swingComponent }
243+
)
244+
}
245+
}
246+
}
247+
248+
awaitIdle()
249+
assertEquals(
250+
expected = swingElementSize.roundToDimension(),
251+
actual = swingComponent.size
252+
)
253+
254+
densityScale = 2f
255+
awaitIdle()
256+
assertEquals(
257+
expected = (swingElementSize * densityScale).roundToDimension(),
258+
actual = swingComponent.size
259+
)
260+
}
211261
}

0 commit comments

Comments
 (0)