I'm trying to add an image to a tableView and went through several questions and answers and it still doesn't work.
The other fields in the tableView like name are loaded correctly.
Intelij tells me that updateItem is never used, which is probably why it doesn't work, but I have no idea how to debug this...
Here's what I got so far
#FXML private TableColumn<PlayerManager, Image> tableColumnType;
#FXML private void initialize(){
tableColumnType.setCellFactory(param -> {
//Set up the ImageView
final ImageView imageview = new ImageView();
imageview.setFitHeight(10);
imageview.setFitWidth(10);
///imageview.setImage(imageComputer); //uncommenting this places the image on all cells, even empty ones
//Set up the Table
TableCell<PlayerManager, Image> cell = new TableCell<PlayerManager, Image>() {
public void updateItem(PlayerManager item, boolean empty) {
if (item != null) { // choice of image is based on values from item, but it doesn't matter now
imageview.setImage(imageComputer);
}
}
};
// Attach the imageview to the cell
cell.setGraphic(imageview);
return cell;
});
}
The questions I went through are:
How to add an Image into a JavaFx TableView column
Display image in table
Inserting images into TableView rows - JavaFX
The signature of the updateItem method is wrong: it should be
public void updateItem(Image item, boolean empty) { /* ... */ }
If the compiler rejects the #Override annotation, then you know you are not defining the correct method. So you should use #Override and if you get a compile error, it is a signal that something is not right.
So you should be able to do
#FXML private TableColumn<PlayerManager, Image> tableColumnType;
#FXML private void initialize(){
tableColumnType.setCellFactory(param -> {
//Set up the ImageView
final ImageView imageview = new ImageView();
imageview.setFitHeight(10);
imageview.setFitWidth(10);
///imageview.setImage(imageComputer); //uncommenting this places the image on all cells, even empty ones
//Set up the Table
TableCell<PlayerManager, Image> cell = new TableCell<PlayerManager, Image>() {
#Override
public void updateItem(Image item, boolean empty) {
if (item != null) { // choice of image is based on values from item, but it doesn't matter now
imageview.setImage(imageComputer);
}
}
};
// Attach the imageview to the cell
cell.setGraphic(imageview);
return cell;
});
}
If your table cell needs to access the actual PlayerManager object, then you need to make the table column a TableColumn<PlayerManager, PlayerManager> and update the cellValueFactory (which you haven't shown) accordingly.
Finally, note that your updateItem(...) method needs to deal with all cases, including empty cells for which the item is null.
So you may need something like
#FXML private TableColumn<PlayerManager, PlayerManager> tableColumnType;
#FXML private void initialize(){
tableColumnType.setCellValueFactory(cellData -> new SimpleObjectProperty<PlayerManager>(cellData.getValue());
tableColumnType.setCellFactory(param -> {
//Set up the ImageView
final ImageView imageview = new ImageView();
imageview.setFitHeight(10);
imageview.setFitWidth(10);
///imageview.setImage(imageComputer); //uncommenting this places the image on all cells, even empty ones
//Set up the Table
TableCell<PlayerManager, PlayerManager> cell = new TableCell<PlayerManager, PlayerManager>() {
#Override
public void updateItem(PlayerManager item, boolean empty) {
if (item != null) { // choice of image is based on values from item, but it doesn't matter now
imageview.setImage(imageComputer);
} else {
imageView.setImage(null);
}
}
};
// Attach the imageview to the cell
cell.setGraphic(imageview);
return cell;
});
}
The signature of the updateItem() method is wrong.
Try to use:
#Override
protected void updateItem(Image item, boolean empty){
//your code
}
Edit:
I think you can solve your problem by also setting a CellValueFactory for your TableColumn:
tableColumnType.setCellValueFactory(
new Callback<CellDataFeatures<PlayerManager, Image>, ObservableValue<Image>(){
#Override
public ObservableValue<Image> call(
CellDataFeatures<PlayerManager, Image> param) {
return param.getValue().exampleMethod; /* Method of your PlayerManager which returns an Image as ObservableValue. To do so you could wrap it in an `ObjectProperty<Image>`*/
}
}
);
Related
I realized that, even though the Sharedprefs, saves the checkbox state, it doesn't keep the drawable resource background thingy that way...... any way to save that too? I was hoping it stays like the picture below. EDIT : So my objective would be that, On checkbox being checked, background changes, because of sharedprefs, the checked state is saved and on exiting the app, the checkbox remains checked but the background of the checkbox returns to its "un-highlighted" state without the drawable background
CheckBox C1,C2,C3;
//Creating keys for sharedpreference
private static final String C1key = "C1_key";
private static final String C2key = "C2_key";
private static final String C3key = "C3_key";
SharedPreferences shp = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anime);
//sharedpreference created with the name as anime
shp = getSharedPreferences("Anime",MODE_PRIVATE);
//This is just background gradient animation
ConstraintLayout constraintLayout = findViewById(R.id.layout_anime);
AnimationDrawable animationDrawable = (AnimationDrawable) constraintLayout.getBackground();
animationDrawable.setEnterFadeDuration(2000);
animationDrawable.setExitFadeDuration(4000);
animationDrawable.start();
//Initializing checkboxes
C1 = findViewById(R.id.C1);
C2 = findViewById(R.id.C2);
C3 = findViewById(R.id.C3);
//mapping checkbox and string for ease of use during sharedprefs
Map<String, CheckBox> checkBoxMap = new HashMap();
checkBoxMap.put(C1key,C1);
checkBoxMap.put(C2key,C2);
checkBoxMap.put(C3key,C3);
//loading initial values from sharedprefs, and also creating onCheckedChangeListeners from the map
loadInitialValues(checkBoxMap);
setupCheckedChangeListener(checkBoxMap);
}
public void loadInitialValues(Map<String, CheckBox> checkboxMap) {
for (Map.Entry<String, CheckBox> checkboxEntry: checkboxMap.entrySet()) {
boolean checked = shp.getBoolean(checkboxEntry.getKey(), false);
checkboxEntry.getValue().setChecked(checked);
}
}
public void setupCheckedChangeListener(Map<String, CheckBox> checkboxMap) { //for loop to cover all the checkboxes and keys in the map
for (final Map.Entry<String, CheckBox> checkboxEntry: checkboxMap.entrySet()) {
checkboxEntry.getValue().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
final SharedPreferences.Editor editor = shp.edit();
editor.putBoolean(checkboxEntry.getKey(), isChecked);
editor.apply();
// this part is to turn the background of the checkbox to a specified drawable when its checked and when it isn't
if(checkboxEntry.getValue().isChecked()) //checkboxentry.getvalue().ischecked is to check whether specific checkboxes are in the checked state or not, Ex C1.ischecked() C2.ischecked() and so on
{
checkboxEntry.getValue().setBackgroundResource(R.drawable.cb_background);
}
else
{
checkboxEntry.getValue().setBackgroundResource(R.drawable.cb_background_default);
}
}
});
}
Than i believe should be something like this:
//If is selected set the background
if (C1.isChecked()) {
C1.setSelected(true);
C1.setBackgroundResource(R.drawable.[name of the background]);
}else{
//If is not selected
C1.setBackgroundResource(0);
}
Thanks to Suehtam for helping me out with this really appreciate it!!! this the solution
private void loadInitialValues(Map<String, CheckBox> checkboxMap) {
for (Map.Entry<String, CheckBox> checkboxEntry: checkboxMap.entrySet()) {
boolean checked = shp.getBoolean(checkboxEntry.getKey(), false);
checkboxEntry.getValue().setChecked(checked);
if (checkboxEntry.getValue().isChecked()) {
checkboxEntry.getValue().setSelected(true);
checkboxEntry.getValue().setBackgroundResource(R.drawable.cb_background);
}else{
//If is not selected
checkboxEntry.getValue().setBackgroundResource(0);
}
}
}
private void setupCheckedChangeListener(Map<String, CheckBox> checkboxMap) {
for (final Map.Entry<String, CheckBox> checkboxEntry: checkboxMap.entrySet()) {
checkboxEntry.getValue().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
final SharedPreferences.Editor editor = shp.edit();
editor.putBoolean(checkboxEntry.getKey(), isChecked);
if (checkboxEntry.getValue().isChecked()) {
checkboxEntry.getValue().setSelected(true);
checkboxEntry.getValue().setBackgroundResource(R.drawable.cb_background);
}else{
//If is not selected
checkboxEntry.getValue().setBackgroundResource(0);
}
editor.apply();
}
});
}
}
Humm, if i understood what you want to do is not to save the value but instead to set the box selected.
something like this:
if(C1.isChecked()){
//In this way the box would be with the selected view.
C1.setSelected(true)
}
if is not the state selected and is just the drawable you could do the same:
It's just an example since i don't know which drawable function you are going to use.
Ex:
if(C1.isChecked()){
C1.setCheckMarkDrawable([drawable location]);
}
I found this post and I think it's very similar but I need some help adapting it to my case: How to set the style of list view cells based on a condition in JavaFX
Basically, I have a ListView and I want to change the background color of individual cells based on a condition. I have an arrayList locations of location objects, and I want to check a property of a single location to determine the background color of the cell. the ListView is populated by iterating through locations and getting the name of each location, then storing it in arraylist, then finally populating the listView. Here is relevant code:
#FXML
private ListView<String> locationListView;
private ArrayList<String> locationList = new ArrayList();
private ListProperty<String> listProperty = new SimpleListProperty<>();
#Override
public void initialize(URL url, ResourceBundle rb) {
for (int i = 0; i < locations.size(); i++) {
locationList.add(locations.get(i).name());
}
}
locationListView.itemsProperty().bind(listProperty);
listProperty.set(FXCollections.observableArrayList(locationList));
}
And here is where I am struggling, I copied/modified from the post I linked above.
locationListView.setCellFactory(lv -> new ListCell<String>() {
#Override
protected void updateItem(String c, boolean empty) {
super.updateItem(c, empty);
for (int i = 0; i < locations.size(); i++) {
if (locations.get(i).visited) {
setStyle("-fx-background-color: green");
}
}
}
});
I'm aware this is long ways from working as intended but I'm not sure where to go from here, I think I'm approaching it incorrectly.
Overall I have maybe made this more complicated than it needs to be (new to javafx), but any help is appreciated.
I'll use a ListView as navigation menu. So I found out how to add an ImageView next to the ListCell title using ListView.setCellFactory. But now I want to have more space between ImageView and title. How can I achieve this?
This is my code:
lvNavigation.setCellFactory(listView -> new ListCell<String>(){
private ImageView imageView = new ImageView();
#Override
public void updateItem(String name, boolean empty) {
super.updateItem(name, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
Image image = getImageFromStatus(name);
imageView.setImage(image);
setText(name);
setGraphic(imageView);
}
}
});
getImageFromStatus(name) returns an Image object.
Thats how it actually looks like:
Use the graphicTextGapProperty :
setGraphicTextGap(10.0); // Or any other appropriate value
i want to style JavaFx list cells based on text Value. I can do a style by even/odd (s. below)
.list-cell:odd {
-fx-font-size: 20;
}
Is there a possibility based on text, like
`.list-cell[text*='containedText''] {
-fx-font-size: 20;
}
If this is not possible, is there something like :nth-child() (this is not working). I know which childs have to be selected, so i could create the css on the fly.
`
My final goal is to style a autocomplete based on attributes of each entry.
regards
Andreas
I found a solution for styling AutoComplete Cells based on included text. But it's not very elegant. I copied the following classes:
AutoCompletePopup
AutoCompletePopupSkin
autocompletion.css
AutoCompletionBinding
AutoCompletionTextFieldBinding
In AutoCompletePopup i overwrote one method to add a CellFactory:
protected Skin<?> createDefaultSkin() {
autoCompletePopupSkin = new AutoCompletePopupSkin(this);
final ListView<T> listView = (ListView) autoCompletePopupSkin.getNode();
listView.setCellFactory(l -> new TextFieldListCell<T>() {
#Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
this.getStyleClass().remove("bold");
if(!empty && item.toString().contains("(H)")) {
this.getStyleClass().add("bold");
}
}
});
return autoCompletePopupSkin;
}
In the css i added the class with my desired styling;
.bold { -fx-font: normal bold 12 serif;}
Thx to James_D who gave me the hint with the CellFactory!
I am new for android, I have ListView with custom adapter, I pass one string if matches in ListView item want to change list item text color from Activity.
Here my code:
MyActivity:
public void handleResult(String rawResult) {
if(Utility.isNotNull(rawResult.getText().toString())) {
for(int i=0;i<listView.getAdapter().getCount();i++){
if(rawResult.equals(listItems.get(i).getStockItems())){
// listView.getChildAt(i).setBackgroundColor(ContextCompat.getColor(context, R.color.hint));
/* Here I want to change list item text color*/
adapter.notifyDataSetChanged();
}
}
}
}
Thanks in advance!
In your model class add one paramter like this
public class DataHolder{
private String StockItems;
private int isSelected;
public DataHolder(String StockItems, int isSelected) {
this.StockItems = StockItems;
this.isSelected = isSelected;
}
public String getStockItems() {
return StockItems;
}
public void setStockItems(String StockItems) {
this.StockItems = StockItems;
}
public int getiIsSelected() {
return isSelected;
}
public void setIsSelected(String isSelected) {
this.isSelected = isSelected;
}
}
initialise IsSelected zero
public void handleResult(String rawResult) {
if(Utility.isNotNull(rawResult.getText().toString())) {
for(int i=0;i<listView.getAdapter().getCount();i++){
if(rawResult.equals(listItems.get(i).getStockItems())){
listItems.get(i).setIsSelected(1);
adapter.notifyDataSetChanged();
}
}
}
}
In your cusom adapter class check
if(listItems.get(i).getiIsSelected()==1)
{
//set red text color
}
else
{
//set black text color
}
UI tasks can only be done on the UI Thread. If u want to run it from the handler, you have to define a runOnUiThread method. Take a look at this ans
how to use runOnUiThread
try this code:
for(int i=0;i<listView.getChildCount();i++) {
// yours code
View item = listView.getChildAt(i);
item.setBackgroundResource(R.drawable.your_image); //change image
((TextView)item.findViewById(R.id.text1)).setTextColor(Color.RED); //text1 is your cusotm listview item's text id
adapter.notifyDataSetChanged();?
}
I assume you use TextView , To change his text color, first you need to get him, when you create your Item, add id to TextView
with xml
<TextView
android:id="#+id/myId"...
Or if you use java
textView.setId(R.id.myId)
and in your code :
((TextView)listView.getChildAt(i).findViewById(R.id.myId)).setTextColor(ContextCompat.getColor(context, R.color.hint));
If you want to set the Item Background with your Drawble Image you can use
.setBackground(getResources().getDrawable(R.drawable.yourDrawble));
Make one method in your Adapter class to update text color and create one flag in Adapter that is initially false ,Use below method to do this
boolean isChangeColor = false;
String colorCode = "#FFFFFF";
private void updateTextColor(boolean isChangeColor , String colorCode) {
this.isChangeColor=isChangeColor;
this.colorCode=colorCode;
notifyDataSetChanged();
}
And in getView()
if(isChangeColor) {
textView.setTextColor(Color.parseColor(colorCode));
} else {
colorCode = "#FFFFFF";
textView.setTextColor(Color.parseColor(colorCode));
}