Редактирование строки в TableView

1

У меня есть TableView в JavaFX (2.2/Java 7), где каждый столбец сортируется (сортируется в реальном времени), а все строки/столбцы редактируются. В качестве примера допустим, что вся таблица представляет собой "порядок". Каждая строка в таблице представляет "строки заказа", а столбцы представляют свойства "строки заказа", такие как "продукт", "количество", "цена" и т.д. Пользователь может добавлять, удалять и редактировать строки ("заказать линии "), как он пожелает.

Чтобы сделать пользовательский интерфейс менее запутанным для пользователя, я хотел бы использовать выбор строки, а также следить за тем, чтобы только одна строка редактировалась за раз (потому что сортировка в противном случае сделала бы отредактированное значение "прыгать" в таблице), У меня также есть проверка на "строку заказа", которую легче визуализировать для строки, а не отдельных столбцов (в качестве примера предположим, что комбинация или продукт X и количество 7 являются незаконными, так как продукт X можно заказывать только в единицах из 5, я хочу выделить как X, так и значение 7).

Выбор строки можно легко включить. Но есть ли хороший способ для редактирования строк? Режим по умолчанию/встроенный режим редактирования в TableView больше похож на режим Excel, где каждый столбец можно редактировать, проверять и проверять отдельно, и это не то, что я хочу. Я хочу что-то вроде списка файлов в проводнике файлов. Важно, чтобы все изменения для редактируемой строки поручены к модели основы (items собственности на TableView) сразу (то есть. Нет onEditCommit для отдельных столбцов) из - за сортировки и проверки.

Я реализовал что-то подобное раньше в Swing, а затем в итоге использовал то, что я назвал ColumnList, который действительно представляет собой List, но с заголовками столбцов и столбцами, чтобы он отображался точно так же, как таблица. Будет ли это также жизнеспособным выбором в JavaFX? Класс TableColum кажется очень привязанным к TableView, но я могу что-то упустить.

Я также знаю пример "Адресной книги" в учебниках JavaFX, в котором есть поля выбора строк и редактора под таблицей. Это то, что я в настоящее время реализовал в своем приложении, но хочу, чтобы редактирование отображалось в строке с текущей выбранной строкой. Таким образом, превращение редакторов в "сверху" или "внутри", выбранная в данный момент строка также является альтернативой, если кто-то может придумать способ ее достижения.

  • 0
    Да, есть хороший способ. И да, TableColumn очень ограничен с TableView . Просто взгляните на этот урок по оракулам, я думаю, он объясняет все, что вам нужно.
  • 0
    Спасибо @ Брано! Хотя я знаю об этом примере, и это не совсем то, чего я хочу. Я хочу "встроенное" редактирование строки. Это могло бы работать, хотя, если бы я мог заставить текстовое поле редактирования появляться "сверху" таблицы, внутри выбранной строки. Но я еще не нашел способ сделать это ... Я обновлю вопрос.
Показать ещё 2 комментария
Теги:
javafx
javafx-2

1 ответ

3
Лучший ответ

Вы всегда можете сделать свой собственный редактор и вытащить его за стол по мере необходимости. Это не отличное решение, но с некоторыми настройками это может быть приятно. Dbl нажмите, чтобы отредактировать строку.

import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
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.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TableEdit extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<Order> tv = new TableView<>();
        ObservableList<Order> items = FXCollections.observableArrayList(
                new Order("a-12", 100), new Order("b-23", 200), new Order("c-34", 300));
        tv.setItems(items);

        TableColumn<Order, String> tcNum = new TableColumn("Order#");
        tcNum.setPrefWidth(100);
        TableColumn<Order, Number> tcQty = new TableColumn("Qty");
        tcQty.setPrefWidth(100);
        tcNum.setCellValueFactory(new PropertyValueFactory<>("orderNum"));
        tcQty.setCellValueFactory(new PropertyValueFactory<>("qty"));
        tv.getColumns().addAll(tcNum, tcQty);

        HBox hbox = new HBox();
        TextField orderNum = new TextField();
        orderNum.setPrefWidth(100);
        TextField qty = new TextField();
        qty.setPrefWidth(100);

        tv.getSelectionModel().selectedItemProperty().addListener((obs, ov, nv) -> {
            if (nv != null) {
                orderNum.setText(nv.orderNum.get());
                qty.setText(String.valueOf(nv.qty.get()));
            }
        });

        Button commit = new Button("Commit");
        commit.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent evt) {
                Order item = tv.getSelectionModel().getSelectedItem();
                item.orderNum.set(orderNum.getText());
                item.qty.set(Integer.valueOf(qty.getText()));
                tv.toFront();
            }
        });

        hbox.getChildren().addAll(orderNum, qty, commit);
        StackPane root = new StackPane(hbox, tv);

        tv.setOnMouseClicked(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent evt) {
                if (evt.getClickCount()==2){
                    StackPane.setMargin(hbox, new Insets(evt.getSceneY(), 0, 0, 0));
                    hbox.toFront();
                }
            }
        });

        Scene scene = new Scene(root, 300, 250);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }

    public class Order {

        private final SimpleStringProperty orderNum = new SimpleStringProperty();
        private final SimpleIntegerProperty qty = new SimpleIntegerProperty();

        public SimpleStringProperty orderNumProperty() {return orderNum;}
        public SimpleIntegerProperty qtyProperty() {return qty;}

        public Order(String orderNum, int qty) {
            this.orderNum.set(orderNum);
            this.qty.set(qty);
        }
    }
}

Изображение 174551

  • 0
    Интересно ... :-) Спасибо! Завтра мне придется заняться этим, поскольку у меня нет рабочего ноутбука с проектом, в котором я сейчас нахожусь. Из того, что я понимаю, это выглядит многообещающе. Я не уверен, будет ли hbox полностью помещаться в текущем выделении с этим кодом или текстовые поля совпадают со столбцами в таблице. Но это похоже на возможное начало. :-)
  • 0
    Я добавил рис. Проблема в нахождении вершины TableCell. Все остальные выравнивания работают нормально. Я просто использовал prefWidth.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню