Есть метод, который удаляет из БД выбранную в TableView
запись. Запись из БД нормально удаляется, а как обновить TableView
? В TableView
остается запись, пока не перезапустить приложение.
public class MainController {
@FXML
private ComboBox categoryComboBox;
@FXML
private TableView<Phone> phonesTable;
@FXML
private TableColumn<Phone, Integer> idColumn;
@FXML
private TableColumn<Phone, String> modelColumn;
@FXML
private TableColumn<Phone, Integer> priceColumn;
@FXML
private TableColumn<Phone, String> categoryColumn;
@FXML
private TableColumn<Phone, String> descriptionColumn;
@FXML
private TableColumn<Phone, String> producerColumn;
@FXML
private TableColumn<Phone, Integer> statusColumn;
//Главная сцена
private Stage mainStage;
//Сцена редактирования информации
private Stage editStage;
//Загрузчик для сцен редактирования и добавления
private FXMLLoader fxmlLoader = new FXMLLoader();
//Parent для сцены редактирования
Parent fxmlEdit;
//Контроллер сцены редактирования
EditController editController;
//Телефоны
private Phones phonesList = new Phones();
//Категории
private Categories categoriesList = new Categories();
//Фильтруемый список. Нужен для фильтрации списка телефонов, когда в выпадающем списке будет выбираться определенная категория
private FilteredList<Phone> filteredList = new FilteredList<Phone>(phonesList.getPhoneList(), phone -> true);
//Метод устанавливает подмостки для главного контроллера
public void setMainStage(Stage mainStage) {
this.mainStage = mainStage;
}
//Метод инициализации
public void initialize() throws SQLException, IOException {
fillPhonesTable();
fillCategoryComboBox();
//Выводим в колонки TableView данные из списка
idColumn.setCellValueFactory(new PropertyValueFactory<Phone, Integer>("id"));
modelColumn.setCellValueFactory(new PropertyValueFactory<Phone, String>("model"));
priceColumn.setCellValueFactory(new PropertyValueFactory<Phone, Integer>("price"));
categoryColumn.setCellValueFactory(new PropertyValueFactory<Phone, String>("category"));
descriptionColumn.setCellValueFactory(new PropertyValueFactory<Phone, String>("description"));
producerColumn.setCellValueFactory(new PropertyValueFactory<Phone, String>("producer"));
statusColumn.setCellValueFactory(new PropertyValueFactory<Phone, Integer>("status"));
comboBoxFilter(categoryComboBox);
//Сортируемый список, чтобы при нажатии на колонку в TableView данные сортировались
SortedList<Phone> sortedList = new SortedList<Phone>(filteredList);
//Выполняет сортировку данных в TableView при нажатии на заголовок колонки в TavleView
sortedList.comparatorProperty().bind(phonesTable.comparatorProperty());
//Выводим отсортированные и отфильтрованные данные в TableView
phonesTable.setItems(sortedList);
//Загружаем сцену редактирования
editSceneLoader();
}
//Данный метод заполняет выпадающий список categoryComboBox названиями категорий из таблицы БД
private void fillCategoryComboBox() throws SQLException, IOException {
//Заполняем список названиями категорий
categoriesList.fillCategoryList();
//Устанавливаем для ComboBox значения из списка, который получили на предыдущем этапе.
categoryComboBox.setItems(categoriesList.getCategoryList());
}
private void fillPhonesTable() throws SQLException, IOException {
//Заполняем список phonesList телефонами
phonesList.fillPhoneList();
//При двойном клике на запись открываем окно для редактирования информации
phonesTable.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (event.getClickCount() == 2) {
//Устанавливаем методику. Т.е. передаем в сцену редактирования данные о выбранной модели телефона
editController.setPhone((Phone) phonesTable.getSelectionModel().getSelectedItem());
//Вызываем метод, для отображения модального окна
editSceneShow();
}
}
});
}
//Метод фильтрует записи в TableView при выборе категории в ComboBox
private void comboBoxFilter(ComboBox comboBox) {
comboBox.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
filteredList.setPredicate(phone -> {
if (comboBox.getValue() == null) {
return true;
}
String filter = comboBox.getValue().toString().toLowerCase();
if (phone.getCategory().toLowerCase().equals(filter)) {
return true;
}
return false;
});
}
});
}
public void onDeleteClick(ActionEvent actionEvent) throws SQLException, IOException {
try (Connection connection = DBConnection.getConnection()) {
//Составляем подготовленный запрос на удаление записи из таблицы
String deleteQuery = "DELETE FROM phones WHERE id = ?";
//Подготовленный запрос
PreparedStatement statement = connection.prepareStatement(deleteQuery);
//Получаем выбранную в TableView запись (т.е. объект типа Phone) и получаем значения поля id через геттер getID()
statement.setInt(1, phonesTable.getSelectionModel().getSelectedItem().getId());
//Выполняем сам запрос
statement.executeUpdate();
}
}
}
Сделал так. Есть ли способ лучше?
public void onDeleteClick(ActionEvent actionEvent) throws SQLException, IOException {
try (Connection connection = DBConnection.getConnection()) {
//Составляем подготовленный запрос на удаление записи из таблицы
String deleteQuery = "DELETE FROM phones WHERE id = ?";
//Подготовленный запрос
PreparedStatement statement = connection.prepareStatement(deleteQuery);
//Получаем выбранную в TableView запись (т.е. объект типа Phone) и получаем значения поля id через геттер getID()
statement.setInt(1, phonesTable.getSelectionModel().getSelectedItem().getId());
//Выполняем сам запрос
statement.executeUpdate();
//Удаляем из списка phonesList удаляемый из БД элемент.
// Т.е. узнаем индекс выбранной записи из TableView и удаляем элемент с таким id в списке phonesList
phonesList.getPhoneList().remove(phonesTable.getSelectionModel().getSelectedIndex());
//Фильтруемый список. Нужен для фильтрации списка телефонов, когда в выпадающем списке будет выбираться определенная категория
FilteredList<Phone> filteredList = new FilteredList<Phone>(phonesList.getPhoneList(), phone -> true);
//Сортируемый список, чтобы при нажатии на колонку в TableView данные сортировались
SortedList<Phone> sortedList = new SortedList<Phone>(filteredList);
//Выполняет сортировку данных в TableView при нажатии на заголовок колонки в TavleView
sortedList.comparatorProperty().bind(phonesTable.comparatorProperty());
//Выводим отсортированные и отфильтрованные данные в TableView
phonesTable.setItems(sortedList);
}
}
Вот такая ошибка
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787) at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670) at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) at javafx.base/javafx.event.Event.fireEvent(Event.java:198) at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8863) at javafx.controls/javafx.scene.control.Button.fire(Button.java:200) at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206) at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274) at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.base/javafx.event.Event.fireEvent(Event.java:198) at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3876) at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1300(Scene.java:3604) at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1874) at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2613) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295) at java.base/java.security.AccessController.doPrivileged(Native Method) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433) at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556) at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942) at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175) at java.base/java.lang.Thread.run(Thread.java:844) Caused by: java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76) at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275) at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83) at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782) ... 47 more Caused by: java.lang.UnsupportedOperationException at java.base/java.util.AbstractList.remove(AbstractList.java:167) at java.base/java.util.AbstractList$Itr.remove(AbstractList.java:387) at java.base/java.util.AbstractCollection.remove(AbstractCollection.java:299) at phonesapp.controllers.MainController.onDeleteClick(MainController.java:249) ... 58 more
На строке
phonesTable.getItems().remove(phonesTable.getSelectionModel().getSelectedItem());
Класс Phones
public class Phones {
private ObservableList<Phone> phoneList = FXCollections.observableArrayList();
public ObservableList<Phone> getPhoneList() {
return phoneList;
}
public void fillPhoneList() throws SQLException, IOException {
try (Connection connection = DBConnection.getConnection()) {
Statement statement = connection.createStatement();
String query = "SELECT * FROM phones LEFT OUTER JOIN category ON phones.categoryID = category.id LEFT OUTER JOIN producer ON phones.producerID = producer.id";
try (ResultSet resultSet = statement.executeQuery(query)) {
while (resultSet.next()) {
int id = resultSet.getInt("id");
String model = resultSet.getString("model");
int price = resultSet.getInt("price");
String category = resultSet.getString("category");
String description = resultSet.getString("description");
String producer = resultSet.getString("producer");
int status = resultSet.getInt("status");
phoneList.add(new Phone(id, model, price, category, description, producer, status));
}
}
}
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Приложение имеет сложный дизайн и по этому было решено делать прорисовку на surfaceView, то есть почти нет никаких xml файлов, все отрисовывается...
Почему в записи кода thisname = name; есть ошибка Cannot acces java