I encountered problem I am unable to solve. Thing is, my TableView is already populated and I need for cells that match my criteria to set value zero. I have variable korZemljiste and if my condition is fullfilled cells in column colOsnovica need to be set to value 0.00.
Here is what I tried:
if (korZemljiste < 10000)
{
tblTabela.getItems().stream().forEach((o)
-> {
colOsnovica.setCellFactory(TextFieldTableCell.forTableColumn());
colOsnovica.setOnEditCommit(
new EventHandler<CellEditEvent<Nepokretnost, Number>>() {
#Override
public void handle(CellEditEvent<Nepokretnost, Number> t) {
((Nepokretnost) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setOsnovica(t.getNewValue());
}
});});}
Sorry, for ugly end of code, couldn't make to copy it properly.
This part I modified from Oracle example and I get error:
error: incompatible types: no instance(s) of type variable(s) S exist so that Callback<TableColumn<S,String>,TableCell<S,String>> conforms to Callback<TableColumn<Nepokretnost,Number>,TableCell<Nepokretnost,Number>>
colOsnovica.setCellFactory(TextFieldTableCell.forTableColumn());
where S is a type-variable:
S extends Object declared in method forTableColumn()
error: incompatible types: Number cannot be converted to double
).setOsnovica(t.getNewValue());
My TableView using <Nepokretnost, Number> form.
Note: I guess I don't need this example from Oracle site because I don't want to manually change contents of cell in column, I just want to set them to value 0.00.
Some easy solution anyone?
Thanks in advance.
For the first error, since your table column type is not a String, you cannot use the no-argument version of TextFieldTableCell.forTableColumn(). The underlying problem is that, to edit the cell, the text field provides a String and the data in the cell is a Number. You need to provide a converter, using the overloaded form of TextFieldTableCell.forTableColumn(...):
colOsnovica.setCellFactory(TextFieldTableCell.forTableColumn(new NumberStringConverter()));
For the second error, just replace t.getNewValue() (which returns a Number) with t.getNewValue().doubleValue() (which gets the double representation of the Number).
#james-d
Hm, my mistake. Class is simple, here it is:
package obracun;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
/**
*
* #author Dalibor
*/
public class Nepokretnost {
private final SimpleStringProperty tipNepokretnosti;
private final SimpleStringProperty zona;
private final SimpleStringProperty pravo;
private final SimpleDoubleProperty povrsina;
private final SimpleDoubleProperty amortizacija;
private final SimpleDoubleProperty osnovica;
private final SimpleDoubleProperty kredit;
private final SimpleDoubleProperty porez;
public Nepokretnost(String tipNepokretnosti, String zona, String pravo,
Double povrsina, double amortizacija, Double osnovica, Double kredit, Double porez) {
this.tipNepokretnosti = new SimpleStringProperty(tipNepokretnosti);
this.zona = new SimpleStringProperty(zona);
this.pravo = new SimpleStringProperty(pravo);
this.povrsina = new SimpleDoubleProperty(povrsina);
this.amortizacija = new SimpleDoubleProperty(amortizacija);
this.osnovica = new SimpleDoubleProperty(osnovica);
this.kredit = new SimpleDoubleProperty(kredit);
this.porez = new SimpleDoubleProperty(porez);
}
public String getTipNepokretnosti() {
return tipNepokretnosti.get();
}
public void setTipNepokretnosti(String tipNepokretnosti) {
this.tipNepokretnosti.set(tipNepokretnosti);
}
public String getZona() {
return zona.get();
}
public void setZona(String zona) {
this.zona.set(zona);
}
public String getPravo() {
return pravo.get();
}
public void setPravo(String pravo) {
this.pravo.set(pravo);
}
public double getPovrsina() {
return povrsina.get();
}
public void setPovrsina(double povrsina) {
this.povrsina.set(povrsina);
}
public double getAmortizacija() {
return amortizacija.get();
}
public void setAmortizacija(double amortizacija) {
this.amortizacija.set(amortizacija);
}
public double getOsnovica() {
return osnovica.get();
}
public void setOsnovica(double osnovica) {
this.osnovica.set(osnovica);
}
public double getKredit() {
return kredit.get();
}
public void setKredit(double kredit) {
this.kredit.set(kredit);
}
public double getPorez() {
return porez.get();
}
public void setPorez(double porez) {
this.porez.set(porez);
}
}
I didn't realized it is necessary to post class here. I had this application made before just in Swing. There I just changed contents of JTableView field. This is kinda different, thanks for help.
I posted and screenshot of app. On screenshot I already added elements in TableView I wanted. Code I posted in question is part of Calculate (Обрачун) button event handler. In this example calculation should change the contents of field Основица to 0.00.
Related
I'm new to Java programming, sorry if this is a dumb question.
I find it hard to word this question properly, but I have an assignment to create a aircraft class that can make aircraft land, takeoff etc. And need to test it using Testclass. When the new object are entered it automatically assigns a unique ID to the aircraft in the constructor.
I can do this using a instance method fine as it has a return value which is returned to to Testclass. The question wants me to do this in the constructor itself, however, the constructor never returns anything. So the variable never gets sent to the Testclass. I clearly am not understanding OOP properly. Even when I try to just use a getter method to get the ID created in the constructor it gives me the initialized variable before the the constructor has worked on this. This is the code I have so far and its completely wrong I know but if someone could point me in the right direction or tell me how to word this question better it would be a massive help.
// I need to enter 3 aircraft into the system in the testclass
public class Aircraft {
private int aircraftID;
private static int lastID;
private String airportcode;
private int ID = 100;
private int count;
public Aircraft(int a, int b, int c){
// Constructor
// Assign ID
this.ID = a;
lastID = ID;
ID++;
this.ID =b;
lastID = ID;
ID++;
}
}
OK, you want to create an Aircraft that has an automatically-assigned unique identifier, and can take off and land. That implies you need a field for tracking the identifier, a field for tracking whether it's in the air (or not), and methods for the take off and land operations. You also need a static field for generating the unique identifiers. (Note that this implementation isn't thread safe.)
private class Aircraft {
private static int staticId = 0;
private int uniqueId = 0;
private boolean onGround = true; // Aircraft start on the ground in this implementation
public Aircraft(){
this.uniqueId = staticId; // putting this line first makes uniqueId zero-indexed in effect
staticId++;
}
public void land(){
onGround = true;
}
public void takeoff(){
onGround = false;
}
public boolean isFlying(){
return !onGround; // If it's not on the ground, it's flying
}
public int getUniqueId(){
return uniqueId;
}
}
Unit tests checks all of the methods and expected functionality of the class in question:
import org.junit.Test;
import static org.junit.Assert.*;
import Aircraft;
class Testclass {
private final Aircraft aircraft = new Aircraft();
#Test
public void hasId(){
aircraft.getUniqueId() >= 0;
}
#Test
public void canLand(){
assertTrue(aircraft.land());
}
#Test
public void canTakeOff(){
assertTrue(aircraft.takeOff());
}
#Test
public void checkFlightOperationsAreTrackedCorrectly(){
aircraft.land();
assertFalse(aircraft.isFlying());
aircraft.takeOff();
assertTrue(aircraft.isFlying());
}
}
As pointed out a constructor does not return anything (the simplified version is that with new it returns an object instance). I am kinda guessing at what you are trying to acomplish, but I'll have a go anyways. It seems to me that you are trying to cram the construction of 3 objects into one constructor - which is why your constructor has 3 parameters. Also you are playing havoc with the IDs.
I have removed all the variables that I didnt quite understand, leaving only ID that increments with each instantiated Aircraft. The #Override is mainly just for show.
public class Aircraft {
private int aircraftID;
private static int lastID = 0;
#Override
public String toString(){
return "Aircraft_" + this.aircraftID;
}
public Aircraft() {
lastID++;
this.aircraftID = lastID;
}
}
I took the liberty and wrote the TestClass just to see if we have the same thing in mind. Again the printAircraft() method is for show.
public class TestClass {
private List<Aircraft> aircrafts;
public TestClass(){
aircrafts = new ArrayList<>();
}
public void addAircraft(Aircraft a){
aircrafts.add(a);
}
public void printAircraft(){
Iterator<Aircraft> it = aircrafts.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
and to test it, we create and instance of TestClass add 3 Aircraft instances and print out the contents
public static void main(String[] args) {
TestClass tc = new TestClass();
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.printAircraft();
}
This would be the case if you are to write the TestClass. If that is given, it would help to know what it looks like - maybe that would help us understand better.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm trying to create a Java program that manage a booking ticket system.
I have a film Class:
public class Film {
private String title;
private Double price;
private String ageRestriction;
private double rating;
private String genre;
private String location;
private String screenDay;
A FilmList Class that create an ArrayList of Films item and sort, based by two parameters (Location and Week)
public class FilmList {
public FilmList(ArrayList<Film> filmArrayList) {
this.filmArrayList = filmArrayList;
}
public FilmList (){
this.filmArrayList = new ArrayList<>();
}
public ArrayList <Film> filmArrayList;
public void addFilm(Film films){
this.filmArrayList.add(films);
}
private String showLocation;
private String screenWeek;
public void setScreenWeek(String screenDay) {
this.screenWeek = screenDay;
}
public String getScreenWeek() {
return screenWeek;
}
public void setShowLocation(String location) {
this.showLocation = showLocation;
}
public String getShowLocation() {
return showLocation;
}
public Optional<Film> searchFilm(){
Optional<Film> movieFounded = filmArrayList.stream().filter(i -> i.getLocation().contains(getShowLocation()) &&
i.getScreenDay().contains(getScreenWeek())).findAny();
return movieFounded;
}
The setShowLocation parameter it's stetted by the click of a button (there's one of them for each theatre, and the setScreenWeek it's stetted by a Combobox
the Graphic unit interface with the console. Notice that if I press the button without select anything on the combobox I got an error.
So
FilmList filmList = new FilmList();
filmList.addFilm
System.out.println(searchFilm().toString());
Your code is a bit strange, but I suppose you meant passing a Film instance to addFilm, and then using filmList.searchFilm().
Anyway
filter(
i -> i.getLocation().contains(getShowLocation()) &&
i.getScreenDay().contains(getScreenWeek())
)
Here you're filtering the filmArrayList, which contains a single element at that point. And
i.getLocation().contains(getShowLocation())
means basically
i.getLocation().contains(null)
as the showLocation field isn't initialized.
The same applies for the second condition, using screenWeek.
I'm actually surprised it doesn't throw a NullPointerException, as
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1; // NullPointerException at s.toString()
}
But anyway, let's say you initialized those fields, then the only element is discarded by the filter operation, that's why you see Optional.empty.
final FilmList filmList = new FilmList();
filmList.setShowLocation("Your location");
filmList.setScreenWeek("Screen week");
filmList.addFilm(filmInstance);
System.out.println(filmList.searchFilm().toString());
You obviosly need a fully constructed Film instance
final Film filmInstance = new Film();
filmInstance.title = "The NullPointerException adventure";
filmInstance.price = 12D;
filmInstance.ageRestriction = "+18";
filmInstance.rating = 18D;
filmInstance.genre = "Horror";
filmInstance.location = "US";
filmInstance.screenDay = "Monday";
filmList.addFilm(filmInstance);
The problem is in the FilmList#setShowLocation method.
You're assigning showLocation to itself, and the location parameter is unused.
public void setShowLocation(String location) {
this.showLocation = showLocation;
}
This should be
public void setShowLocation(String location) {
this.showLocation = location;
}
I've got a project written in JavaFX and I'm trying to get a refresh on a tableview without result.
I've googled around and tried some examples I've found but it still doesn't work.
I populate a tableview with information each row in this table can have new comments added to by double click on the row. The a new Tabpane is opened and the new comment can be added there. On close of this tabpane I'd like the one I clicked from to be refreshed.
I must be doing something wrong. I just don't know what.
In my StoreController
private void populateTableView(List<Store> stores) {
ObservableList<Store> data = FXCollections.observableArrayList(stores);
storeNumberColumn.setCellValueFactory(
new PropertyValueFactory<Store, String>("id"));
storePhoneColumn.setCellValueFactory(
new PropertyValueFactory<Store, String>("phoneNbr"));
chainColumn.setCellValueFactory(
new PropertyValueFactory<Store, String>("chainId"));
commentColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Store, ImageView>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Store, ImageView> p) {
Integer numberOfComments = p.getValue().getCommentsCount();
ReadOnlyObjectWrapper wrapper = null;
if (numberOfComments == 0) {
wrapper = null;
} else if (numberOfComments == 1) {
wrapper = new ReadOnlyObjectWrapper(new ImageView(COMMENT_SINGLE_FLAG_SOURCE));
} else {
wrapper = new ReadOnlyObjectWrapper(new ImageView(COMMENT_DOUBLE_FLAG_SOURCE));
}
return wrapper;
}
});
storeTable.setItems(data);
sortTable(storeTable, missedColumn);
}
#FXML
public void handleTableAction(MouseEvent event) {
if (event.getClickCount() == 2) {
showNewCommentStage();
}
}
private void showNewCommentStage() {
initCommentController();
Store store
= storeTable.getSelectionModel().selectedItemProperty().getValue();
commentController.showNewStage(commentPane, store);
}
It seems like the call-function doesn't get called when the commentpane is closed.
CommentController
public void showNewStage(Pane pane, Store store) {
this.store = store;
initStage(pane);
windowHandler = new WindowHandler(stage);
effectHandler.playEffect(pane);
constructCommentHeaders();
List<Comment> comments;
comments = commentService.listByStoreId(store.getId());
populateCommentTable(comments);
}
Like I said I've tried a lot of the solutions found here on Stackoverflow but with no results. The Tableview doesn't refresh. The Stores and the Comments are in different database tables if that's important
Can someone point me in the right direction?
Thanks!
****EDIT****
The Store.class
public class Store extends CommentEntity {
private String id;
private String chainId;
private String phoneNbr;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getChainId() {
return chainId;
}
public void setChainId(String chainId) {
this.chainId = chainId;
}
public String getPhoneNbr() {
return phoneNbr;
}
public void setPhoneNbr(String phoneNbr) {
this.phoneNbr = phoneNbr;
}
#Override
public String toString() {
return "Store{" + "id=" + id + ", chainId=" + chainId + '}';
}
#Override
public String getCommentIdentifier() {
return id;
}
}
The CommentEntity.Class
public abstract class CommentEntity {
private int commentsCount;
public int getCommentsCount() {
return commentsCount;
}
public void setCommentsCount(int commentsCount) {
this.commentsCount = commentsCount;
}
public abstract String getCommentIdentifier();
}
Thank you for input, I hadn't even reflected over the ImageView / String.
Two issues:
First, you need to distinguish between the data the cells in your column are displaying, and the cells that actually display those data. The cellValueFactory determines the data that are displayed. The PropertyValueFactory is a cellValueFactory implementation that references a JavaFX Property, so when you call
storeNumberColumn.setCellValueFactory(new PropertyValueFactory<Store, String>("id"));
it effectively tells the cells in the storeNumberColumn to call the idProperty() method on the Store object in the current row to get the data for the cell. (If no such method exists, it will try to use getId() as a backup plan.)
By default, you get a cellFactory that displays text resulting from calling toString() on the data generated by the cellValueFactory. In the case where your data are simply Strings, this is usually what you need. In other cases, you often need to provide a cellFactory of your own to get the correct way to display the data.
In your case, the data for the commentColumn are simply the number of comments. You are going to display that by choosing an image based on that numeric value.
So you should have
TableColumn<Store, Number> commentColumn = new TableColumn<>("Comments");
For the cellValueFactory, you can just use
commentColumn.setCellValueFactory(new PropertyValueFactory<>("commentsCount"));
Then you need a cellFactory that displays the appropriate ImageView:
commentColumn.setCellFactory(new Callback<TableColumn<Store, Number>, new TableCell<Store, Number>>() {
#Override
public TableCell<Store, Number>() {
private ImageView imageView = new ImageView();
#Override
public void updateItem(Number numberOfComments, boolean empty) {
super.updateItem(count, empty) ;
if (empty) {
setGraphic(null);
} else {
if (numberOfComments.intValue() == 0) {
setGraphic(null);
} else if (numberOfComments.intValue() == 1) {
imageView.setImage(new Image(COMMENT_SINGLE_FLAG_SOURCE));
setGraphic(imageView);
} else {
imageView.setImage(new Image(COMMENT_DOUBLE_FLAG_SOURCE));
setGraphic(imageView);
}
}
}
}
});
The second issue is actually about the update. A TableView keeps its contents "live" by observing JavaFX properties that are provided by the cellValueFactory as ObservableValues. If the value might change while the table is displayed, you must provide an actual property that can be observed: using a ReadOnlyObjectWrapper is no good (because it's read only, so it's wrapped value will not change). The PropertyValueFactory will also return a ReadOnlyObjectWrapper if you do not have JavaFX property accessor methods (i.e. if it is only using getXXX() methods to access the data). So your model class must provide JavaFX Properties.
You can make an immediate fix to this by updating CommentEntity to use an IntegerProperty:
public abstract class CommentEntity {
private final IntegerProperty commentsCount = new SimpleIntegerProperty();
public final int getCommentsCount() {
return commentsCountProperty().get();
}
public final void setCommentsCount(int commentsCount) {
commentsCountProperty().set(commentsCount);
}
public IntegerProperty commensCountProperty() {
return commentsCount ;
}
public abstract String getCommentIdentifier();
}
I would also strongly recommend updating the Store class to use JavaFX Properties in a similar manner.
i have the following problem: I read out database items in an observable list. Now I want to display some items from the selected line in a few textfields on the right side of my tableview.
I got the observable-line-index with the following code, but I want to select an other column of the line.
AnalysemethodenTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
public void changed(ObservableValue<?> observable, Object oldvalue, Object newValue) {
index.set(analysemethodendata.indexOf(newValue));
databaseIndex = (analysemethodendata.indexOf(newValue) + 1);
System.out.println("Index:\t" + databaseIndex);
}
});
I found the following code: Click
But i don't understand this. It's something like to write a new list and place a copy of the items of the observable list in this new list.
I think, if I have the index of the line with my code, I can select the other items in the line of the observable list, too (I thought like "x,y" like an array)
If i cast it to String, the output is only machine code.
Hope I can understand the solution with your help!
EDIT: I inserted the following code:
System.out.println(analysemethodendata.get(databaseIndex).toString());
But I only get machine code in my Output:
table.analysemethoden_table#63c0d5b7
EDIT 2:
Table-Controller-Code:
package table;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleStringProperty;
public class analysemethoden_table {
private final SimpleStringProperty rAmnorm;
private final SimpleStringProperty rMethverantw;
private final SimpleFloatProperty rBestimmungsgrenze;
private final SimpleFloatProperty rNachweisgrenze;
public analysemethoden_table (String sAmnorm, String sMethoverantw, Float sBestimmungsgrenze, Float sNachweisgrenze) {
this.rAmnorm = new SimpleStringProperty(sAmnorm);
this.rMethverantw = new SimpleStringProperty(sMethoverantw);
this.rBestimmungsgrenze = new SimpleFloatProperty(sBestimmungsgrenze);
this.rNachweisgrenze = new SimpleFloatProperty(sNachweisgrenze);
}
// Getter- und Setter-Methoden
/** rAmnorm **/
public String getRAmnorm() {
return rAmnorm.get();
}
public void setRAmnorm(String set) {
rAmnorm.set(set);
}
/** rMethverantw **/
public String getRMethverantw() {
return rMethverantw.get();
}
public void setRMethverantw(String set) {
rMethverantw.set(set);
}
/** rBestimmungsgrenze **/
public Float getRBestimmungsgrenze() {
return rBestimmungsgrenze.get();
}
public void setRBestimmungsgrenze(Float set) {
rBestimmungsgrenze.set(set);
}
/** rNachweisgrenze **/
public Float getRNachweisgrenze() {
return rNachweisgrenze.get();
}
public void setRNachweisgrenze(Float set) {
rNachweisgrenze.set(set);
}
}
You need to use
analysemethodendata.get(databaseIndex).getRAmnorm();
or any other getter method in place of getRAmnorm() to get the required output.
databaseIndex -> row number
I have encountered a weird problem in my app (java).
I have an enum. Something like that
public enum myEnum implement myIntrface{
valueA(1),valueb(2),valuec(3),valued(4)
private int i;
// and then - a constructor
public MyEnum(int number){
i = number;
}
private MyObj obj = new MyObj;
// getter and setter for obj
}
and in another class I have this
MyEnum.valueA.setObj(new Obj(...))
in briefe - I have an enum with a private instance member that has a set and a get.
So far so good -
The only thing that amazes me is that later on I look at the value of the MyEnum.valueA().obj is null.
there is nothing that updates the value to null, I have even gave it a default value in the constructor and I still see it null later.
any suggestions?
Enums should be un-modifiable classes so you shouldn't really be doing this. If your looking to modify the state of a type based object like an enum you should use an final class approach with embedded constants. Below is an example of a class based approach with a modifiable name an a un-modifiable name...
public final class Connection {
public static final Connection EMAIL = new Connection("email");
public static final Connection PHONE = new Connection("phone");
public static final Connection FAX = new Connection("fax");
/**/
private final String unmodifiableName; //<-- it's final
private String modifiableName;
/*
* The constructor is private so no new connections can be created outside.
*/
private Connection(String name) {
this.unmodifiableName = name;
}
public String getUnmodifiableName() {
return unmodifiableName;
}
public String getModifiableName() {
return modifiableName;
}
public void setModifiableName(String modifiableName) {
this.modifiableName = modifiableName;
}
}
The purpose of enums is to represent constant values. It does not make any sense to set the fields of a constant value.
You should declare your fields as final, and use the constructor to initialize all of them.
For reference, the following code works as expected:
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.get()); // prints "null"
MyEnum.valueA.set(new Integer(42));
System.out.println(MyEnum.valueA.get()); // prints "42"
}
}
the cause of this problem is the db40 framework . It loads an enum from the db using reflection. This is well documented .
http://developer.db4o.com/Forums/tabid/98/aft/5439/Default.aspx