i m trying to create a ListView, that some cell base on what they have inside can not be clicked. that works fine for now but the problem is when i click an element that is disabled, it return me the that last element which i clicked.
here is how i create the ListView
public ListView<String> createStringList(int sizeX, int sizeY) {
ListView<String> list = new ListView<String>();
list.setMaxSize(sizeX, sizeY);
list.setMinSize(sizeX, sizeY);
list.setStyle("-fx-font-size:8.0;");
list.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
#Override
public ListCell<String> call(ListView<String> param) {
return new ListCell<String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
} else if (Main.controller.getGame().chessBot != null) {
setText(item);
String botColor = Main.controller.getGame().chessBot.getBotColor().toString();
if (botColor.equals("BLACK")) {
if (item.contains("Black") || item.contains("Schwarz")) {
setDisable(true);
}else {
setDisable(false);
}
} else {
if (item.contains("White") || item.contains("Weiß")) {
setDisable(true);
}else {
setDisable(false);
}
}
} else {
setText(item);
setDisable(false);
}
}
};
}
});
return list;
}
Here i add the list on the Pane
...
...
historyList = GUIToolCreator.getInstance().createStringList(120, 220);
//TODO:
historyList.setOnMouseClicked(e -> {
int selectedIndex = getSelecetedInHistoryList();
if (selectedIndex >= 0) {
System.out.println(Main.controller.getGame().getHistory().get(selectedIndex).getStart().toSmallString() + "-"
+ Main.controller.getGame().getHistory().get(selectedIndex).getEnd().toSmallString() + ": Color ->"
+ Main.controller.getGame().getHistory().get(selectedIndex).getColor());
} else {
System.out.println("can not be selected!");
}
});
...
...
here all i need is that this method return -1 if the selected cell is disable but instead i recieve the last cell that i clicked
public int getSelecetedInHistoryList() {
int selectedIndex = historyList.getSelectionModel().getSelectedIndex();
if (selectedIndex == -1) {
return selectedIndex;
}
System.out.println(selectedIndex);
if (Main.controller.getGame().chessBot != null) {
if (Main.controller.getGame().chessBot.getBotColor() == Main.controller.getGame().getHistory()
.get(selectedIndex).getColor()) {
selectedIndex = -1;
}
}
return selectedIndex;
}
Related
Here is the code i write to change row color where leather's meter < 200 but i face null pointer exception in if condition. First i get all data from database and add them all to table view so i don't expect null pointer exception. What is the problem?
#FXML
TableView<Leather> tableView;
ObservableList<Leather> data = FXCollections.observableArrayList();
#Override
public void initialize(URL location, ResourceBundle resources) {
tableView.setEditable(true);
codeCol.setCellValueFactory(new PropertyValueFactory<>("code"));
colorCol.setCellValueFactory(new PropertyValueFactory<>("color"));
meterCol.setCellValueFactory(new PropertyValueFactory<>("meter"));
indexCol.setCellFactory(col -> new TableCell<Task, String>() {
#Override
public void updateIndex(int index) {
super.updateIndex(index);
if (isEmpty() || index < 0) {
setText(null);
} else {
setText(Integer.toString(index+1));
}
}
});
data.addAll(storeService.getAll());
tableView.setItems(data);
tableView.setRowFactory(tv -> new TableRow<Leather>(){
#Override
protected void updateItem(Leather item, boolean empty) {
super.updateItem(item,empty);
if (item.getMeter()<200){
setStyle("-fx-background-color: #DB8A6B");
}
}
});
}
You need to handle all cases in your rowFactory (in the same way you do in your cellFactory):
tableView.setRowFactory(tv -> new TableRow<Leather>(){
#Override
protected void updateItem(Leather item, boolean empty) {
super.updateItem(item,empty);
if (empty || item == null) {
setStyle("");
} else if (item.getMeter()<200){
setStyle("-fx-background-color: #DB8A6B");
} else {
setStyle("");
}
}
});
I'm trying to delete items in my ListView when delete Button is clicked, but it is not working and I can't figure it out.
Here is an Example of my Code for deleting an entry based on the instance "Student":
public void deleteButton(ActionEvent actionEvent) {
if (notesListView.getSelectionModel().isEmpty()) {
InfoModal.show("Bitte wählen Sie die zu löschende Notiz aus.");
return;
}
boolean delete = ConfirmationModal.show("Soll die Notiz gelöscht werden?");
if (delete) {
Dao<Notepad, Integer> notepadDao = db.getNotepadDao();
try {
if (this.objectType instanceof Student) {
Dao<StudentNotepad, Integer> studentNotepadDao = db.getStudentNotepadDao();
for (StudentNotepad n : studentNotepadDao) {
if (notesListView.getSelectionModel().getSelectedItem().equals(n.getNotepad())) {
SceneManager.getInstance().getLoaderForScene(SceneType.NOTESTAB_WINDOW).
<NotesTabController>getController().notesListView.getItems().remove(n.getNotepad());
studentNotepadDao.delete(n);
notepadDao.delete(n.getNotepad());
}
}
}
}
}
}
This is how my ListView/ListCell is initiated:
public void setObject(Object object) {
//Getting Object Type (Group, Groupage or Student)
this.objectType = object;
try {
if (this.objectType instanceof Student) {
ObservableList<Notepad> list = FXCollections.observableArrayList();
for (StudentNotepad s : db.getStudentNotepadDao()) {
if ((db.getLoggedInUser() == s.getNotepad().getUser()) && ((((Student) this.objectType).getId() == s.getStudent().getId()))) {
list.add(s.getNotepad());
}
}
notesListView.setItems(list);
notesListView.getItems().clear(); //not needed if list is definitly empty
db.getStudentNotepadDao().queryForAll().stream()
.map(StudentNotepad::getNotepad)
.filter(n -> n.getUser().equals(db.getLoggedInUser()))
.forEach(notesListView.getItems()::add);
notesListView.setCellFactory(new Callback<ListView<Notepad>, ListCell<Notepad>>() {
public ListCell<Notepad> call(ListView<Notepad> param) {
return new ListCell<Notepad>() {
#Override
protected void updateItem(Notepad item, boolean empty) {
super.updateItem(item, empty);
String style = "";
if (!empty && item != null) {
setText(item.getNotepadName());
switch (item.getNotepadPriority()) {
case "Hoch":
style = "-fx-background-color: red";
break;
case "Mittel":
style = "-fx-background-color: yellow";
break;
case "Niedrig":
style = "-fx-background-color: green";
break;
case "Neutral":
style = "-fx-background-color: grey";
break;
}
}
else {
setText("");
}
setStyle(style);
}
};
}
});
}
} catch(SQLException e) {
e.printStackTrace();
}
}
Additionally, my List is not refreshing after changing the Object within the same ObjectType. Example: Changing from Student1 to Student2. Changing between ObjectTypes themselves like Student1 to Group1 works. I think that the problem lays in the filter function of my ListCell.
Does someone have an idea? I'm struggeling with this problem for hours and can't figure it out!
I have a custom hashtable implementation in java.
public class HashSet<T> implements HashTableInterface<T> {
private static int DEFAULT_ARRAY_SIZE = 10;
private T[] items;
public HashSet() {
final T[] items = (T[]) new Object[DEFAULT_ARRAY_SIZE];
this.items = items;
}
#Override
public boolean add(T item) {
int index = getIndex(item);
do {
if (items[index] != null) {
index = (index + 1) % DEFAULT_ARRAY_SIZE;
} else {
items[index] = item;
break;
}
} while (index != getIndex(item));
return true;
}
#Override
public boolean remove(T item) {
if (contains(item)) {
items[getIndex(item)] = null;
return true;
} else {
return false;
}
}
#Override
public boolean contains(T item) {
T itemArray = items[getIndex(item)];
if (item.equals(itemArray)) {
return true;
} else {
int index = (getIndex(item) + 1) % DEFAULT_ARRAY_SIZE;
do {
if (items[index] != null) {
if (items[index].equals(item)) {
return true;
} else {
index = (index + 1) % DEFAULT_ARRAY_SIZE;
}
} else {
break;
}
} while (index != getIndex(item));
}
return items[getIndex(item)] != null;
}
#Override
public int getIndex(T item) {
return item.hashCode() % DEFAULT_ARRAY_SIZE;
}
#Override
public int size() {
int count = 0;
for (T item : items) {
if (item != null) {
count++;
}
}
return count;
}
#Override
public String toString() {
return items.toString();
}}
In my add method I want to check if the place where the item would be stored is free, if not it should go to the next index. Until it finds an empty place.
My code works but I think, there could be a better way to do this.
public boolean add(T item) {
int index = getIndex(item);
do {
if (items[index] != null) {
index = (index + 1) % DEFAULT_ARRAY_SIZE;
} else {
items[index] = item;
break;
}
} while (index != getIndex(item));
return true;
}
I have the same problem in the contains method
public boolean contains(T item) {
T itemArray = items[getIndex(item)];
if (item.equals(itemArray)) {
return true;
} else {
int index = (getIndex(item) + 1) % DEFAULT_ARRAY_SIZE;
do {
if (items[index] != null) {
if (items[index].equals(item)) {
return true;
} else {
index = (index + 1) % DEFAULT_ARRAY_SIZE;
}
} else {
break;
}
} while (index != getIndex(item));
}
return items[getIndex(item)] != null;
}
There a many different ways to do collision avoidance, what you did is called "Linear Probing".
There is also (reference here)
Quadratic probing
Double hashing
And schemes that use linked lists for colliding values.
All of these have different tradeoffs which you should inform yourself on to make an informed decision.
I have a combobox which shows list of User objects. I have coded a custom cell factory for the combobox:
#FXML ComboBox<User> cmbUserIds;
cmbUserIds.setCellFactory(new Callback<ListView<User>,ListCell<User>>(){
#Override
public ListCell<User> call(ListView<User> l){
return new ListCell<User>(){
#Override
protected void updateItem(Useritem, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
} else {
setText(item.getId()+" "+item.getName());
}
}
} ;
}
});
ListView is showing a string(id+name), but when I select an item from listview, Combobox is showing toString() method return value i.e address of object.
I can't override toString() method, because the User domain object should be same as the one at server.
How to display id in combobox? Please suggest
EDIT1
I tried below code. Now combo box shows id when I select a value from the listview.
cmbUserIds.setConverter(new StringConverter<User>() {
#Override
public String toString(User user) {
if (user== null){
return null;
} else {
return user.getId();
}
}
#Override
public User fromString(String id) {
return null;
}
});
The selected value in combo box is cleared when control focus is lost. How to fix this?
EDIT2:
#FXML AnchorPane root;
#FXML ComboBox<UserDTO> cmbUsers;
List<UserDTO> users;
public class GateInController implements Initializable {
#Override
public void initialize(URL location, ResourceBundle resources) {
users = UserService.getListOfUsers();
cmbUsers.setItems(FXCollections.observableList(users));
cmbUsers.getSelectionModel().selectFirst();
// list of values showed in combo box drop down
cmbUsers.setCellFactory(new Callback<ListView<UserDTO>,ListCell<UserDTO>>(){
#Override
public ListCell<UserDTO> call(ListView<UserDTO> l){
return new ListCell<UserDTO>(){
#Override
protected void updateItem(UserDTO item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
} else {
setText(item.getUserId()+" "+item.getUserNm());
}
}
} ;
}
});
//selected value showed in combo box
cmbUsers.setConverter(new StringConverter<UserDTO>() {
#Override
public String toString(UserDTO user) {
if (user == null){
return null;
} else {
return user.getUserId();
}
}
#Override
public UserDTO fromString(String userId) {
return null;
}
});
}
}
Just create and set a CallBack like follows:
#FXML ComboBox<User> cmbUserIds;
Callback<ListView<User>, ListCell<User>> cellFactory = new Callback<ListView<User>, ListCell<User>>() {
#Override
public ListCell<User> call(ListView<User> l) {
return new ListCell<User>() {
#Override
protected void updateItem(User item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
} else {
setText(item.getId() + " " + item.getName());
}
}
} ;
}
}
// Just set the button cell here:
cmbUserIds.setButtonCell(cellFactory.call(null));
cmbUserIds.setCellFactory(cellFactory);
You need to provide a functional fromString() Method within the Converter!
I had the same problem as you have and as I implemented the fromString() with working code, the ComboBox behaves as expected.
This class provides a few of my objects, for dev-test purposes:
public class DevCatProvider {
public static final CategoryObject c1;
public static final CategoryObject c2;
public static final CategoryObject c3;
static {
// Init objects
}
public static CategoryObject getCatForName(final String name) {
switch (name) {
case "Kategorie 1":
return c1;
case "Cat 2":
return c2;
case "Steuer":
return c3;
default:
return c1;
}
}
}
The converter object:
public class CategoryChooserConverter<T> extends StringConverter<CategoryObject> {
#Override
public CategoryObject fromString(final String catName) {
//This is the important code!
return Dev_CatProvider.getCatForName(catName);
}
#Override
public String toString(final CategoryObject categoryObject) {
if (categoryObject == null) {
return null;
}
return categoryObject.getName();
}
}
I want a javax.swing.ListModel be shared among multiple javax.swing.ComboBoxModels.
With the following code , when I select an item from the JComboBox,in a running program through the view, the JComboBox always shows the first item as selected.
public class DelegatedComboBoxModel<T> extends AbstractListModel<T> implements
ComboBoxModel<T> {
protected ListModel<T> listModel;
protected Object selectedObject;
ListDataListener listDataChangeDelegater = new ListDataListener() {
#Override
public void intervalRemoved(ListDataEvent e) {
fireIntervalRemoved(DelegatedComboBoxModel.this, e.getIndex0(),
e.getIndex1());
}
#Override
public void intervalAdded(ListDataEvent e) {
fireIntervalAdded(DelegatedComboBoxModel.this, e.getIndex0(),
e.getIndex1());
}
#Override
public void contentsChanged(ListDataEvent e) {
fireContentsChanged(DelegatedComboBoxModel.this, e.getIndex0(),
e.getIndex1());
}
};
public DelegatedComboBoxModel(ListModel<T> listModel) {
// DefaultComboBoxModel<E>
this.listModel = listModel;
if (listModel.getSize() > 0) {
selectedObject = listModel.getElementAt(0);
}
listModel.addListDataListener(listDataChangeDelegater);
}
#Override
public T getElementAt(int index) {
if (index >= 0 && index < listModel.getSize())
return listModel.getElementAt(index);
else
return null;
}
#Override
public int getSize() {
return listModel.getSize();
}
#Override
public void setSelectedItem(Object anObject) {
if ((selectedObject != null && !selectedObject.equals(anObject))
|| selectedObject == null && anObject != null) {
selectedObject = anObject;
fireContentsChanged(this, -1, -1);
}
}
#Override
public Object getSelectedItem() {
return selectedObject;
}
}
I cannot figure out what went wrong with the above code.
How to fix the code ?
(Limitation : Should not use or subclass DefaultComboBoxModel or use any third-party library.)