Skip to content

Commit f594b6c

Browse files
authored
Merge pull request #155 from Dokyeongyun/ft-220213-enhanceUsageUI
Ft 220213 enhance usage UI
2 parents 7c1a08b + 018e589 commit f594b6c

20 files changed

+419
-44
lines changed

config/common.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ unit.filesize=GB
1616

1717
unit.rounding=2
1818

19+
usage-ui-type = 2
20+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package root.core.domain.enums;
2+
3+
import java.util.List;
4+
5+
public interface EnumType {
6+
7+
String getName();
8+
9+
List<String> getNames();
10+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package root.core.domain.enums;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public enum UsageStatus {
7+
NORMAL("cornflowerblue"), DANGEROUS("#ff4141");
8+
9+
private String color;
10+
11+
UsageStatus(String color) {
12+
this.color = color;
13+
}
14+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package root.core.domain.enums;
2+
3+
import java.util.Arrays;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.Optional;
8+
import java.util.function.Function;
9+
import java.util.stream.Collectors;
10+
import java.util.stream.Stream;
11+
12+
import lombok.Getter;
13+
14+
@Getter
15+
public enum UsageUIType implements EnumType {
16+
17+
NUMERIC("1", "수치 값"), GRAPHIC_BAR("2", "막대형 그래픽"), GRAPHIC_PIE("3", "원형 그래픽");
18+
19+
private String code;
20+
private String name;
21+
22+
private UsageUIType(String code, String name) {
23+
this.code = code;
24+
this.name = name;
25+
}
26+
27+
private static final Map<String, UsageUIType> UsageUITypeMap = Collections
28+
.unmodifiableMap(Stream.of(values()).collect(Collectors.toMap(UsageUIType::getCode, Function.identity())));
29+
30+
public static UsageUIType find(String code) {
31+
return Optional.ofNullable(UsageUITypeMap.get(code)).orElse(NUMERIC);
32+
}
33+
34+
@Override
35+
public String getName() {
36+
return name;
37+
}
38+
39+
@Override
40+
public List<String> getNames() {
41+
return Arrays.asList(values()).stream().map(ui -> ui.getName()).collect(Collectors.toList());
42+
}
43+
}

src/main/java/root/javafx/Controller/RunMenuController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,9 @@ private <T extends MonitoringResult> void initAndAddMonitoringAnchorPane(Monitor
201201
monitoringAP.setAnchor(0, 0, 0, 0); // Anchor Constraint 설정
202202
monitoringAP.setAliasComboBoxLabelText(labelText); // ComboBox 좌측 Lebel Text 설정
203203
monitoringAP.setAliasComboBoxItems(comboBoxItems); // ComboBox Items 설정
204-
for(String key : tableColumns.keySet()) { // TableView에 출력할 Column 설정
205-
monitoringAP.addAndSetPropertyTableColumn(tableColumns.get(key), key);
204+
for (String key : tableColumns.keySet()) { // TableView에 출력할 Column 설정
205+
monitoringAP.addAndSetPropertyTableColumn(tableColumns.get(key).getClazz(),
206+
tableColumns.get(key).getFieldName(), key);
206207
}
207208
parentAP.getChildren().add(monitoringAP); // Monitoring AnchorPane을 부모 Node에 추가
208209
}

src/main/java/root/javafx/Controller/SettingMenuController.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@
4141
import javafx.stage.FileChooser;
4242
import javafx.stage.FileChooser.ExtensionFilter;
4343
import javafx.stage.Stage;
44+
import javafx.util.StringConverter;
4445
import root.core.domain.AlertLogCommand;
4546
import root.core.domain.JdbcConnectionInfo;
4647
import root.core.domain.JschConnectionInfo;
48+
import root.core.domain.enums.UsageUIType;
4749
import root.core.repository.constracts.PropertyRepository;
4850
import root.core.repository.implement.PropertyRepositoryImpl;
4951
import root.javafx.CustomView.ConnectionInfoVBox;
@@ -89,9 +91,12 @@ public class SettingMenuController implements Initializable {
8991

9092
@FXML
9193
JFXComboBox<FileSize> fileSizeCB;
92-
94+
9395
@FXML
9496
JFXComboBox<Integer> roundingDigitsCB;
97+
98+
@FXML
99+
JFXComboBox<UsageUIType> usageUICB;
95100

96101
/* Common Data */
97102
String[] dbMonitorings;
@@ -144,6 +149,27 @@ public void initialize(URL location, ResourceBundle resources) {
144149
map.put("unit.rounding", newValue);
145150
propertyRepository.saveCommonConfig(map);
146151
});
152+
153+
// Set usage UI type comboBox items and Set setting value;
154+
String usageUICode = propertyRepository.getCommonResource("usage-ui-type");
155+
usageUICB.setConverter(new StringConverter<UsageUIType>() {
156+
@Override
157+
public String toString(UsageUIType uiType) {
158+
return uiType.getName();
159+
}
160+
161+
@Override
162+
public UsageUIType fromString(String string) {
163+
return usageUICB.getItems().stream().filter(ui -> ui.getName().equals(string)).findFirst().orElse(null);
164+
}
165+
});
166+
this.usageUICB.getItems().addAll(UsageUIType.values());
167+
this.usageUICB.getSelectionModel().select(UsageUIType.find(usageUICode));
168+
usageUICB.getSelectionModel().selectedItemProperty().addListener((options, oldValue, newValue) -> {
169+
Map<String, Object> map = new HashMap<>();
170+
map.put("usage-ui-type", newValue.getCode());
171+
propertyRepository.saveCommonConfig(map);
172+
});
147173
}
148174

149175
/**

src/main/java/root/javafx/CustomView/MonitoringAnchorPane.java

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,28 @@
1212

1313
import com.jfoenix.controls.JFXComboBox;
1414

15+
import javafx.beans.binding.Bindings;
16+
import javafx.collections.FXCollections;
1517
import javafx.event.ActionEvent;
1618
import javafx.fxml.FXML;
1719
import javafx.fxml.FXMLLoader;
20+
import javafx.scene.Node;
1821
import javafx.scene.control.Alert.AlertType;
1922
import javafx.scene.control.DatePicker;
2023
import javafx.scene.control.Label;
24+
import javafx.scene.control.TableCell;
2125
import javafx.scene.control.TableColumn;
2226
import javafx.scene.control.TableView;
2327
import javafx.scene.control.cell.PropertyValueFactory;
2428
import javafx.scene.layout.AnchorPane;
25-
import root.core.domain.ArchiveUsage;
2629
import root.core.domain.MonitoringResult;
30+
import root.core.domain.enums.UsageUIType;
2731
import root.core.repository.constracts.PropertyRepository;
2832
import root.core.repository.implement.PropertyRepositoryImpl;
2933
import root.core.repository.implement.ReportFileRepo;
3034
import root.core.usecase.constracts.ReportUsecase;
3135
import root.core.usecase.implement.ReportUsecaseImpl;
32-
import root.javafx.Model.TypeAndFieldName;
36+
import root.javafx.CustomView.UsageUI.UsageUIFactory;
3337
import root.utils.AlertUtils;
3438
import root.utils.UnitUtils.FileSize;
3539

@@ -141,8 +145,8 @@ public void syncTableData(String id) {
141145
if (tableDataMap.get(id) == null) {
142146
return;
143147
}
144-
monitoringResultTV.getItems().clear();
145-
monitoringResultTV.getItems().setAll(tableDataMap.get(id));
148+
monitoringResultTV.setItems(null);
149+
monitoringResultTV.setItems(FXCollections.observableList(tableDataMap.get(id)));
146150
aliasComboBox.getSelectionModel().select(id);
147151
}
148152

@@ -157,50 +161,35 @@ public <E> void addTableColumn(E type, String tcHeaderText) {
157161
monitoringResultTV.getColumns().add(new TableColumn<T, E>(tcHeaderText));
158162
}
159163

160-
/**
161-
* TableView의 TableColumn에 Property를 설정한다.
162-
*
163-
* @param <E>
164-
* @param index
165-
* @param t
166-
*/
167-
@SuppressWarnings("unchecked")
168-
public <E> void setTableColumnProperty(int index, TypeAndFieldName t) {
169-
TableColumn<T, E> tc = (TableColumn<T, E>) this.monitoringResultTV.getColumns().get(index);
170-
((TableColumn<ArchiveUsage, E>) tc).setCellValueFactory(new PropertyValueFactory<>(t.getFieldName()));
171-
}
172-
173164
/*
174165
* TableView에 TableColumn을 추가하고 Property를 설정한다.
175166
*
176167
* @param <E>
177168
* @param t
178169
* @param tcHeaderText
179170
*/
180-
public <E> void addAndSetPropertyTableColumn(TypeAndFieldName t, String tcHeaderText) {
181-
TableColumn<T, E> tc = new TableColumn<T, E>(tcHeaderText);
182-
tc.setCellValueFactory(new PropertyValueFactory<>(t.getFieldName()));
183-
monitoringResultTV.getColumns().add(tc);
184-
}
185-
186-
/**
187-
* TableView에 추가된 TableColumn을 얻는다.
188-
*
189-
* @param index
190-
* @return
191-
*/
192171
@SuppressWarnings("unchecked")
193-
public TableColumn<T, ?> getTableColumn(int index) {
194-
TableColumn<T, ?> tc = this.monitoringResultTV.getColumns().get(index);
195-
if (tc.getUserData() instanceof String) {
196-
return (TableColumn<T, String>) tc;
197-
} else if (tc.getUserData() instanceof Integer) {
198-
return (TableColumn<T, Integer>) tc;
199-
} else if (tc.getUserData() instanceof Double) {
200-
return (TableColumn<T, Double>) tc;
172+
public <E> void addAndSetPropertyTableColumn(Class<E> fieldType, String fieldName, String tcHeaderText) {
173+
TableColumn<T, E> tc = new TableColumn<T, E>(tcHeaderText);
174+
tc.setCellValueFactory(new PropertyValueFactory<>(fieldName));
175+
176+
// TODO Usage UI Type별로 구체화되는 TableCellFactory 만들기
177+
UsageUIType usageUIType = UsageUIType.find(propertyRepo.getCommonResource("usage-ui-type"));
178+
if (fieldName.equals("usedPercent")) {
179+
tc.setCellFactory(col -> {
180+
TableCell<T, Double> cell = new TableCell<>();
181+
cell.itemProperty().addListener((observableValue, o, newValue) -> {
182+
if (newValue != null) {
183+
Node usageUI = UsageUIFactory.create(usageUIType, newValue, 90);
184+
cell.graphicProperty()
185+
.bind(Bindings.when(cell.emptyProperty()).then((Node) null).otherwise(usageUI));
186+
}
187+
});
188+
return (TableCell<T, E>) cell;
189+
});
201190
}
202191

203-
return tc;
192+
monitoringResultTV.getColumns().add(tc);
204193
}
205194

206195
/**
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package root.javafx.CustomView.UsageUI;
2+
3+
import java.io.IOException;
4+
5+
import javafx.fxml.FXML;
6+
import javafx.fxml.FXMLLoader;
7+
import javafx.scene.control.Label;
8+
import javafx.scene.control.ProgressBar;
9+
import javafx.scene.layout.AnchorPane;
10+
import root.core.domain.enums.UsageStatus;
11+
12+
public class UsageBarUI extends AnchorPane implements UsageUI {
13+
14+
@FXML
15+
ProgressBar usageUI;
16+
17+
@FXML
18+
Label usageLB;
19+
20+
private double usage;
21+
22+
private double baseline;
23+
24+
public UsageBarUI(double usage, double baseline) {
25+
this.usage = usage;
26+
this.baseline = baseline;
27+
28+
try {
29+
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/usageUI/UsageBarUI.fxml"));
30+
loader.setController(this);
31+
loader.setRoot(this);
32+
loader.load();
33+
} catch (IOException e) {
34+
e.printStackTrace();
35+
}
36+
37+
setUsage();
38+
setUsageText();
39+
setColor();
40+
}
41+
42+
@Override
43+
public void setUsageText() {
44+
usageLB.setText(usage == -1 ? "ERROR" : usage + "%");
45+
}
46+
47+
@Override
48+
public void setUsage() {
49+
usageUI.setProgress(usage == -1 ? ProgressBar.INDETERMINATE_PROGRESS : usage / 100.0);
50+
}
51+
52+
@Override
53+
public void setColor() {
54+
UsageStatus type = usage >= baseline ? UsageStatus.DANGEROUS : UsageStatus.NORMAL;
55+
usageUI.setStyle("-fx-accent2:" + type.getColor());
56+
}
57+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package root.javafx.CustomView.UsageUI;
2+
3+
import java.io.IOException;
4+
5+
import javafx.fxml.FXML;
6+
import javafx.fxml.FXMLLoader;
7+
import javafx.scene.control.Label;
8+
import javafx.scene.control.ProgressIndicator;
9+
import javafx.scene.layout.HBox;
10+
import root.core.domain.enums.UsageStatus;
11+
12+
public class UsageCircleUI extends HBox implements UsageUI {
13+
14+
@FXML
15+
ProgressIndicator usageUI;
16+
17+
@FXML
18+
Label usageLB;
19+
20+
private double usage;
21+
22+
private double baseline;
23+
24+
public UsageCircleUI(double usage, double baseline) {
25+
this.usage = usage;
26+
this.baseline = baseline;
27+
28+
try {
29+
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/usageUI/UsageCircleUI.fxml"));
30+
loader.setController(this);
31+
loader.setRoot(this);
32+
loader.load();
33+
} catch (IOException e) {
34+
e.printStackTrace();
35+
}
36+
37+
setUsage();
38+
setUsageText();
39+
setColor();
40+
}
41+
42+
@Override
43+
public void setUsageText() {
44+
usageLB.setText(usage == -1 ? "ERROR" : usage + "%");
45+
}
46+
47+
@Override
48+
public void setUsage() {
49+
usageUI.setProgress(usage == -1 ? 0 : usage / 100.0);
50+
}
51+
52+
@Override
53+
public void setColor() {
54+
String color = usage >= baseline ? UsageStatus.DANGEROUS.getColor() : UsageStatus.NORMAL.getColor();
55+
usageUI.setStyle("-fx-progress-color: " + color);
56+
}
57+
}

0 commit comments

Comments
 (0)