Am new to Javafx and wondering how to populate a tableview from a 2-dimensional array of String:
String[][] staffArray = (String[][]) connection.getAll("StaffServices");
ObservableList row = FXCollections.observableArrayList(staffArray);
//don't know what should go in here
staffTable.setItems(row);
would really appreciate a response.
I think JavaFX should have a method that just takes 2d arrays and makes tables but it's not that hard to make. The trick is to use the CellValueFactory to get the right array index for each column instead of getting a bean. This is similar to code I use.
import java.util.Arrays;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TableViewSample extends Application {
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
String[][] staffArray = {{"nice to ", "have", "titles"},
{"a", "b", "c"},
{"d", "e", "f"}};
ObservableList<String[]> data = FXCollections.observableArrayList();
data.addAll(Arrays.asList(staffArray));
data.remove(0);//remove titles from data
TableView<String[]> table = new TableView<>();
for (int i = 0; i < staffArray[0].length; i++) {
TableColumn tc = new TableColumn(staffArray[0][i]);
final int colNo = i;
tc.setCellValueFactory(new Callback<CellDataFeatures<String[], String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<String[], String> p) {
return new SimpleStringProperty((p.getValue()[colNo]));
}
});
tc.setPrefWidth(90);
table.getColumns().add(tc);
}
table.setItems(data);
root.getChildren().add(table);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}
Best practices for TableView in JavaFX are to use Objects with Properties and bind them to Columns.
I would suggest moving on or converting your 2 dimensional array to a more Strongly Typed model.
What you are aiming for is to have a ObservableList<Model> that you can then assign to your TableView.
Oracle has a really good introduction to the TableView that show cases the recommendations I suggested.
Additionally to answer of Brian, I added proper CellFactory, to avoid using toString() method, when we are going to view results with good design. My solution is OK, when you are using Model - View - Controller model. Here is the code for Controller block:
#FXML
private TableView<String[]> table = new TableView<>();
#FXML
public void initialize() {
//binding our ObservableList with TableView
String[][] staffArray = {{"a", "b", "c"},
{"d", "e", "f"}};
ObservableList<String[]> data = FXCollections.observableArrayList();
data.addAll(Arrays.asList(staffArray));
for (int i = 0; i < data.get(0).length; i++) {
TableColumn tc = new TableColumn();
tc.setSortable(false);
final int colNo = i;
tc.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<String[], String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<String[], String> p) {
return new SimpleStringProperty((p.getValue()[colNo]));
}
});
tc.setCellFactory(col -> {
TableCell<String[], String> cell = new TableCell<>();
cell.itemProperty().addListener((observableValue, o, newValue) -> {
if (newValue != null) {
Node graphic = createPriorityGraphic(newValue);
cell.graphicProperty().bind(Bindings.when(cell.emptyProperty()).then((Node) null).otherwise(graphic));
}
});
return cell;
});
table.getColumns().add(tc);
}
// making Headers of table hidden
table.widthProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
// Get the table header
Pane header = (Pane) table.lookup("TableHeaderRow");
if (header != null && header.isVisible()) {
header.setMaxHeight(0);
header.setMinHeight(0);
header.setPrefHeight(0);
header.setVisible(false);
header.setManaged(false);
}
}
});
table.setItems(data);
table.setSelectionModel(null);
table.setMaxSize(315.0, 502.0);
}
//prepare some special design for tableview output, if needed
#FXML
private Node createPriorityGraphic(String value) {
if (!value.equals("0") && value != "") {
Rectangle graphic = new Rectangle();
graphic.setHeight(25);
graphic.setWidth(25);
graphic.setOpacity(80);
return graphic;
}
return null;
}
Related
Hi Guys: I´m trying with Uber Clone code and I´m using Netbeans . I have two questions:
1).- In the countryPickerForm Listing 4.12 (The Listing number is the book´s listing "Create an Uber Clone..."); Netbeans marks me an error,("Cannot find symbol variable CommonCode"), of course, in the CommonCode object, i don´t know what library to use
´´´
public class CountryPickerForm extends Form{
//#SuppressWarnings("LeakingThisInConstructor")
public CountryPickerForm(Button sourceButton, Resources Flag){
super(BoxLayout.y());
**CommonCode.initBlackTitleForm(this,"Select a Country", val-> search(val));**
Image blankIcon = Image.createImage(100, 70, 0);
´´´
2).- And the second question: What is te correct place to the Listing (5.22) "Toogling the "WhereTo?" UI when focus changes". I placed it Inside the MapForm class outside from any method, but Neatbeans marks me an error: "< identifier > expected. Ilegal start of type "
This is the code:
from.addFocusListener(new FocusListener(){
public void focusGained(Component cmp){
fromSelected.setIcon(square);
if(layer.getComponentCount()> 1){
Component c = layer.getComponentAt(1);
c.setY(getDisplayHeight());
layer.animateUnlayout(200,150,() ->{
c.remove();
revalidate();
});
}
}
public void focusLost(){
fromSelected.setIcon(circle);
}
});
to.addFocusListener(new FocusListener(){
public void focusGained(Component cmp){
fromSelected.setIcon(circle):
toSelected.setIcon(square);
showToNavigationBar(layer);
}
public void focusLost(Component cmp){
toSelecte3dsetIcon(circle);
}
});
Thanks Guys!!!!
CommonCode was somehow lost in one of the edits to the book. It's a part of the downloadable zip listed at the start of the book and should be there. This is the full listing of that class:
package com.codename1.apps.uberclone.forms;
import com.codename1.apps.uberclone.server.UserService;
import com.codename1.components.MultiButton;
import com.codename1.io.Log;
import com.codename1.ui.Button;
import static com.codename1.ui.CN.*;
import com.codename1.ui.Command;
import com.codename1.ui.Container;
import com.codename1.ui.Display;
import com.codename1.ui.FontImage;
import com.codename1.ui.Form;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.Label;
import com.codename1.ui.TextField;
import com.codename1.ui.Toolbar;
import com.codename1.ui.animations.CommonTransitions;
import com.codename1.ui.animations.Transition;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.plaf.Style;
import com.codename1.util.LazyValue;
import com.codename1.util.SuccessCallback;
import java.io.IOException;
/**
* Common code for construction and initialization of various classes e.g. the side menu logic etc.
*
* #author Shai Almog
*/
public class CommonCode {
private static Image avatar;
public static Image getAvatar(SuccessCallback<Image> avatarChanged) {
if(avatar == null) {
int size = convertToPixels(10);
Image temp = Image.createImage(size, size, 0xff000000);
Graphics g = temp.getGraphics();
g.setAntiAliased(true);
g.setColor(0xffffff);
g.fillArc(0, 0, size, size, 0, 360);
Object mask = temp.createMask();
UserService.fetchAvatar(i -> {
avatar = i.fill(size, size).applyMask(mask);
avatarChanged.onSucess(avatar);
});
if(avatar != null) {
return avatar;
}
Style s = new Style();
s.setFgColor(0xc2c2c2);
s.setBgTransparency(255);
s.setBgColor(0xe9e9e9);
FontImage x = FontImage.createMaterial(FontImage.MATERIAL_PERSON, s, size);
avatar = x.fill(size, size);
if(avatar instanceof FontImage) {
avatar = ((FontImage)avatar).toImage();
}
avatar = avatar.applyMask(mask);
}
return avatar;
}
public static Image setAvatar(String imageFile) {
int size = convertToPixels(10);
Image temp = Image.createImage(size, size, 0xff000000);
Graphics g = temp.getGraphics();
g.setAntiAliased(true);
g.setColor(0xffffff);
g.fillArc(0, 0, size, size, 0, 360);
Object mask = temp.createMask();
try {
Image img = Image.createImage(imageFile);
avatar = img.fill(size, size).applyMask(mask);
} catch(IOException err) {
// this is unlikely as we just grabbed the image...
Log.e(err);
}
return avatar;
}
public static MultiButton createEntry(char icon, String title) {
MultiButton b = new MultiButton(title);
b.setUIID("Container");
b.setUIIDLine1("WhereToButtonLine1");
b.setIconUIID("WhereToButtonIcon");
FontImage.setMaterialIcon(b, icon);
return b;
}
public static MultiButton createEntry(char icon, String title, String subtitle) {
MultiButton b = new MultiButton(title);
b.setTextLine2(subtitle);
b.setUIID("Container");
b.setUIIDLine1("WhereToButtonLineNoBorder");
b.setUIIDLine2("WhereToButtonLine2");
b.setIconUIID("WhereToButtonIcon");
FontImage.setMaterialIcon(b, icon);
return b;
}
public static Label createSeparator() {
Label sep = new Label("", "WhereSeparator");
sep.setShowEvenIfBlank(true);
return sep;
}
public static void constructSideMenu(Toolbar tb) {
Button userAndAvatar = new Button("Shai Almog", "AvatarBlock");
userAndAvatar.setIcon(getAvatar(i -> userAndAvatar.setIcon(i)));
userAndAvatar.setGap(convertToPixels(3));
userAndAvatar.addActionListener(e -> new EditAccountForm().show());
tb.addComponentToSideMenu(userAndAvatar);
MultiButton uberForBusiness = new MultiButton("Do you Uber for business?");
uberForBusiness.setTextLine2("Tap to create your business profile");
uberForBusiness.setUIID("UberForBusinessBackground");
uberForBusiness.setUIIDLine1("UberForBusinessLine1");
uberForBusiness.setUIIDLine2("UberForBusinessLine2");
tb.addComponentToSideMenu(uberForBusiness);
tb.addCommandToSideMenu("Payment", null, e -> {});
tb.addCommandToSideMenu("Your Trips", null, e -> {});
tb.addCommandToSideMenu("Help", null, e -> {});
tb.addCommandToSideMenu("Free Rides", null, e -> {});
tb.addCommandToSideMenu("Settings", null, e -> new SettingsForm().show());
Button legalButton = new Button("Legal", "Legal");
Container legal = BorderLayout.centerCenterEastWest(null, new Label("v4.178.1001", "VersionNumber"), legalButton);
legal.setLeadComponent(legalButton);
legal.setUIID("SideNavigationPanel");
tb.setComponentToSideMenuSouth(legal);
}
/**
* Initializes a form with a black background title animation style
* #param f the form
*/
public static void initBlackTitleForm(Form f, String title, SuccessCallback<String> searchResults) {
Form backTo = getCurrentForm();
f.getContentPane().setScrollVisible(false);
Button back = new Button("", "TitleCommand");
removeTransitionsTemporarily(backTo);
back.addActionListener(e -> backTo.showBack());
back.getAllStyles().setFgColor(0xffffff);
FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK);
f.setBackCommand(new Command("") {
#Override
public void actionPerformed(ActionEvent evt) {
backTo.showBack();
}
});
Container searchBack = null;
if(searchResults != null) {
Button search = new Button("", "TitleCommand");
search.getAllStyles().setFgColor(0xffffff);
FontImage.setMaterialIcon(search, FontImage.MATERIAL_SEARCH);
search.addActionListener(e -> {
});
searchBack = BorderLayout.north(
BorderLayout.centerEastWest(null, search, back));
} else {
searchBack = BorderLayout.north(
BorderLayout.centerEastWest(null, null, back));
}
Label titleLabel = new Label(title, "WhiteOnBlackTitle");
titleLabel.getAllStyles().setMarginTop(back.getPreferredH());
titleLabel.getAllStyles().setMarginUnit(Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS);
f.getToolbar().setTitleComponent(LayeredLayout.encloseIn(searchBack, titleLabel));
f.getAnimationManager().onTitleScrollAnimation(titleLabel.createStyleAnimation("WhiteOnBlackTitleLeftMargin", 200));
f.setTransitionInAnimator(CommonTransitions.createCover(CommonTransitions.SLIDE_VERTICAL, false, 300));
f.setTransitionOutAnimator(CommonTransitions.createUncover(CommonTransitions.SLIDE_VERTICAL, true, 300));
}
public static void removeTransitionsTemporarily(final Form f) {
final Transition originalOut = f.getTransitionOutAnimator();
final Transition originalIn = f.getTransitionInAnimator();
f.setTransitionOutAnimator(CommonTransitions.createEmpty());
f.setTransitionInAnimator(CommonTransitions.createEmpty());
f.addShowListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
f.setTransitionOutAnimator(originalOut);
f.setTransitionInAnimator(originalIn);
f.removeShowListener(this);
}
});
}
}
The second listing appears in MapForm in showNavigationToolbar. This code goes through some additional refactoring later on and looks like this:
void showNavigationToolbar() {
final Container layer = getLayeredPane(MapForm.class, true);
final Container pinLayer = createPinLayer(layer);
Button back = new Button("", "TitleCommand");
FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK);
CompletionContainer cc = new CompletionContainer();
AutoCompleteAddressInput from = new AutoCompleteAddressInput("Current Location", "From", layer, cc);
AutoCompleteAddressInput to = new AutoCompleteAddressInput("", "Where To?", layer, cc);
from.setCurrentLocation(LocationService.getCurrentLocation());
Image circle = createCircle();
Label fromSelected = new Label(circle);
Label toSelected = new Label(square);
SearchService.nameMyCurrentLocation(LocationService.getCurrentLocation(), name -> from.setTextNoEvent(name));
to.requestFocus();
lastFocused = to;
from.addFocusListener(createFromFocusListener(fromSelected, from, circle));
to.addFocusListener(createToFocusListener(fromSelected, circle, toSelected, to));
addMapListener((source, zoom, center) -> onMapChangeEvent(center));
Container navigationToolbar = BoxLayout.encloseY(back,
BorderLayout.centerCenterEastWest(from, null, fromSelected),
BorderLayout.centerCenterEastWest(to, null, toSelected)
);
navigationToolbar.setUIID("WhereToToolbar");
navigationToolbar.getUnselectedStyle().setBgPainter((g1, rect) ->
paintWhereToToolbarBackground(g1, layer, rect, fromSelected, circle, toSelected)
);
cc.addCompletionListener(e ->
onCompletionEvent(to, from, pinLayer, navigationToolbar, layer));
back.addActionListener(e ->
onBackFromNavigation(pinLayer, navigationToolbar, layer));
layer.add(NORTH, navigationToolbar);
navigationToolbar.setWidth(getDisplayWidth());
navigationToolbar.setHeight(getPreferredH());
navigationToolbar.setY(-navigationToolbar.getHeight());
getAnimationManager().addAnimation(layer.createAnimateLayout(200),
() -> cc.showCompletionBar(layer));
}
private FocusListener createToFocusListener(final Label fromSelected, Image circle, final Label toSelected, AutoCompleteAddressInput to) {
return new FocusListener() {
#Override
public void focusGained(Component cmp) {
fromSelected.setIcon(circle);
toSelected.setIcon(square);
lastFocused = to;
}
#Override
public void focusLost(Component cmp) {
toSelected.setIcon(circle);
}
};
}
private FocusListener createFromFocusListener(final Label fromSelected, AutoCompleteAddressInput from, Image circle) {
return new FocusListener() {
#Override
public void focusGained(Component cmp) {
fromSelected.setIcon(square);
lastFocused = from;
}
#Override
public void focusLost(Component cmp) {
fromSelected.setIcon(circle);
}
};
}
Current out put of code is output image
import java.io.Serializable;
import java.util.HashMap;
import java.util.Objects;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.part.ViewPart;
public class Theartview extends ViewPart implements Serializable {
Table table;
private TableViewer tableViewer;
public void createPartControl(Composite parent) {
System.out.println("createPartControl call");
Composite tableComposite = new Composite(parent, SWT.NONE);
TableColumnLayout tableColumnLayout = new TableColumnLayout();
tableComposite.setLayout(tableColumnLayout);
tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
true));
tableViewer = new TableViewer(tableComposite, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL);
tableViewer.setContentProvider(ArrayContentProvider.getInstance());
// TODO viewer.setLabelProvider(new ViewLabelProvider());
table = tableViewer.getTable();
// Table table = tableViewer.getTable();
System.out.println("#############table$$$$$$$$" + table);
table.setHeaderVisible(true);
table.setLinesVisible(true);
String[] titles = { "Threat Name", "Category Name", "Status",
"Priority", "Description", "Justification" };
for (int loopIndex = 0; loopIndex < titles.length; loopIndex++) {
TableViewerColumn tableViewerColumn = new TableViewerColumn(
tableViewer, SWT.NONE);
TableColumn tblclmn = tableViewerColumn.getColumn();
tableColumnLayout.setColumnData(tblclmn, new ColumnPixelData(200,
true, true));
tblclmn.setText(titles[loopIndex]);
}
}
private static class Dummy {
public String value;
public Dummy(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
#SuppressWarnings("static-access")
public void fillTableRoWData() {
System.out.println("After connection fillTableRoWData call");
System.out.println("No of Connected object = no of fillTableRoWData call ");
if (Connection.Number_Of_Connection != 0) {
// item = new TableItem(table, SWT.NONE);
if (Service.class.isInstance(sourceNode)) {
String id = "S1";
shortDescription = threattypexmltoobject.shortdescription(id,
sourceNode.getName(), targetNode.getName(), null);
category = "Spoofing";
description = threattypexmltoobject.longdescription(id,
sourceNode.getName(), targetNode.getName(), null);
fillRows(shortDescription, category, description);
}
if (Service.class.isInstance(sourceNode)
&& (connectionType == Connection.CONNECTION_DESIGN)) {
String id = "T1";
System.out.println(conn.getConnectionDesign());
shortDescription = threattypexmltoobject.shortdescription(id,
sourceNode.getName(), targetNode.getName(),
conn.getConnectionDesign());
category = "Tampering";
description = threattypexmltoobject.longdescription(id,
sourceNode.getName(), targetNode.getName(),
conn.getConnectionDesign());
fillRows(shortDescription, category, description);
}
}
private void fillRows(String shortdesc, String categ, String descp) {
System.out.println("fillRows call from above method.");
TableItem item = new TableItem(table, SWT.NONE);
// for Threat_Name
item.setText(0, "x");
// For Category_Name
item.setText(1, "y");
// For Status_Name
item.setText(2, "z");
// For Priority_Name
item.setText(3, "a");
// For Descrption_Name
item.setText(4, "b");
// For justification
item.setText(5, "c");
}
public static class FirstValueEditingSupport extends EditingSupport {
private final TableViewer viewer;
private final CellEditor editor;
private final String[] possibleValues = { "Mitigated",
"Not Applicable", "Not Started", "Needs Investigation" };
public FirstValueEditingSupport(TableViewer viewer) {
super(viewer);
this.viewer = viewer;
this.editor = new ComboBoxCellEditor(viewer.getTable(),
possibleValues);
}
#Override
protected CellEditor getCellEditor(Object element) {
return editor;
}
#Override
protected boolean canEdit(Object element) {
return true;
}
#Override
protected Object getValue(Object element) {
Dummy dummy = (Dummy) element;
int index = 0;
for (int i = 0; i < possibleValues.length; i++) {
if (Objects.equals(possibleValues[i], dummy.getValue())) {
index = i;
break;
}
}
return index;
}
#Override
protected void setValue(Object element, Object value) {
Dummy dummy = (Dummy) element;
int index = (Integer) value;
dummy.setValue(possibleValues[index]);
viewer.update(element, null);
}
}
}
Questions
How to set combo box in the 3rd and 4th column of table viewer. here FirstValueEditingSupport is combobox options value which is display comobo dropdown
String shortDescription, set into 1st and 2ed column how to set ?
in Output image "Status" and "Priority", which is column name of the table where set combo box in the table.
Please only ask one question in a question.
You set the editing support in the TableColumnViewer for the column you want to edit. So for the columns you want to edit do:
tableViewerColumn.setEditingSupport(new FirstValueEditingSupport());
To set the data shown in each column you set a label provider of the column.
tableViewerColumn.setLabelProvider(column label provider);
where the label provider is derived from CellLabelProvider or one of its many subclasses.
Note: NEVER set the table viewer contents by creating TableItems - you must always use a content provider and a setInput call on the table viewer. TableViewer is in complete control of the underlying Table and is free to discard any TableItems you may create. With very few exceptions you should never be looking at the Table or TableItem objects when using TableViewer.
The content provider should provide one object for each row in the table, the column label providers should use this row object to get labels for the individual columns.
I want to create a simple table with multiple selection using checkboxes on the first column.
I've created a custom "TableColumn" to handle this feature in every table I need. I've implemented all the features except one: when I select or deselect a single row the corresponding checkbox on the first colum must be selected or unselected. I need help to develop this last function.
public class ColumnSelectRow extends TableColumn{
private CheckBox headerCheckBox = new CheckBox();
public ColumnSelectRow(String title) {
super(title);
setSortable(false);
setPrefWidth(100);
setMaxWidth(100);
setMinWidth(100);
setResizable(false);
setGraphic(headerCheckBox);
setCellValueFactory( new Callback<TableColumn.CellDataFeatures<Object, Boolean>, ObservableValue<Boolean>>() {
#Override
public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Object, Boolean> p) {
return new SimpleBooleanProperty(p.getValue() != null);
}
});
setCellFactory(new Callback<javafx.scene.control.TableColumn<Object, Boolean>, TableCell<Object, Boolean>>() {
#Override
public TableCell<Object, Boolean> call(javafx.scene.control.TableColumn<Object, Boolean> p) {
return new SelectButtonCell();
}
});
headerCheckBox.setOnAction(t->{
if(disableEvents) return;
TableView table = ColumnSelectRow.this.getTableView();
if (table == null) return;
if(headerCheckBox.isSelected()) table.getSelectionModel().selectAll();
else table.getSelectionModel().clearSelection();
});
}
public CheckBox getHeaderCheckBox() {
return headerCheckBox;
}
private boolean disableEvents = false;
private class SelectButtonCell extends TableCell {
private final CheckBox checkBox = new CheckBox();
public SelectButtonCell(){
setAlignment(Pos.CENTER);
checkBox.setOnAction(t -> {
int row = getTableRow().getIndex();
TableView table = SelectButtonCell.this.getTableView();
if (table == null) return;
if(checkBox.isSelected()) table.getSelectionModel().select(row);
else table.getSelectionModel().clearSelection(row);
table.getFocusModel().focus(row);
boolean empty = table.getSelectionModel().isEmpty();
boolean full = table.getSelectionModel().getSelectedCells().size()==table.getItems().size();
disableEvents = true;
headerCheckBox.setIndeterminate(false);
if(empty) headerCheckBox.setSelected(false);
else if(full) headerCheckBox.setSelected(true);
else headerCheckBox.setIndeterminate(true);
disableEvents = false;
});
}
public CheckBox getCheckBox() {
return checkBox;
}
#Override
protected void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if(!empty){
setGraphic(checkBox);
}
int row = getTableRow().getIndex();
TableView table = SelectButtonCell.this.getTableView();
checkBox.setSelected(table.getSelectionModel().isSelected(row));
}
public boolean isCheckBoxSelected(){
return checkBox.isSelected();
}
}
thanks!!
Edit: a custom table with the first column selectable
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class MyTable extends Application {
private ColumnSelectRow columSelect;
#Override
public void start(Stage primaryStage) throws Exception {
columSelect = new ColumnSelectRow();
TableView T = new TableView<>();
T.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
ObservableList<myObject> al = FXCollections.observableArrayList();
al.add(new myObject(1));
al.add(new myObject(2));
al.add(new myObject(3));
T.setItems(al);
T.getColumns().add(columSelect);
TableColumn<myObject, Number> number = new TableColumn("Number");
number.setCellValueFactory(cellData->cellData.getValue().propetry);
T.getColumns().add(number);
Scene scene = new Scene(T);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private class myObject{
public SimpleIntegerProperty propetry = new SimpleIntegerProperty();
public myObject(int i) {
propetry.set(i);
}
}
}
I'm still new to JavaFX and need to create a combobox with objects (SimlpePerson) and not strings. I want to edit the shown value in the box itself. Works good for strings but I have problems with SimpleObjects. I made a StringConverter and it also works, I can edit the object shown in the comboBox. But the list itself is not rerendered after that. If I click on the ComboBox I see the original values. How can I change that?
Any suggestion is very welcome!=)
BR and Thank you!
Stefan
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class ComboBoxDemo extends Application{
public class SimplePerson {
private StringProperty name;
private String somethingElse;
public SimplePerson(String name) {
setName(name);
}
public final void setName(String value) { nameProperty().set(value); }
public String getName() { return nameProperty().get(); }
public StringProperty nameProperty() {
if (name == null) name = new SimpleStringProperty(this, "name");
return name;
}
}
final ObservableList<SimplePerson> persons = FXCollections.observableArrayList(
new SimplePerson("Jacob"),
new SimplePerson("Isabella"),
new SimplePerson("Ethan"),
new SimplePerson("Emma"),
new SimplePerson("Michael")
);
#Override
public void start(Stage stage) throws Exception {
// TODO Auto-generated method stub
final ComboBox cb = new ComboBox();
cb.setItems(persons);
cb.setEditable(true);
cb.setConverter(new StringConverter<SimplePerson>() {
#Override
public String toString(SimplePerson p)
{
if(p != null)
return p.getName();
return "";
}
#Override
public SimplePerson fromString(String name)
{
if(cb.getValue() != null)
{
((SimplePerson)cb.getValue()).setName(name);
cb.show();
return (SimplePerson)cb.getValue();
}
return null;
}
});
stage.setScene(new Scene(cb));
stage.show();
}
public static void main(String[] args) { launch(args); }
}
Check out this solution. There is a handler which is triggered when you've finished editing. There you may implement all the code which changes the model's state.
To update the combobox list the following approach work may:
cb.getEditor().setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
SimplePerson person = cb.getValue();
if (null != person) {
int idx = persons.indexOf(person);
person.setName(cb.getEditor().getText());
persons.set(idx, person);
cb.setValue(person);
}
}
});
Combobox1 has 3 items (Spain, France, UK) and Combobox2 6 items (Barcelona, Madrid, Paris, Marseille, London, Bristol).
When one item is selected from Combobox1 (Spain) it should be available to Combobox2 the specific items (Barcelona, Madrid).
Can anyone help me with this?
Thanks in advance
Three combox listener example code.i think this solution use ful for your.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package threecombobox;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
/**
*
* #author reegan
*/
public class ThreeComboBox extends Application {
#Override
public void start(Stage primaryStage) {
List combox1List = new ArrayList();
for (int i = 1; i < 10; i++) {
combox1List.add(i);
}
final Map combox2Map = new HashMap();
for (int i = 0; i < combox1List.size(); i++) {
List l = new ArrayList();
for (int j = 1; j < 10; j++) {
int k = (int) combox1List.get(i) * 10 + j;
l.add(k);
}
combox2Map.put(combox1List.get(i), l);
}
final Map combox3Map = new HashMap();
for (Object o : combox1List) {
for (Object o1 : (List) combox2Map.get(o)) {
List l = new ArrayList();
for (int i = 1; i < 10; i++) {
int value = (int) o1 * 10 + i;
l.add(value);
}
combox3Map.put(o1, l);
}
}
ObservableList combox1 = FXCollections.observableList(combox1List);
HBox box = new HBox(20);
box.setPadding(new Insets(20, 20, 20, 20));
ComboBox cb1 = new ComboBox();
final ComboBox cb2 = new ComboBox();
final ComboBox cb3 = new ComboBox();
cb1.setItems(combox1);
cb1.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
#Override
public void changed(ObservableValue ov, Object t, Object t1) {
ObservableList combox2 = FXCollections.observableArrayList((List) combox2Map.get(t1));
cb2.setItems(combox2);
}
});
cb2.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
#Override
public void changed(ObservableValue ov, Object t, Object t1) {
if (t1 != null) {
ObservableList combox3 = FXCollections.observableArrayList((List) combox3Map.get(t1));
cb3.setItems(combox3);
}
}
});
box.getChildren().addAll(cb1, cb2, cb3);
Scene scene = new Scene(box, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Well, we don't know your data structure, but if a city is attached to a country, add a listener to your country combobox and each time the selection change, you reconfigure the items on the city combobox.
I'll do something like that :
ComboBox<City> cityBox;
ComboBox<Country> countryBox;
countryBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
#Override
public void changed(ObservableValue observableValue, Country oldCountry, Country newCountry) {
//Here configure your cityBox corresponding with newCountry
}
});
or with binding
cityBox.itemsProperty().bind(new ListBinding<City>() {
{
bind(cityBox.getSelectionModel().selectedItemProperty());
}
#Override
protected ObservableList<City> computeValue() {
Country country = countryBox.getValue();
// add the city corresponding to the country on a new list
return //The list with the city filtered with the country
}
});