Skip to content

Commit

Permalink
Merge pull request #74 from tpoerschke/refactor/#56/category-mdv
Browse files Browse the repository at this point in the history
#56 Kategorien: Verwaltungsansichten in MDV überführen
  • Loading branch information
tpoerschke authored Aug 22, 2024
2 parents 4f6246e + 29293e2 commit 3b39068
Show file tree
Hide file tree
Showing 27 changed files with 407 additions and 419 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import timkodiert.budgetBook.view.ImportView;
import timkodiert.budgetBook.view.MonthlyOverview;
import timkodiert.budgetBook.view.View;
import timkodiert.budgetBook.view.category.CategoriesManageView;
import timkodiert.budgetBook.view.category.CategoryDetailView;
import timkodiert.budgetBook.view.fixed_turnover.FixedTurnoverDetailView;
import timkodiert.budgetBook.view.fixed_turnover.FixedTurnoverManageView;
import timkodiert.budgetBook.view.unique_expense.UniqueExpenseDetailView;
Expand Down Expand Up @@ -37,6 +39,8 @@ private void registerController() {
viewControllerMap.put(FixedTurnoverDetailView.class, viewComponent::getFixedTurnoverDetailView);
viewControllerMap.put(UniqueExpensesManageView.class, viewComponent::getUniqueExpensesManageView);
viewControllerMap.put(UniqueExpenseDetailView.class, viewComponent::getUniqueExpenseDetailView);
viewControllerMap.put(CategoriesManageView.class, viewComponent::getManageCategoriesView);
viewControllerMap.put(CategoryDetailView.class, viewComponent::getCategoryDetailView);
// Technische Ansichten
viewControllerMap.put(MigrationView.class, viewComponent::getMigrationView);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ public interface ServiceModule {

@Binds @Singleton PropertiesService bindPropertiesService(PropertiesServiceImpl impl);

@Binds @Singleton FXMLLoader bindFXMLLoader(BbFxmlLoader impl);
@Binds FXMLLoader bindFXMLLoader(BbFxmlLoader impl);
}
// @formatter:on
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
import timkodiert.budgetBook.view.AnnualOverviewView;
import timkodiert.budgetBook.view.ImportView;
import timkodiert.budgetBook.view.MainViewImpl;
import timkodiert.budgetBook.view.ManageCategoriesView;
import timkodiert.budgetBook.view.MonthlyOverview;
import timkodiert.budgetBook.view.NewCategoryView;
import timkodiert.budgetBook.view.category.CategoriesManageView;
import timkodiert.budgetBook.view.category.CategoryDetailView;
import timkodiert.budgetBook.view.fixed_turnover.FixedTurnoverDetailView;
import timkodiert.budgetBook.view.fixed_turnover.FixedTurnoverManageView;
import timkodiert.budgetBook.view.unique_expense.UniqueExpenseDetailView;
Expand All @@ -34,8 +34,8 @@ public interface ViewComponent {
// -----------------------------------
// Kategorien Ausgaben
// -----------------------------------
ManageCategoriesView getManageCategoriesView();
NewCategoryView getNewCategoryView();
CategoriesManageView getManageCategoriesView();
CategoryDetailView getCategoryDetailView();

// -----------------------------------
// Regelmäßige Umsätze
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,12 @@
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.MenuBar;
import javafx.scene.control.RadioMenuItem;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.jetbrains.annotations.Nullable;

Expand All @@ -29,16 +26,13 @@
import timkodiert.budgetBook.injector.ControllerFactory;
import timkodiert.budgetBook.injector.ViewComponent;
import timkodiert.budgetBook.properties.PropertiesService;
import timkodiert.budgetBook.util.StageBuilder;

import static timkodiert.budgetBook.view.FxmlResource.ANNUAL_OVERVIEW;
import static timkodiert.budgetBook.view.FxmlResource.IMPORT_VIEW;
import static timkodiert.budgetBook.view.FxmlResource.MAIN_VIEW;
import static timkodiert.budgetBook.view.FxmlResource.MANAGE_CATEGORIES_VIEW;
import static timkodiert.budgetBook.view.FxmlResource.MANAGE_REGULAR_TURNOVER_VIEW;
import static timkodiert.budgetBook.view.FxmlResource.MANAGE_UNIQUE_TURNOVER_VIEW;
import static timkodiert.budgetBook.view.FxmlResource.MONTHLY_OVERVIEW;
import static timkodiert.budgetBook.view.FxmlResource.NEW_CATEGORY_VIEW;

@Singleton
public class MainViewImpl implements Initializable, MainView {
Expand Down Expand Up @@ -147,34 +141,7 @@ public void openImportView(ActionEvent event) {

@FXML
private void openManageCategoriesView(ActionEvent event) {
try {
Stage stage = StageBuilder.create(languageManager)
.withModality(Modality.APPLICATION_MODAL)
.withOwner(this.primaryStage)
.withFXMLResource(MANAGE_CATEGORIES_VIEW.toString())
.withView(viewComponent.getManageCategoriesView())
.build();
stage.show();
} catch (Exception e) {
Alert alert = new Alert(AlertType.ERROR, languageManager.get("alert.viewCouldNotBeOpened"));
alert.showAndWait();
}
}

@FXML
private void openNewCategoryView(ActionEvent event) {
try {
Stage stage = StageBuilder.create(languageManager)
.withModality(Modality.APPLICATION_MODAL)
.withOwner(this.primaryStage)
.withFXMLResource(NEW_CATEGORY_VIEW.toString())
.withView(viewComponent.getNewCategoryView())
.build();
stage.show();
} catch (Exception e) {
Alert alert = new Alert(AlertType.ERROR, languageManager.get("alert.viewCouldNotBeOpened"));
alert.showAndWait();
}
loadViewPartial(FxmlResource.MANAGE_CATEGORY_VIEW);
}

@FXML
Expand Down
1 change: 0 additions & 1 deletion bb.application/src/main/resources/fxml/Main.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
<MenuItem mnemonicParsing="false" onAction="#openUniqueExpensesManageView" text="%menuItem.openUniqueExpensesView" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" onAction="#openManageCategoriesView" text="%menuItem.manageCategoriesView" />
<MenuItem mnemonicParsing="false" onAction="#openNewCategoryView" text="%menuItem.openNewCategoryView" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" onAction="#openSettingsView" text="%menuItem.openSettingsView" />
</items>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package timkodiert.budgetBook.domain.adapter;

import lombok.Getter;

import timkodiert.budgetBook.domain.model.Category;

public class CategoryAdapter implements Adapter<Category> {

@Getter
private final Category bean;

public CategoryAdapter(Category bean) {
this.bean = bean;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package timkodiert.budgetBook.domain.model;

import org.hibernate.annotations.GenericGenerator;

import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.hibernate.annotations.GenericGenerator;

@MappedSuperclass
@Getter
Expand All @@ -15,4 +14,8 @@ public abstract class BaseEntity implements ContentEquals {
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
protected int id;

public boolean isNew() {
return id <= 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package timkodiert.budgetBook.domain.model;

import static timkodiert.budgetBook.util.ObjectUtils.nvl;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
Expand All @@ -16,16 +14,19 @@
import jakarta.validation.constraints.NotBlank;
import javafx.scene.control.CheckBoxTreeItem;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

import timkodiert.budgetBook.domain.adapter.Adaptable;
import timkodiert.budgetBook.domain.adapter.CategoryAdapter;

import static timkodiert.budgetBook.util.ObjectUtils.nvl;

@Getter
@NoArgsConstructor
@RequiredArgsConstructor
@Entity
public class Category extends BaseEntity {
public class Category extends BaseEntity implements Adaptable<CategoryAdapter> {

@Setter
@NonNull
Expand Down Expand Up @@ -53,10 +54,27 @@ public class Category extends BaseEntity {
@Transient
private CheckBoxTreeItem<Category> treeItem = new CheckBoxTreeItem<>();

@Transient
private transient CategoryAdapter adapter;

public Category() {
initAdapter();
}

@Override
public void initAdapter() {
this.adapter = new CategoryAdapter(this);
}

public CheckBoxTreeItem<Category> asTreeItem() {
this.treeItem.setValue(this);
this.treeItem.getChildren().setAll(this.getChildren().stream().map(Category::asTreeItem).toList());
return this.treeItem;
CheckBoxTreeItem<Category> treeItem = new CheckBoxTreeItem<>();
treeItem.setValue(this);
treeItem.getChildren().setAll(this.getChildren().stream().map(Category::asTreeItem).toList());
return treeItem;
}

public boolean hasParent() {
return parent != null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package timkodiert.budgetBook.ui.helper;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

import javafx.scene.control.CheckBoxTreeItem;
import javafx.scene.control.TreeItem;
Expand All @@ -12,31 +14,40 @@

public class CategoryTreeHelper {

private List<CheckBoxTreeItem<Category>> allTreeItems;
private final List<CheckBoxTreeItem<Category>> allTreeItems;

private CategoryTreeHelper(TreeView<Category> categoriesTreeView, List<Category> categories) {
allTreeItems = categories.stream().map(Category::asTreeItem).toList();
List<? extends TreeItem<Category>> roots = allTreeItems.stream()
.filter(ti -> ti.getValue().getParent() == null)
.toList();
private CategoryTreeHelper(TreeView<Category> categoriesTreeView, List<Category> categories, boolean checkboxCells) {
List<CheckBoxTreeItem<Category>> roots = categories.stream().filter(Predicate.not(Category::hasParent)).map(Category::asTreeItem).toList();
allTreeItems = roots.stream().flatMap(root -> identifyAllTreeItems(root).stream()).toList();
TreeItem<Category> root = new TreeItem<>(new Category("ROOT"));
root.getChildren().addAll(roots);
categoriesTreeView.setCellFactory(CheckBoxTreeCell.forTreeView());
if (checkboxCells) {
categoriesTreeView.setCellFactory(CheckBoxTreeCell.forTreeView());
}
categoriesTreeView.setRoot(root);
categoriesTreeView.setShowRoot(false);
}

private List<CheckBoxTreeItem<Category>> identifyAllTreeItems(CheckBoxTreeItem<Category> root) {
List<CheckBoxTreeItem<Category>> items = new ArrayList<>();
items.add(root);
root.getChildren().forEach(child -> items.addAll(identifyAllTreeItems((CheckBoxTreeItem<Category>) child)));
return items;
}

public void selectCategories(Categorizable entity) {
allTreeItems.forEach(ti -> ti.setSelected(entity.getCategories().contains(ti.getValue())));
}

public List<Category> getSelectedCategories() {
return allTreeItems.stream()
.filter(CheckBoxTreeItem::isSelected).map(TreeItem::getValue)
.toList();
return allTreeItems.stream().filter(CheckBoxTreeItem::isSelected).map(TreeItem::getValue).toList();
}

public static CategoryTreeHelper from(TreeView<Category> treeView, List<Category> categories) {
return new CategoryTreeHelper(treeView, categories);
return new CategoryTreeHelper(treeView, categories, true);
}

public static CategoryTreeHelper from(TreeView<Category> treeView, List<Category> categories, boolean checkboxCells) {
return new CategoryTreeHelper(treeView, categories, checkboxCells);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public enum FxmlResource {
IMPORT_VIEW("/fxml/Importer/ImportView.fxml", "stageTitle.importView"),
IMAGE_VIEW("/fxml/ImageView.fxml", null),
MONTH_YEAR_PICKER_WIDGET("/fxml/MonthYearPickerWidget.fxml", null),
MANAGE_CATEGORIES_VIEW("/fxml/ManageCategories.fxml", null),
MANAGE_CATEGORY_VIEW("/fxml/category/Manage.fxml", "stageTitle.mdv.categories"),
CATEGORY_DETAIL_VIEW("/fxml/category/Detail.fxml", null),
NEW_CATEGORY_VIEW("/fxml/NewCategory.fxml", null),
;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package timkodiert.budgetBook.view.mdv_base;

import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.function.Supplier;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import org.jetbrains.annotations.Nullable;

import timkodiert.budgetBook.dialog.DialogFactory;
import timkodiert.budgetBook.domain.adapter.Adaptable;
import timkodiert.budgetBook.domain.adapter.Adapter;
import timkodiert.budgetBook.domain.model.BaseEntity;
import timkodiert.budgetBook.domain.repository.Repository;
import timkodiert.budgetBook.i18n.LanguageManager;

public abstract class BaseListManageView<T extends BaseEntity & Adaptable<A>, A extends Adapter<T>> extends BaseManageView<T, A> {

@FXML
protected TableView<A> entityTable;

protected final Repository<T> repository;
private final DialogFactory dialogFactory;

public BaseListManageView(Supplier<T> emptyEntityProducer,
Repository<T> repository,
FXMLLoader fxmlLoader,
DialogFactory dialogFactory,
LanguageManager languageManager) {
super(fxmlLoader, languageManager, repository, emptyEntityProducer);
this.repository = repository;
this.dialogFactory = dialogFactory;
}

@Override
public void initialize(URL location, ResourceBundle resources) {
super.initialize(location, resources);

entityTable.setRowFactory(tableView -> {
TableRow<A> row = new TableRow<>();
row.setOnMouseClicked(event -> {
if (event.getClickCount() == 1 && !row.isEmpty()) {
if (detailView.isDirty()) {
Alert alert = dialogFactory.buildConfirmationDialog();
Optional<ButtonType> result = alert.showAndWait();
if (result.get().equals(DialogFactory.CANCEL)) {
entityTable.getSelectionModel().select(detailView.getEntity().get().getAdapter());
return;
}
if (result.get().equals(DialogFactory.SAVE_CHANGES) && !detailView.save()) {
entityTable.getSelectionModel().select(detailView.getEntity().get().getAdapter());
return;
}
}

detailView.setEntity(row.getItem().getBean());
}
});
return row;
});

initControls();
}

@Override
protected void reloadTable(@Nullable T updatedEntity) {
entityTable.getItems().setAll(repository.findAll().stream().map(T::getAdapter).toList());
entityTable.sort();
}

}
Loading

0 comments on commit 3b39068

Please sign in to comment.