@@ -4,28 +4,32 @@ import com.icuxika.bittersweet.control.KButton
4
4
import com.icuxika.bittersweet.demo.AppResource
5
5
import com.icuxika.bittersweet.demo.AppView
6
6
import com.icuxika.bittersweet.demo.annotation.AppFXML
7
- import com.icuxika.bittersweet.demo.api.ProgressFlowState
7
+ import com.icuxika.bittersweet.demo.api.*
8
8
import com.icuxika.bittersweet.demo.system.Theme
9
9
import com.icuxika.bittersweet.demo.util.FileDownloader
10
10
import com.icuxika.bittersweet.dsl.onAction
11
11
import com.icuxika.bittersweet.extension.logger
12
+ import javafx.beans.binding.When
12
13
import javafx.beans.property.SimpleBooleanProperty
13
14
import javafx.beans.property.SimpleDoubleProperty
15
+ import javafx.beans.property.SimpleStringProperty
14
16
import javafx.collections.FXCollections
15
17
import javafx.fxml.FXML
16
18
import javafx.fxml.Initializable
17
19
import javafx.geometry.Pos
18
20
import javafx.scene.control.*
19
21
import javafx.scene.layout.BorderPane
22
+ import javafx.scene.layout.HBox
20
23
import javafx.scene.layout.StackPane
21
24
import javafx.scene.layout.VBox
22
25
import javafx.scene.paint.Color
26
+ import javafx.scene.text.Text
23
27
import javafx.stage.Stage
24
28
import javafx.util.Callback
25
- import kotlinx.coroutines.CoroutineScope
26
- import kotlinx.coroutines.Dispatchers
29
+ import kotlinx.coroutines.*
30
+ import kotlinx.coroutines.flow.Flow
27
31
import kotlinx.coroutines.javafx.JavaFx
28
- import kotlinx.coroutines.launch
32
+ import java.io.File
29
33
import java.net.URL
30
34
import java.nio.file.Path
31
35
import java.util.*
@@ -41,9 +45,33 @@ class MainController : Initializable {
41
45
42
46
private val scope = CoroutineScope (Dispatchers .JavaFx )
43
47
48
+ private lateinit var job: Job
49
+ private val downloadUrl = " https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.9_240403_x64_01.exe"
50
+ private val savePath = Path .of(System .getProperty(" user.home" )).resolve(" Downloads" ).resolve(" temp" )
51
+ .resolve(" QQ.exe" )
52
+
44
53
private val progressProperty = SimpleDoubleProperty (ProgressIndicator .INDETERMINATE_PROGRESS )
45
54
private val cButtonBadgeVisibleProperty = SimpleBooleanProperty (true )
46
55
56
+ private suspend fun Flow<ProgressFlowState<Double>>.resolveFlowCollector () {
57
+ collect {
58
+ when (it) {
59
+ is ProgressFlowState .Progress -> {
60
+ progressProperty.set(it.progress)
61
+ }
62
+
63
+ is ProgressFlowState .Success -> {
64
+ LOGGER .info(" 下载完成[${Thread .currentThread().name} ]-->${it.result} " )
65
+ LOGGER .info(" 文件保存路径->$savePath " )
66
+ }
67
+
68
+ is ProgressFlowState .Error -> {
69
+ LOGGER .info(" 下载失败[${Thread .currentThread().name} ]-->${it.throwable.message} " )
70
+ }
71
+ }
72
+ }
73
+ }
74
+
47
75
override fun initialize (location : URL ? , resources : ResourceBundle ? ) {
48
76
container.sceneProperty().addListener { _, oldScene, newScene ->
49
77
if (oldScene == null && newScene != null ) {
@@ -59,33 +87,79 @@ class MainController : Initializable {
59
87
ProgressBar ().apply {
60
88
progressProperty().bind(progressProperty)
61
89
},
62
- Button (" 下载" ).apply {
63
- styleClass.add(" test-button" )
64
- onAction {
65
- scope.launch {
66
- val fileURL =
67
- " https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.9_240403_x64_01.exe"
68
- val filePath =
69
- Path .of(System .getProperty(" user.home" )).resolve(" Downloads" ).resolve(" temp" )
70
- .resolve(" result1.exe" );
71
- FileDownloader .downloadFile(fileURL, filePath).collect {
72
- when (it) {
73
- is ProgressFlowState .Progress -> {
74
- progressProperty.set(it.progress)
75
- }
90
+ HBox (
91
+ Button (" 下载1" ).apply {
92
+ styleClass.add(" test-button" )
93
+ onAction {
94
+ job = scope.launch {
95
+ FileDownloader .downloadFile(downloadUrl, savePath).resolveFlowCollector()
96
+ }
97
+ }
98
+ },
99
+ Button (" 下载2" ).apply {
100
+ styleClass.add(" test-button" )
101
+ onAction {
102
+ job = scope.launch {
103
+ suspendGetFileFlow(downloadUrl, savePath).resolveFlowCollector()
104
+ }
105
+ }
106
+ },
107
+ Button (" 取消" ).apply {
108
+ styleClass.add(" test-button" )
109
+ onAction {
110
+ scope.launch {
111
+ job.cancelAndJoin()
112
+ progressProperty.set(ProgressIndicator .INDETERMINATE_PROGRESS )
113
+ savePath.toFile().delete()
114
+ }
115
+ }
116
+ },
117
+ ).apply {
118
+ alignment = Pos .CENTER
119
+ spacing = 12.0
120
+ },
121
+ Text ().apply {
122
+ textProperty().bind(
123
+ SimpleStringProperty (" 进度: " ).concat(
124
+ When (
125
+ progressProperty.isEqualTo(
126
+ SimpleDoubleProperty (ProgressIndicator .INDETERMINATE_PROGRESS )
127
+ )
128
+ ).then(SimpleStringProperty (" 0" ))
129
+ .otherwise(progressProperty.multiply(100 ).asString(" %.2f" ))
130
+ ).concat(" %" )
131
+ )
132
+ },
133
+ HBox (
134
+ Button (" 上传" ).apply {
135
+ onAction {
136
+ job = scope.launch {
137
+ suspendPostFileFlow<ApiData <Unit >>(
138
+ " http://127.0.0.1:8080/users/upload" , mapOf (
139
+ Api .REQUEST_KEY_FILE to File (" C:\\ Users\\ icuxika\\ Downloads\\ openjdk-14.0.2_windows-x64_bin.zip" ),
140
+ " id" to " 11" ,
141
+ )
142
+ ).collect {
143
+ when (it) {
144
+ is ProgressFlowState .Progress -> {
145
+ progressProperty.set(it.progress)
146
+ }
76
147
77
- is ProgressFlowState .Success -> {
78
- LOGGER .info(" 下载完成[${Thread .currentThread().name} ]-->${it.result} " )
79
- LOGGER .info(" 文件保存路径->$filePath " )
80
- }
148
+ is ProgressFlowState .Error -> {
149
+ LOGGER .info(" 上传失败[${Thread .currentThread().name} ]-->${it.throwable.message} " )
150
+ }
81
151
82
- is ProgressFlowState .Error -> {
83
- LOGGER .info(" 下载失败[${Thread .currentThread().name} ]-->${it.throwable.message} " )
152
+ is ProgressFlowState .Success -> {
153
+ println (it.result)
154
+ }
84
155
}
85
156
}
86
157
}
87
158
}
88
- }
159
+ },
160
+ ).apply {
161
+ alignment = Pos .CENTER
162
+ spacing = 12.0
89
163
},
90
164
ComboBox (FXCollections .observableArrayList(Theme .entries)).apply {
91
165
valueProperty().bindBidirectional(AppResource .themeProperty())
0 commit comments