Swing에서 Jetpack Compose 데스크탑까지 #2
아이디어는 유효한 경로를 입력한 다음 찾기를 클릭하는 것입니다. 분명히 해당 조건이 충족되는 경우에만 버튼이 활성화되어야 합니다. 컴포저블
FirstRow
은 현재 한 가지 상태를 기억합니다.val name = remember { mutableStateOf(TextFieldValue("")) }
따라서 다음과 같이 버튼 코드를 쉽게 추가할 수 있습니다.
Button(
onClick = {},
modifier = Modifier.alignByBaseline(),
enabled = File(name.value.text).isDirectory
) {
Text("Find")
}
텍스트 필드는 기본 클립보드에서 작동하므로 경로가 문자열인 경우 Ctrl-V 또는 Cmd-V로 붙여넣을 수 있습니다. 그러나 그것은 특히 데스크탑 파이가 아닙니다. 데스크탑 운영 체제의 주요 기능은 다중 창을 지원하는 것입니다. 따라서 기본 파일 관리자에서 폴더를 선택하고 싶을 것입니다. 맞습니까?
저는 데스크톱용 Jetpack Compose 초보자이며 이것을 놓쳤을 수도 있지만 지금까지 드래그 앤 드롭 지원을 보지 못했습니다. 그래서 스스로 이 일을 하기로 했습니다. 데스크톱용 Jetpack Compose 최상위 창은 Swing과 쉽게 상호작용할 수 있으므로 여기에서 드래그 앤 드롭 기능을 빌릴 수 있습니다. 이것이 일반적으로 어떻게 작동하는지 봅시다:
val target = object : DropTarget() {
@Synchronized
override fun drop(evt: DropTargetDropEvent) {
try {
evt.acceptDrop(DnDConstants.ACTION_REFERENCE)
val droppedFiles = evt
.transferable.getTransferData(
DataFlavor.javaFileListFlavor) as List<*>
for (file in droppedFiles) {
println((file as File).absolutePath)
}
} catch (ex: Exception) {
ex.printStackTrace()
}
}
}
AppManager.windows.first().window.contentPane.dropTarget = target
DropTarget
는 Swing 항목이므로 자세히 설명하지 않겠습니다. 하지만 이 코드는 드롭된 파일의 이름만 출력한다는 점을 명심하십시오. 텍스트 필드를 업데이트하려면 for
루프를 변경해야 합니다. 곧 이에 대해 자세히 알아보십시오. 하지만 먼저 마지막 줄을 살펴보겠습니다(말장난 의도 없음). AppManager.windows
는 응용 프로그램의 모든 창 목록을 제공합니다. TKDupeFinder에는 기본 창 하나만 있습니다. 그래서 우리는 이것을 first()
로 얻을 수 있습니다. 이것은 androidx.compose.desktop.AppFrame
의 인스턴스입니다. window
는 ComposeWindow
를 확장하는 JFrame
입니다. 이것이 우리가 contentPane
에 액세스하고 놓기 대상을 설정할 수 있는 이유입니다.멋지죠? 이 세션을 마치기 위해 텍스트 필드를 업데이트하는 방법은 다음과 같습니다. 먼저 약간 변경된
main()
기능:fun main() {
invokeLater {
AppWindow(title = "TKDupeFinder",
size = IntSize(600, 400)).show {
TKDupeFinderContent()
}
}
}
TKDupeFinderContent
는 컴포저블입니다. 보시다시피 name
를 기억하고 FirstRow
로 전달합니다(이것도 새로운 것임). 드래그 시 업데이트name
가 필요하기 때문에 이렇게 합니다.@Composable
fun TKDupeFinderContent() {
val name = remember { mutableStateOf(TextFieldValue("")) }
DesktopMaterialTheme {
Column() {
FirstRow(name)
SecondRow()
ThirdRow()
}
}
val target = object : DropTarget() {
@Synchronized
override fun drop(evt: DropTargetDropEvent) {
try {
evt.acceptDrop(DnDConstants.ACTION_REFERENCE)
val droppedFiles = evt
.transferable.getTransferData(
DataFlavor.javaFileListFlavor) as List<*>
droppedFiles.first()?.let {
name.value = TextFieldValue((it as File).absolutePath)
}
} catch (ex: Exception) {
ex.printStackTrace()
}
}
}
AppManager.windows.first().window.contentPane.dropTarget = target
}
내 코드는 하나의 파일 또는 폴더만 창으로 끌어온 것으로 가정합니다. 더 있으면 첫 번째 항목(
droppedFiles.first()
)을 사용합니다. 경로( absolutePath
)는 TextFieldValue
로 래핑되어야 합니다. 다음 클립은 이것이 macOS에서 어떻게 보이는지 보여줍니다.꽤 멋지죠? 다음 포스트는 중복에 대한 실제 검색을 다룰 것입니다. 계속 지켜봐주십시오. 첫 번째 부분을 놓친 경우 읽을 수 있습니다. TKDupeFinder 저장소가 켜져 있습니다GitHub.
Reference
이 문제에 관하여(Swing에서 Jetpack Compose 데스크탑까지 #2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tkuenneth/from-swing-to-jetpack-compose-desktop-2-4a4h텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)