자바FX - 10에서 테이블 뷰에서 상품 정보를 가져와 테이블을 만드는 방법을 해봤다.
다음은 테이블 뷰에서 레코드를 입력하고 삭제하는 방법이다.
이 내용은 정보를 가져오는 데이터 베이스까지 다루지는 않는다. 와전한 프로그램의 완성을 위해서는 테이블 뷰를 활용하여 테이블의 정보를 업데이트 하면 다시 데이타베이스를 불러와서 똑같이 업데이트하는 작업이 필요할 것이다.
화면을 보고 조작하는 부분이 하나인 것이고 그 내용을 뒤에서 데이터 베이스에 업데이트 하는 내용은 또 다른 부분임을 염두해 둔다.
전 포스트 자바FX-10의 소스 코드에서 추가하는 부분이다.
새로운 데이터를 레코드에 입력하기 위해 컴포넌트들을 만들어야 한다. 텍스트 필드 세개와 버튼 두개다.
버튼 두개에는 이벤트 리스너를 등록하여 함수를 실행시킨다. 레코드를 추가하고 삭제하는 버튼이다. 버튼 하나에 하나의 기능이 들어간다.
자바의 SWING 을 써봤다면 어렵지 않은 문법이다.
자바는 C++은 아니지만 new 키워드를 사용할 때 마다 메모리에 버튼이 생성된다는 것을 생각하면 좀더 이해가 빠르다.
이제 컴포넌트들을 레이아웃에 추가하면 된다. Hbox를 사용해서 수평으로 보이게 될 것이다. VBox 레이아웃에 HBox 를 추가할 것이다. 레이아웃은 계산하는 게 필요하지만 잘 모르겠으면 여러번 사용하다 보면 대략적으로 자신에게 맞는 스타일이 나온다. 어느 정도는 JAVA FX 에서 자동으로 배치한다.
추가와 삭제 버튼을 구현한다. 버튼을 클릭했을 때 현재 텍스트필드에 있는 내용들을 가져와서 Product 클래스를 업데이트 한다. 그 후 테이블 뷰에 바뀐 프로덕트 클래스를 업데이트 한다. 현재의 텍스트 필드에 있는 내용은 지워준다.
이해하기 쉬운 절차니까 코드가 길어도 큰 문제가 없을 것이다. 삭제 버튼은 현재 테이블 뷰에서 선택된 아이템 getSelectedItems 를 가져와서 삭제한다.
이렇게 하면 화면상에서 업데이트가 된다. 소스코드가 언뜻 긴 것 처럼 보이지만 GUI 가 그렇듯이 단순 컴포넌트의 반복이다. 디자인적인 면에 신경을 쓰다보면 코드가 길어질 수 있다. 어찌보면 디자인의 영역은 예술에 가까운 것이지 알고리즘과는 좀 다른 부분이다. 그래서 프론트엔드 UX를 백엔드와 분리하는 이유기도 한데 디자인 영역은 코드가 길어져도 별로 복잡하지 않다. 알고리즘이 꼬였을 때가 힘든 것이다.
일례로 다음의 메인페이지 원본소스를 보면 엄청나게 복잡하게 되있다. 다음의 개발자들은 매일 같이 저 복잡한 코드를 들여다 보고 일을 한다. 하지만 프론트엔드의 소스는 HTML과 CSS로 되어 있기 때문에 절차적으로 하나씩 판독이 가능하다. 자바스크립트가 들어간 부분이 있지만 대부분 자바 스크립트는 파일을 분리해두었다. 즉 별도의 모듈로 관리하는 것이다.
자바 FX에서도 HTML/CSS와 비슷한 FXML 이라는게 있다. 2000년대 이후 코드와 디자인 적인 측면을 지속적으로 분리하려는 시도가 있는 것이다. 가장 성공적인 표준은 JS, HTML/CSS 가 되겠지만 자바FX에서도 그런 도구를 사용할 수 있다는 점은 알아두면 좋을 것이다.
view-source:https://www.daum.net
*소스코드
package com;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
Stage window;
Scene scene;
TableView<Product> tableView;
TextField nameInput, priceInput, quantityInput;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
window.setTitle("Learning JavaFX");
// Name
TableColumn<Product, String> nameColumn = new TableColumn<>("NAME");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
// Price
TableColumn<Product, Long> priceColumn = new TableColumn<>("PRICE");
priceColumn.setMinWidth(200);
priceColumn.setCellValueFactory(new PropertyValueFactory<>("price"));
// QT
TableColumn<Product, Integer> quantityColumn = new TableColumn<>("QT");
quantityColumn.setMinWidth(150);
quantityColumn.setCellValueFactory(new PropertyValueFactory<>("quantity"));
// Name Input
nameInput = new TextField();
nameInput.setPromptText("Name");
nameInput.setMinWidth(100);
// price Input
priceInput = new TextField();
priceInput.setPromptText("Price");
// QT Input
quantityInput = new TextField();
quantityInput.setPromptText("Quantity");
// Button
Button addButton = new Button("추가");
addButton.setOnAction(e -> addButtonClicked());
Button deleteButton = new Button("삭제");
deleteButton.setOnAction(e -> deleteButtonClicked());
HBox hBox = new HBox();
hBox.setPadding(new Insets(10,10,10,10));
hBox.setSpacing(10);
hBox.getChildren().addAll(nameInput,priceInput,quantityInput,addButton,deleteButton);
tableView = new TableView<>();
tableView.setItems(getProduct());
tableView.getColumns().addAll(nameColumn, priceColumn, quantityColumn);
VBox layout = new VBox(20);
layout.setPadding(new Insets(10,10,10,10));
layout.getChildren().add(tableView);
layout.getChildren().add(hBox);
scene = new Scene(layout, 650, 400);
window.setScene(scene);
window.show();
}
private void deleteButtonClicked() {
ObservableList<Product> productSelected, allProducts;
allProducts = tableView.getItems();
productSelected = tableView.getSelectionModel().getSelectedItems();
productSelected.forEach(allProducts::remove);
}
private void addButtonClicked() {
Product product = new Product();
product.setName(nameInput.getText());
product.setPrice(Long.parseLong(priceInput.getText()));
product.setQuantity(Integer.parseInt(quantityInput.getText()));
tableView.getItems().addAll(product);
nameInput.clear();
priceInput.clear();
quantityInput.clear();
}
// 모든 product
public ObservableList<Product> getProduct(){
ObservableList<Product> products = FXCollections.observableArrayList();
products.add(new Product("노트북", 1200000L, 20));
products.add(new Product("아이패드", 900000L, 70));
products.add(new Product("카메라", 400000L, 45));
products.add(new Product("모니터", 450000L, 30));
products.add(new Product("스마트TV", 350000L, 40));
return products;
}
}