This question already has an answer here:
Javafx TableView not showing data
(1 answer)
Closed 4 years ago.
Purpose: To browse for a folder and select it. And to add its properties in columns.
For example, the name of the folder goes in the name column, the location goes in the location, and etc.
For some reason, I am not able to add the properties of selected folder into the table named folderTable. The program seem to know that something is in the first row after I add a folder but it doesn't display the folder itself.
I am learning, so any help is appreciated.
public class mainClass2 extends Application {
Stage window;
TableView<syncedFolders> folderTable;
Button file, edit, view, addFolder, printInfo, close, deleteFolder;
private String name, location, dateModified;
private long size;
private double printSize = 0, bytes = 0, kilobytes = 0, megabytes = 0, gigabytes = 0, tempSize = 0;
private String printSizeAb = "";
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
HBox topMenu = new HBox();
file = new Button("File");
edit = new Button("Edit");
view = new Button("View");
topMenu.getChildren().addAll(file, edit, view);
VBox leftMenu = new VBox();
printInfo = new Button("Print folder info");
printInfo.setOnAction(e -> {
round(printSize, 1);
System.out.println("Name: " + name);
System.out.println("Location: " + location);
System.out.println("Last Modified: " + dateModified);
System.out.println("Size: " + tempSize + printSizeAb);
});
leftMenu.getChildren().add(printInfo);
HBox botBox = new HBox();
addFolder = new Button("Add Folder");
deleteFolder = new Button("Delete Folder");
close = new Button("Exit");
addFolder.setOnAction(e -> {
DirectoryChooser chooser = new DirectoryChooser();
chooser.setTitle("JavaFX Projects");
File defaultDirectory = new File("D:\\");
chooser.setInitialDirectory(defaultDirectory);
File selectedDirectory = chooser.showDialog(window);
name = selectedDirectory.getName();
location = selectedDirectory.toString();
size = getFolderSize(selectedDirectory);
bytes = size;
kilobytes = (bytes / 1024);
megabytes = (kilobytes / 1024);
gigabytes = (megabytes / 1024);
if (bytes < 1024) {
printSize = kilobytes;
printSizeAb = " KB";
} else if (bytes >= 1024 && bytes < Math.pow(1024, 3)) {
printSize = megabytes;
printSizeAb = " MB";
} else // if (bytes >= Math.pow(1024, 2) && bytes <= Math.pow(1024, 3))
{
printSize = gigabytes;
printSizeAb = " GB";
}
addFolder();
lasModifiedDate();
});
// Name column
TableColumn<syncedFolders, String> nameCol = new TableColumn<>("Name");
nameCol.setMinWidth(200);
nameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
// location column
TableColumn<syncedFolders, String> locationCol = new TableColumn<>("Location");
locationCol.setMinWidth(200);
locationCol.setCellValueFactory(new PropertyValueFactory<>("location"));
// date modified column
TableColumn<syncedFolders, String> dateModifiedCol = new TableColumn<>("Last Modified");
dateModifiedCol.setMinWidth(200);
dateModifiedCol.setCellValueFactory(new PropertyValueFactory<>("dateModified"));
// size column
TableColumn<syncedFolders, Double> sizeCol = new TableColumn<>("Size");
sizeCol.setMinWidth(200);
sizeCol.setCellValueFactory(new PropertyValueFactory<>("size"));
folderTable = new TableView<>();
folderTable.setItems(getSyncedFolders());
folderTable.getColumns().addAll(nameCol, locationCol, dateModifiedCol, sizeCol);
close.setOnAction(e -> closeProgram());
botBox.setPadding(new Insets(10, 10, 10, 10));
botBox.setSpacing(10);
botBox.getChildren().addAll(addFolder, deleteFolder, close);
BorderPane borderPane = new BorderPane();
borderPane.setTop(topMenu);
borderPane.setLeft(leftMenu);
borderPane.setCenter(folderTable);
borderPane.setBottom(botBox);
Scene scene = new Scene(borderPane, 800, 600);
window.setScene(scene);
window.setTitle("the title");
window.show();
window.setOnCloseRequest(e -> {
e.consume();
closeProgram();
});
}
// Get all of the products
public ObservableList<syncedFolders> getSyncedFolders() {
ObservableList<syncedFolders> folders = FXCollections.observableArrayList();
folders.add(new syncedFolders("Folder", "D://", "July", 3.4));
folders.add(new syncedFolders(name, location, dateModified, tempSize));
return folders;
}
public void addFolder() {
round(printSize, 1);
folderTable.setItems(getSyncedFolders());
folderTable.getItems().add(new syncedFolders(name, location, dateModified, tempSize));
}
private double round(double value, int precision) {
int scale = (int) Math.pow(10, precision);
tempSize = (double) Math.round(value * scale) / scale;
return tempSize;
}
public String lasModifiedDate() {
Path path = Paths.get(location);
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy - hh:mm:ss");
FileTime fileTime = null;
try {
fileTime = Files.getLastModifiedTime(path);
} catch (IOException e1) {
System.out.println("Cannot get the last modified time");
}
dateModified = dateFormat.format(fileTime.toMillis());
return dateModified;
}
private long getFolderSize(File folder) {
long length = 0;
File[] files = folder.listFiles();
int count = files.length;
for (int i = 0; i < count; i++) {
if (files[i].isFile()) {
length += files[i].length();
} else {
length += getFolderSize(files[i]);
}
}
return length;
}
private void closeProgram() {
/**
* Alert alert = new Alert(AlertType.CONFIRMATION); alert.setTitle("Confirmation
* Dialog"); alert.setHeaderText("You are about to exit");
* alert.setContentText("Are you ok with this?");
*
* Optional<ButtonType> result = alert.showAndWait(); if (result.get() ==
* ButtonType.OK)
**/
window.close();
}
}
public class syncedFolders {
private String name, location, dateModified;
private double size;
public syncedFolders() {
this.name = "";
this.location = "";
this.dateModified = "";
this.size = 0;
}
public syncedFolders(String s) {
this.name = s;
}
public syncedFolders(String name, String location, String dateModified, double size) {
this.name = name;
this.location = location;
this.dateModified = dateModified;
this.size = size;
}
public String getname() {
return name;
}
public void setname(String s) {
name = s;
}
public String getlocation() {
return location;
}
public void setlocation(String s) {
location = s;
}
public String getdateModified() {
return dateModified;
}
public void setdateModified(String s) {
dateModified = s;
}
public double getsize() {
return size;
}
public void setsize(double d) {
size = d;
}
}
The TableView uses Properties and Bindings to display the data in each column. You have a CellValueFactory installed on the columns, but you're populating it usinga PropertyValueFactory.
That is the right way to do it, but there's a problem with your syncedFolders class. The PropertyValueFactory looks into your syncedFolders class and tries to find a Property with the name you specified. The problem is that you do not have any properties defined:
private String name, location, dateModified;
private double size;
These are fields, not properties.
You will need to rewrite your syncedFolders class to have observable properties instead, like this:
private SimpleStringProperty name = new SimpleStringProperty();
Do that for each of your fields, update your constructor and setters/getters and try again!
public class syncedFolders {
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleStringProperty location = new SimpleStringProperty();
private SimpleStringProperty dateModified = new SimpleStringProperty();
private SimpleDoubleProperty size = new SimpleDoubleProperty();
public syncedFolders(
String name,
String location,
String dateModified,
double size) {
this.name.set(name);
this.location.set(location);
this.dateModified.set(dateModified);
this.size.setValue(size);
}
public String getName() {
return name.get();
}
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public String getLocation() {
return location.get();
}
public SimpleStringProperty locationProperty() {
return location;
}
public void setLocation(String location) {
this.location.set(location);
}
public String getDateModified() {
return dateModified.get();
}
public SimpleStringProperty dateModifiedProperty() {
return dateModified;
}
public void setDateModified(String dateModified) {
this.dateModified.set(dateModified);
}
public double getSize() {
return size.get();
}
public SimpleDoubleProperty sizeProperty() {
return size;
}
public void setSize(double size) {
this.size.set(size);
}
}
EDIT:
I would also recommend changing how you populate your table. Your current addFolder() method is adding the item directly to the table's items property, but you really should add them to the underlying ObservableList that is set as the table's items:
public void addFolder() {
round(printSize, 1);
folderTable.setItems(getSyncedFolders());
folderTable.getItems().add(new syncedFolders(name, location, dateModified, tempSize));
}
The way folderTable.setItems() works is that it binds a list to the TableView. But that I mean that any changes made to the list will be reflected in the TableView automatically; you should not need to use folderTable.getItems().add() at all.
Related
import java.util.ArrayList;
public class Portfolio {
ArrayList<String> myportfolio = new ArrayList<>();
int portfolioSize;
int holding;
public Portfolio(){
}
public void addStockHolding(StockHolding mystock){
myportfolio.add(String.valueOf(mystock));
}
public int getSize(){
portfolioSize = myportfolio.size();
return portfolioSize;
}
public boolean isInPortfolio(String ticker){
String temp = myportfolio.toString();
if (temp.contains(ticker)) return true;
else return false;
}
public void delaStock(int stockArray){
// String temp = myportfolio.toString();
//int tickerloc = temp.indexOf(ticker);
//int dot = temp.indexOf('.', tickerloc);
//String stocksumm = temp.substring(tickerloc, dot+3);
//myportfolio.remove(stocksumm);
}
public int getstockShares(String ticker){
String temp = myportfolio.toString();
int tickerloc = temp.indexOf(ticker);
int colon = temp.indexOf(':', tickerloc);
int boughtStr = temp.indexOf("bought", tickerloc);
String stockShares = temp.substring(colon+1, boughtStr-1);
stockShares = stockShares.trim();
int sharesOwned = Integer.parseInt(stockShares);
return sharesOwned;
}
public double getstockPrice(String ticker){
String temp = myportfolio.toString();
int tickerloc = temp.indexOf(ticker);
int dsign = temp.indexOf('$', tickerloc);
int dot = temp.indexOf('.', tickerloc);
String orgPrice = temp.substring(dsign+1, dot+3);
orgPrice = orgPrice.trim();
double purchasePrice = Double.parseDouble(orgPrice);
return purchasePrice;
}
public int stockLength(String ticker){
String temp = myportfolio.toString();
int tickerloc = temp.indexOf(ticker);
int dot = temp.indexOf('.');
String stock = temp.substring(tickerloc, dot +2);
int stockloc = myportfolio.indexOf(stock);
return stockloc;
}
public String toString(){
String summary = (myportfolio.toString());
return summary;
}
}
public class StockHolding {
String ticker;
int numberShares;
double initialPrice;
double initialCost;
double currentValue;
double currentProfit;
double currentPrice;
public StockHolding(String ticker, int numberShares, double initialPrice){
this.ticker = ticker;
this.numberShares = numberShares;
this.initialPrice = initialPrice;
}
public String getTicker(String ticker){
return ticker;
}
double getInitialSharePrice(){
return initialPrice;
}
int getShares(){
return numberShares;
}
public double getCurrentSharePrice(){
return currentPrice;
}
public double getInitialCost(){
initialCost = numberShares * initialPrice;
return initialCost;
}
public double getCurrentValue(){
currentValue = numberShares * currentPrice ;
return currentValue;
}
public double getCurrentProfit(){
this.currentProfit = numberShares * (currentPrice - initialPrice);
return this.currentProfit;
}
public String toString(){
String summary = ("Stock " + ticker + ": " + numberShares + " bought at $ " + initialPrice + '\n');
return summary;
}
public void setCurrentSharePrice(double sharePrice){
currentPrice = sharePrice;
}
}
public class StockProject {
public static void main(String[] arg){
PortfolioAction transactions = new PortfolioAction();
}
}
public class Calculations {
private int haveShares;
private double pricePaid;
private String ticker;
private int num;
private int updShares;
private double price;
private double sale;
private Portfolio myportfolio;
private double priceDiff;
public Calculations(String ticker, int num, double price, Portfolio myportfolio){
this.ticker = ticker;
this.num = num;
this.price = price;
this.myportfolio = myportfolio;
}
public void setHaveShares() {
this.haveShares = myportfolio.getstockShares(ticker);
}
public int getHaveShares(){
return this.haveShares;
}
public void setPricePaid(){
pricePaid = myportfolio.getstockPrice(ticker);
}
public double getPricePaid(){
return this.pricePaid;
}
public void setSale(){
sale = num * price;
}
public double getSale(){
return sale;
}
public int getnumShares(){
return haveShares;
}
public void setUpdShares(){
this.updShares = haveShares - num;
}
public int getUpdShares(){
return this.updShares;
}
public void setPriceDiff(){
this.priceDiff = pricePaid - price;
}
public double getpriceDiff(){
this.priceDiff = pricePaid - price;
return this.priceDiff;
}
}
import javax.swing.*;
import java.awt.event.ActionEvent;
public class PortfolioAction {
private JLabel jlticker;
private JTextField jtenterTkr;
private JLabel jlnumShares;
private JTextField jtenterShares;
private JLabel jlPrice;
private JTextField jtenterPrice;
private JLabel jlLeft;
private JLabel jlCash;
private JLabel jlCashAmt;
private JLabel jlRight;
private JLabel butLeft;
private JButton jbsell;
private JButton jbbuy;
private JLabel butRight;
private JTextArea jtsummary;
Portfolio myportfolio = new Portfolio();
Account myaccount = new Account();
public PortfolioAction(){
Messages.getDisclaimer();
WidgetView wv = new WidgetView();
jlticker = new JLabel(" Stock Ticker "); //16
jtenterTkr = new JTextField(" "); //25
jlnumShares = new JLabel(" Number of Shares: "); //21
jtenterShares = new JTextField(" "); //25
jlPrice = new JLabel(" Price per Share: "); //21
jtenterPrice = new JTextField(" "); //25
jlLeft = new JLabel(" "); //65
jlCash = new JLabel(" Cash: $ "); //11
jlCashAmt = new JLabel(" 1000.00 " ); //11
jlRight = new JLabel(" "); //65
butLeft = new JLabel(" "); //60
jbsell = new JButton(" Sell ");
jbbuy = new JButton(" Buy ");
butRight = new JLabel(" ");
jtsummary = new JTextArea();
ButtonSell sellaction = new ButtonSell(jtenterTkr, jtenterShares, jtenterPrice, jlCashAmt, jtsummary);
ButtonBuy buyaction = new ButtonBuy(jtenterTkr, jtenterShares, jtenterPrice, jlCashAmt, jtsummary);
jbsell.addActionListener(sellaction);
jbbuy.addActionListener(buyaction);
wv.add(jlticker);
wv.add(jtenterTkr);
wv.add(jlnumShares);
wv.add(jtenterShares);
wv.add(jlPrice);
wv.add(jtenterPrice);
wv.add(jlLeft);
wv.add(jlCash);
wv.add(jlCashAmt);
wv.add(jlRight);
wv.add(butLeft);
wv.add(jbsell);
wv.add(jbbuy);
wv.add(butRight);
wv.add(jtsummary);
}
class ButtonSell extends WidgetViewActionEvent {
private JTextField enterTkr;
private JTextField enterShares;
private JTextField enterPrice;
private JLabel balance;
private JTextArea summary;
private boolean tkrLoc;
private int num;
private double price;
private String currBal;
private int previousShares;
private String ticker;
private double priceDiff;
private int haveShares;
private String salesummary;
public ButtonSell(JTextField jtenterTkr, JTextField jtenterShares, JTextField jtenterPrice, JLabel jlCashAmt, JTextArea jtSummary) {
enterTkr = jtenterTkr;
enterShares = jtenterShares;
enterPrice = jtenterPrice;
balance = jlCashAmt;
summary = jtsummary;
}
#Override
public void actionPerformed(ActionEvent e) {
this.ticker = enterTkr.getText();
this.ticker = ticker.trim();
try {
String numShares = enterShares.getText();
numShares = numShares.trim();
this.num = Integer.parseInt(numShares);
String getPrice = enterPrice.getText();
getPrice = getPrice.trim();
this.price = Double.parseDouble(getPrice);
String currBal = balance.getText();
this.currBal = currBal.trim();
}catch
(NumberFormatException ex) {
Messages.getNumErrMess();
}catch (NullPointerException ex){
Messages.getnotOwned();
}finally {
this.tkrLoc = myportfolio.isInPortfolio(ticker);
if (this.tkrLoc == false) {
Messages.getnotOwned();
} else{
Calculations sellStocks = new Calculations(ticker, num, price, myportfolio);
sellStocks.setHaveShares();
sellStocks.setPricePaid();
sellStocks.setUpdShares();
sellStocks.setPriceDiff();
sellStocks.setSale();
this.previousShares = sellStocks.getnumShares();
if(this.num > this.previousShares){
Messages.lowStockMsg();
balance.setText(currBal);
enterTkr.setText(" "); //25
enterShares.setText(" "); //25
enterPrice.setText(" "); //25
}else {
double sales = sellStocks.getSale();
myaccount.creditAccount(sales);
double newBal = myaccount.getBalance();
int holding = myportfolio.stockLength(ticker);
myportfolio.delaStock(holding);
int updShares = sellStocks.getUpdShares();
double pricePaid = sellStocks.getPricePaid();
StockHolding mystock = new StockHolding(ticker,updShares, pricePaid);
myportfolio.addStockHolding( mystock);
String bal = String.format("%.2f", newBal);
balance.setText(bal);
enterTkr.setText(" "); //25
enterShares.setText(" "); //25
enterPrice.setText(" "); //25
priceDiff = sellStocks.getpriceDiff();
haveShares = sellStocks.getHaveShares();
if (this.priceDiff < 0) {
double profit = priceDiff * haveShares* -1;
String hasProfit = String.format("%.2f" , profit);
salesummary = ("You made a profit of " + hasProfit);
} else if (this.priceDiff > 0) {
double loss = priceDiff * haveShares* -1;
String hasLoss = String.format("%.2f" , loss);
salesummary = ("You had a loss of " + hasLoss);
} else {
salesummary = "You have broke even.";
}
summary.setText(salesummary + '\n' + myportfolio.toString());
}
}
}
}
}
class ButtonBuy extends WidgetViewActionEvent {
private JTextField enterTkr;
private JTextField enterShares;
private JTextField enterPrice;
private JLabel balance;
private JTextArea summary;
public ButtonBuy(JTextField jtenterTkr, JTextField jtenterShares, JTextField jtenterPrice, JLabel jlCashAmt, JTextArea jtsummary) {
enterTkr = jtenterTkr;
enterShares = jtenterShares;
enterPrice = jtenterPrice;
balance = jlCashAmt;
summary = jtsummary;
}
#Override
public void actionPerformed(ActionEvent e) {
String ticker = enterTkr.getText();
ticker = ticker.trim();
try {
String numShares = enterShares.getText();
numShares = numShares.trim();
int num = Integer.parseInt(numShares);
String getPrice = enterPrice.getText();
getPrice = getPrice.trim();
double price = Double.parseDouble(getPrice);
double availCash = Double.parseDouble(balance.getText());
if ((price * num) > availCash) {
Messages.getMoneyMess();
}
else {
StockHolding mystock = new StockHolding(ticker, num, price);
myportfolio.addStockHolding(mystock);
double cost = mystock.getInitialCost();
myaccount.debitAccount(cost);
double newBal = myaccount.getBalance();
String bal = String.format("%.2f", newBal);
balance.setText(bal);
enterTkr.setText(" "); //25
enterShares.setText(" "); //25
enterPrice.setText(" "); //25
summary.setText(myportfolio.toString());
}
}
catch (NumberFormatException ex) {
Messages.getNumErrMess();
}
}
}
}
import javax.swing.JOptionPane;
public class Messages {
static String notEnuffFunds = "Transaction denied: Not enough Funds";
static String errNum = "Error: Number of Shares and Share price must be numbers only";
static String warn = "Warning";
static String noStock = "Stock not available to sell.";
static String disclaim = "Disclaimer";
static String disclosure = "This program is for entertainment purposes only. The account on this program does not represent" +
" any money in the real world nor does this predict any profit or loss on stocks you purchase in the real world.";
static String lowStock = "Not that meaning stock to sell";
public Messages(){
}
public static void getNumErrMess(){
JOptionPane.showMessageDialog(null, errNum, warn, JOptionPane.WARNING_MESSAGE);
}
public static void getMoneyMess(){
JOptionPane.showMessageDialog(null, notEnuffFunds, warn, JOptionPane.WARNING_MESSAGE);
}
public static void getnotOwned(){
JOptionPane.showMessageDialog(null, noStock, warn, JOptionPane.WARNING_MESSAGE);
}
public static void getDisclaimer(){
JOptionPane.showMessageDialog(null, disclosure, disclaim, JOptionPane.INFORMATION_MESSAGE);
}
public static void lowStockMsg(){
JOptionPane.showMessageDialog(null, lowStock, warn, JOptionPane.WARNING_MESSAGE);
}
}
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* A really simple class to display Swing widgets in a FlowLayout GUI.
* <p>
*
* #author parks
*/
public class WidgetView {
public static final int DEFAULT_X_SIZE = 600;
public static final int DEFAULT_Y_SIZE = 400;
private JFrame jframe;
private JPanel anchor;
private boolean userClicked = false;
private Lock lock;
private Condition waitingForUser;
private JComponent userInputComponent = null;
private ActionListener eventHandler;
/**
* Default constructor will display an empty JFrame that has a Flow layout
* JPanel as its content pane and initialize the frame to a default size.
*/
public WidgetView() {
this(DEFAULT_X_SIZE, DEFAULT_Y_SIZE);
}
/**
* Constructor will display an empty JFrame that has a Flow layout
* JPanel as its content pane and initialize the frame to a given size.
*/
public WidgetView(int pixelSizeInX, int pixelSizeInY) {
lock = new ReentrantLock();
waitingForUser = lock.newCondition();
// lambda expression requires Java 8
// eventHandler = e -> {
// if (e.getSource() != userInputComponent) {
// return;
// }
// lock.lock();
// userClicked = true;
// waitingForUser.signalAll();
// lock.unlock();
// };
//* java 7 solution
eventHandler = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() != userInputComponent) {
return;
}
lock.lock();
userClicked = true;
waitingForUser.signalAll();
lock.unlock();
}
};
jframe = new JFrame();
anchor = new JPanel();
jframe.setContentPane(anchor);
jframe.setSize(pixelSizeInX, pixelSizeInY);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
}
/**
* Add a Swing widget to the GUI.
*
* #param jcomp Swing widget (subclasses of JComponent--like JLabel and
* JTextField) to be added to the JFrame
*/
public void add(JComponent jcomp) {
anchor.add(jcomp);
jframe.setContentPane(anchor);
}
/**
* Add an Abstract Button (like a JButton) to the JFrame. Create an action
* listener to wait (suspend the caller) until it is clicked.
*
* #param absButton Button (like a JButton) to add to the JFrame
*/
public void addAndWait(AbstractButton absButton) {
userInputComponent = absButton;
absButton.addActionListener(eventHandler);
addWait(absButton);
}
/**
* Add a JTextField to the JFrame, and wait for the user to put the cursor
* in the field and click Enter. The caller is suspended until enter is
* clicked.
*
* #param jTextField Field to add to the JFrame
*/
public void addAndWait(JTextField jTextField) {
userInputComponent = jTextField;
jTextField.addActionListener(eventHandler);
addWait(jTextField);
}
private void addWait(JComponent jcomp) {
add(jcomp);
lock.lock();
try {
while (!userClicked) {
waitingForUser.await();
}
}
catch (InterruptedException e1) {
System.err.println("WidgetView reports that something really bad just happened");
e1.printStackTrace();
System.exit(0);
}
userClicked = false;
waitingForUser.signalAll();
lock.unlock();
}
}
import java.awt.event.ActionListener;
public abstract class WidgetViewActionEvent implements ActionListener {
}
public class Account {
double availableBalance = 1000.00;
public Account(){
}
public void debitAccount(double cost){
availableBalance -= cost;
}
public void creditAccount(double sale){
availableBalance += sale;
}
public double getBalance (){
return availableBalance;
}
}
I am working on a school project; a program that has the user enter a sticker, number of stocks and the price. then they have the option to buy and sell. The problem I am having is that say they bought 6 shares of IBM at 34.45 and want to sell 4 of them; I want to update the stock in the portfolio. I figured I would need to delete the original stock bought and put in the remaining stock as a new StockHolding. The problem is how do I find the index of the String in the arrayList of Portfolio to delete the old now out-dated StockHolding? The project has a Calculation class, a portfolioAction class, Messages class, and Account class, with the use of a WidgetView class that was supplied by the teacher. It is my first semester of Java. Thanks for any help.
updated: all the classes for the program are there now. The instructor wanted the inclusion of certain classes. We have not done hash maps and can only use the materials we have covered to this point. So I apologize.
: Output window for sell
I do not get any error messages; I am using IntelliJ IDEA. My problem is in the screenshot. It gives me the update stock but doesn't delete the old one. I have tried index of methods and am just stuck. But all the classes are here and it runs without error. Thank you again and sorry this is so lengthy.
To find the index of the string based on categories..
Try to use this below method:
private ArrayList<String> _categories;
private int getCategoryPos(String category) {
return _categories.indexOf(category);
}
To replace the old value in array list use set:
Instead of removing,
_categories.set( your_index, your_item )
Hope it helps.
your code is a bit long without specifications or sample output. But to find and change the stock you could use
myportfolio.set(indexOf(oldStock), newStock)
Can someone suggest how to dynamicly add TableColumn to TableView in JavaFX?
I need to display class Row at tableView, but I know count of Nodes after another action. I've got trouble when I tried to use StringProperty from Node to set CellValueFactory. From Node class I need to display only reserved and reliability.
public class Row {
private int step;
private Node[] nodes;
private double p = 1;
private double c;
private StringProperty stepProperty;
private StringProperty pProperty;
private StringProperty cProperty;
Row(int step, Node[] nodes, double c){
this.step = step;
this.nodes = nodes;
for (Node node:
nodes) {
p *= node.getReliability();
}
this.c = c;
}
public int getStep() {return step;}
public Node getNode(int index) {return nodes[index];}
public double getP() {return p;}
public double getC() {return c;}
public StringProperty stepProperty() {
this.stepProperty = new SimpleStringProperty(step + "");
return stepProperty;
}
public StringProperty pProperty() {
this.pProperty = new SimpleStringProperty(p + "");
return pProperty;
}
public StringProperty cProperty() {
this.cProperty = new SimpleStringProperty(c + "");
return cProperty;
} }
public class Node {
private StringProperty reserved;
private StringProperty reliability;
private StringProperty price;
Node(String reserved, String reliability, String price){
this.reserved = new SimpleStringProperty(reserved);
this.reliability = new SimpleStringProperty(reliability);
this.price = new SimpleStringProperty(price);
}
public StringProperty reliabilityProperty() {
return reliability;
}
public StringProperty priceProperty() {
return price;
}
public StringProperty reservedProperty() {
return reserved;
}
public double getReliability(){
return Double.parseDouble(reliability.get());}
public int getPrice(){return Integer.parseInt(price.get());}
public int getReserved(){return Integer.parseInt(reserved.get());}
}
You just need something along the following lines:
TableView<Row> table = new TableView<>();
int numNodes = ... ;
TableColumn<Row, Number> stepCol = new TableColumn<>("Step");
stepCol.setCellValueFactory(cellData -> cellData.getValue().stepProperty());
table.getColumn().add(stepCol);
for (int n = 0 ; n < numNodes ; n++) {
final int nodeIndex = n ;
TableColumn<Row, String> reservedCol = new TableColumn<>("Reserved - "+nodeIndex);
reservedCol.setCellValueFactory(cellData -> cellData.getValue().getNode(nodeIndex).reservedProperty());
TableColumn<Row, String> reliabilityCol = new TableColumn<>("Reliability - "+nodeIndex);
reliabilityCol.setCellValueFactory(cellData -> cellData.getValue().getNode(nodeIndex).reliabilityProperty());
table.getColumns().add(reservedCol);
table.getColumns().add(reliabilityCol);
}
TableColumn<Row, String> pCol = new TableColumn<>("P");
stepCol.setCellValueFactory(cellData -> cellData.getValue().pProperty());
table.getColumn().add(pCol);
TableColumn<Row, String> cCol = new TableColumn<>("C");
stepCol.setCellValueFactory(cellData -> cellData.getValue().cProperty());
table.getColumn().add(cCol);
I am experimenting with JavaFX and I am trying to add a progress bar in tree table. Is there a way to link the values of salary to progress bar.
My Code is modified version of Oracle's TreeTableView Example:
public class TreeTableViewSample extends Application implements Runnable {
List<Employee> employees = Arrays.<Employee>asList(
new Employee("Ethan Williams", 30.0),
new Employee("Emma Jones", 10.0),
new Employee("Michael Brown", 70.0),
new Employee("Anna Black", 50.0),
new Employee("Rodger York", 20.0),
new Employee("Susan Collins", 70.0));
/* private final ImageView depIcon = new ImageView (
new Image(getClass().getResourceAsStream("department.png"))
);
*/
final CheckBoxTreeItem<Employee> root
= new CheckBoxTreeItem<>(new Employee("Sales Department", 0.0));
final CheckBoxTreeItem<Employee> root2
= new CheckBoxTreeItem<>(new Employee("Departments", 0.0));
public static void main(String[] args) {
Application.launch(TreeTableViewSample.class, args);
}
#Override
public void start(Stage stage) {
root.setExpanded(true);
employees.stream().forEach((employee) -> {
CheckBoxTreeItem<Employee> cbt=new CheckBoxTreeItem<>(employee);
cbt.selectedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
if (newValue) {
System.out.println("Slected employ name is "+cbt.getValue().getName());
}
});
root.getChildren().add(cbt);
});
stage.setTitle("Tree Table View Sample");
final Scene scene = new Scene(new Group(), 400, 400);
scene.setFill(Color.LIGHTGRAY);
Group sceneRoot = (Group) scene.getRoot();
TreeTableColumn<Employee, String> empColumn
= new TreeTableColumn<>("Employee");
empColumn.setPrefWidth(150);
empColumn.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Employee, String> param)
-> new ReadOnlyStringWrapper(param.getValue().getValue().getName())
);
TreeTableColumn<Employee, Double> salaryColumn
= new TreeTableColumn<>("Salary");
salaryColumn.setPrefWidth(190);
salaryColumn.setCellValueFactory(new Callback<CellDataFeatures<Employee, Double>, ObservableValue<Double>>() {
#Override
public ObservableValue<Double> call(CellDataFeatures<Employee, Double> p) {
// p.getValue() returns the Employee instance for a particular TableView row
return p.getValue().getValue().getSalary();
}
});
salaryColumn.setCellFactory(ProgressBarTreeTableCell.<Employee>forTreeTableColumn());
root2.getChildren().add(root);
TreeTableView<Employee> treeTableView = new TreeTableView<>(root2);
treeTableView.getColumns().setAll(empColumn, salaryColumn);
treeTableView.setRowFactory(f -> new CheckBoxTreeTableRowHack<>());
sceneRoot.getChildren().add(treeTableView);
stage.setScene(scene);
stage.show();
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(this, 3, 10, TimeUnit.SECONDS);
}
#Override
public void run() {
root2.getValue().setSalary(calcSalary(root));
}
public double calcSalary(TreeItem<Employee> t) {
Double salary = 0.0;
if (!t.isLeaf()) {
ObservableList<TreeItem<Employee>> al = t.getChildren();
for (int i = 0; i < al.size(); i++) {
TreeItem<Employee> get = al.get(i);
salary += calcSalary(get);
}
t.getValue().setSalary(salary);
}
return salary += t.getValue().getSalary();
}
public class Employee {
private SimpleStringProperty name;
private SimpleDoubleProperty salary;
public SimpleStringProperty nameProperty() {
if (name == null) {
name = new SimpleStringProperty(this, "name");
}
return name;
}
public SimpleDoubleProperty salaryProperty() {
if (salary == null) {
salary = new SimpleDoubleProperty(this, "salary");
}
return salary;
}
private Employee(String name, Double salary) {
this.name = new SimpleStringProperty(name);
this.salary = new SimpleDoubleProperty(salary);
}
public String getName() {
return name.get();
}
public void setName(String fName) {
name.set(fName);
}
public Double getSalary() {
return salary.get();
}
public void setSalary(Double fName) {
salary.set(fName);
}
}
}
I am recieving error at return p.getValue().getValue().getSalary(); it says Incompatible Types: Double cannot be converted to ObservableValue<Double>. As i know you have to return ObservableValue in the return of the call method. But as newbie i am unable to find a way to cast the value. Setting string is easy.
So far i have tried return new ReadOnlyDoubleWrapper(p.getValue().getValue().getSalary());
but that also didn't worked out for me.
I am using JavaFx 8.
I am trying to create Salary Bars, which can also be used as progress bar for a task and its sub tasks. (Just playing with UI). But don't know how to connect them with the real values of employe, as i guess normal table view is different from tree table view. Thanks ! :)
This is essentially the same as JavaFX Properties in TableView : salaryProperty is not an ObservableValue<Double> but is an ObservableValue<Number>.
You need to make the column a TreeTableColumn<Employee, Number>. Then you can just return the salaryProperty for the employee:
TreeTableColumn<Employee, Number> salaryColumn
= new TreeTableColumn<>("Salary");
salaryColumn.setCellValueFactory(p -> p.getValue().getValue().salaryProperty());
The other option is to use salaryProperty().asObject() which returns an ObjectProperty<Double> bidirectionally bound to salaryProperty():
TreeTableColumn<Employee, Double> salaryColumn
= new TreeTableColumn<>("Salary");
salaryColumn.setCellValueFactory(p ->
p.getValue().getValue().salaryProperty().asObject());
For some reason (seemingly completely independent of code) the frame of my program will only appear some (maybe 20%) of the time. If I just continuously hit run I evently get the frame to show successfully, but it is never repeatable. has this ever happened to anyone else? I highly doubt this has to do with code but just in case
public class Trader{
public static Trader INSTANCE = new Trader();
JTextArea msgBox;
ApiController m_controller;
Connection connect;
Quotes quotes;
ArrayList<String> m_acctList = new ArrayList();
public static void main(String[] args) {
INSTANCE.run();
}
public void run(){
connect = new Connection();
}
public ArrayList<String> accountList() { return m_acctList; }
public ApiController controller() { return m_controller; }
public JFrame frame() { return connect.frame; }
}
next class
public class Connection implements IConnectionHandler{
static int port = 4001;
Quotes quotes;
JFrame frame;
CPanel panel;
boolean connected = false;
JTextArea logIn = new JTextArea();
JTextArea logOut = new JTextArea();
JTextArea msgBox = new JTextArea();
Logger loggerIn = new Logger(logIn);
Logger loggerOut = new Logger(logOut);
ApiController m_controller = new ApiController(this, loggerIn, loggerOut);
final ArrayList<String> m_acctList = new ArrayList<String>();
Connection(){
frame = new JFrame("Trader");
panel = new CPanel();
frame.add(panel);
frame.setSize(800,400);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class CPanel extends JComponent{
Point frameLoc = frame.getLocation();
Dimension frameSize = frame.getSize();
JLabel text = new JLabel("Messages");
JScrollPane messages = new JScrollPane(msgBox);
CPanel(){
setLayout(null);
add(text);
text.setBounds(frameLoc.x+5, frameLoc.y+5,
text.getPreferredSize().width, text.getPreferredSize().height);
add(messages);
msgBox.setEditable(false);
msgBox.setLineWrap(true);
messages.setBounds(text.getLocation().x, text.getLocation().y+text.getSize().height+10,
720, 300);
m_controller.connect(null, port, 0);
}
}
#Override public void connected() {
show( "connected");
m_controller.reqCurrentTime( new ApiController.ITimeHandler() {
#Override public void currentTime(long time) {
show( "Server date/time is " + Formats.fmtDate(time * 1000) );
}
});
m_controller.reqBulletins( true, new ApiController.IBulletinHandler() {
#Override public void bulletin(int msgId, Types.NewsType newsType, String message, String exchange) {
String str = String.format( "Received bulletin: type=%s exchange=%s", newsType, exchange);
show( str);
show( message);
}
});
// Quotes quotes = new Quotes();
}
#Override public void disconnected() {
show( "disconnected");
}
#Override public void accountList(ArrayList<String> list) {
show( "Received account list");
m_acctList.clear();
m_acctList.addAll( list);
}
#Override public void error(Exception e) {
show( e.toString() );
}
#Override public void message(int id, int errorCode, String errorMsg) {
show( id + " " + errorCode + " " + errorMsg);
}
#Override public void show( final String str) {
SwingUtilities.invokeLater( new Runnable() {
#Override public void run() {
msgBox.append(str);
msgBox.append( "\n\n");
Dimension d = msgBox.getSize();
msgBox.scrollRectToVisible( new Rectangle( 0, d.height, 1, 1) );
}
});
}
private static class Logger implements ILogger{
final private JTextArea msgBox;
Logger(JTextArea area){
msgBox = area;
}
#Override public void log(final String str) {
SwingUtilities.invokeLater( new Runnable() {
#Override public void run() {
// m_area.append(str);
//
// Dimension d = m_area.getSize();
// m_area.scrollRectToVisible( new Rectangle( 0, d.height, 1, 1) );
}
});
}
}
}
and lastly
public class Quotes {
int numberOfStocks = 0;
JTextArea msgBox = Trader.INSTANCE.connect.msgBox;
String symbol;
File file = new File("/Users/spencerclayman/Desktop/IB_API/API_Data/stockList.txt");
ArrayList<quote> stockList = new ArrayList();
Quotes(){
msgBox.append("Getting stock quotes");
try(Scanner input = new Scanner(file);){
while(input.hasNextLine()){
symbol = input.nextLine();
newStock(newContract(symbol));
}
}
catch(Exception ex){msgBox.append("Error getting quotes");}
try{wait(10000);}catch(Exception ex){msgBox.append("error waiting - quote");}
for(int i = 0; i < numberOfStocks() -1 ; i++){
msgBox.append(stockList.get(i).m_description
+ " - " + stockList.get(i).m_last +"\n");
}
}
void newStock( NewContract contract) {
quote stock = new quote(contract.description());
stockList.add(stock);
Trader.INSTANCE.controller().reqTopMktData(contract, "", false, stock);
}
void newStock( quote stock) {
stockList.add(stock);
}
public void desubscribe() {
for (quote stock : stockList) {
Trader.INSTANCE.controller().cancelTopMktData(stock);
}
}
public int numberOfStocks(){
try(Scanner input = new Scanner(file);){
while(input.hasNextLine()){
numberOfStocks++;
input.nextLine();
}
}
catch(Exception ex){msgBox.append("Error getting symbols");}
return numberOfStocks;
}
static class quote extends TopMktDataAdapter{
String m_description;
double m_bid;
double m_ask;
double m_last;
long m_lastTime;
int m_bidSize;
int m_askSize;
double m_close;
int m_volume;
boolean m_frozen;
quote(String description){
m_description = description;
}
public String change() {
return m_close == 0 ? null : fmtPct( (m_last - m_close) / m_close);
}
#Override public void tickPrice( NewTickType tickType, double price, int canAutoExecute) {
switch( tickType) {
case BID:
m_bid = price;
break;
case ASK:
m_ask = price;
break;
case LAST:
m_last = price;
break;
case CLOSE:
m_close = price;
break;
}
}
#Override public void tickSize( NewTickType tickType, int size) {
switch( tickType) {
case BID_SIZE:
m_bidSize = size;
break;
case ASK_SIZE:
m_askSize = size;
break;
case VOLUME:
m_volume = size;
break;
}
}
#Override public void tickString(NewTickType tickType, String value) {
switch( tickType) {
case LAST_TIMESTAMP:
m_lastTime = Long.parseLong( value) * 1000;
break;
}
}
#Override public void marketDataType(Types.MktDataType marketDataType) {
m_frozen = marketDataType == Types.MktDataType.Frozen;
}
}
public NewContract newContract(String symbol){
NewContract c = new NewContract();
c.symbol(symbol);
c.secType(Types.SecType.STK);
c.exchange("SMART");
c.currency("USD");
return c;
}
}
again i am highly doubtful that code has anything to do with it. Im assumign its a problem with the IDE.
In my experience CONSTRAINED_RESIZE_POLICY is broken if the TableView contains some fixed width columns unless I am doing something wrong here:
public class JavaFX2Sandbox extends Application
{
public static void main(String[] args)
{
Application.launch(args);
}
#Override
public void start(Stage stage) throws Exception
{
StackPane root = new StackPane();
root.autosize();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
configureTable(root);
}
public static class Person
{
public Person(String firstName, String lastName)
{
this.fixedValue = "Dr.";
this.firstName = firstName;
this.lastName = lastName;
}
public String fixedValue;
public String firstName;
public String lastName;
}
private static class CellValueFactory<T> implements Callback<TableColumn.CellDataFeatures<T, Object>, ObservableValue<Object>>
{
private String mFieldName;
public CellValueFactory(String fieldName)
{
mFieldName = fieldName;
}
#Override
public ObservableValue call(TableColumn.CellDataFeatures<T, Object> p)
{
try
{
if (p == null)
{
return new SimpleObjectProperty(null);
}
Object o = p.getValue();
if (o == null)
{
return new SimpleObjectProperty(null);
}
Object fieldVal = o.getClass().getField(mFieldName).get(o);
if (fieldVal == null)
{
return new SimpleObjectProperty(null);
}
return new SimpleObjectProperty(fieldVal);
}
catch (Exception ex)
{
return new SimpleObjectProperty(ex);
}
}
}
private void configureTable(StackPane root)
{
TableView<Person> table = new TableView<>();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
ArrayList<Person> teamMembers = new ArrayList<>();
teamMembers.add(new Person("John", "Big"));
teamMembers.add(new Person("Frank", "Small"));
TableColumn col0 = new TableColumn("fixed-width");
col0.setResizable(false);
col0.setCellValueFactory(new CellValueFactory("fixedValue"));
TableColumn col1 = new TableColumn("First Name");
col1.setCellValueFactory(new CellValueFactory("firstName"));
TableColumn col2 = new TableColumn("Last Name");
col2.setCellValueFactory(new CellValueFactory("lastName"));
table.getColumns().setAll(col0, col1, col2);
table.setItems(FXCollections.observableList(teamMembers));
root.getChildren().add(table);
}
}
So I started to implement my own resize policy which behaves slightly differently from CONSTRAINED_RESIZE_POLICY but I like mine better :-). It is all okay except for the sum of the widths of the columns do not add up to the width of the TableView.
Here is the implementation of my resize policy class:
static class ColumnResizePolicy implements Callback<TableView.ResizeFeatures, Boolean>
{
double mTVWidth;
#Override
public Boolean call(ResizeFeatures arg0)
{
TableView tv = arg0.getTable();
Double tvWidth = tv.widthProperty().getValue();
if (tvWidth == null || tvWidth <= 0.0)
{
return false;
}
if (mTVWidth != tvWidth && arg0.getColumn() == null)
{
mTVWidth = tvWidth;
int numColsToSize = 0;
double fixedColumnsWidths = 0;
for (TableColumn col : new ArrayList<TableColumn>(tv.getColumns()))
{
if (col.isResizable() && col.isVisible())
{
++numColsToSize;
}
else if (col.isVisible())
{
fixedColumnsWidths += col.getWidth();
}
}
if (numColsToSize == 0)
return TableView.UNCONSTRAINED_RESIZE_POLICY.call(arg0);
TableColumn lastCol = null;
for (TableColumn col : new ArrayList<TableColumn>(tv.getColumns()))
{
if (col.isResizable() && col.isVisible())
{
double newWidth = (tvWidth - fixedColumnsWidths) / numColsToSize;
col.setPrefWidth(newWidth);
lastCol = col;
}
}
if (lastCol != null)
{
lastCol.setPrefWidth(lastCol.getPrefWidth()-2);
}
return true;
}
else
{
return TableView.UNCONSTRAINED_RESIZE_POLICY.call(arg0);
}
}
}
And my question (ironically after this long post) is about number 2 in this line:
lastCol.setPrefWidth(lastCol.getPrefWidth()-2);
I assume that the table width gives back the outer width including the border, hence the difference, but how do I get the inner width?
Try next:
double borderWidth = table.getBoundsInLocal().getWidth() - table.getWidth()
Have you tried getting the width of the place holder node?
I have a problem same https://community.oracle.com/message/12334734#12334734
And this implementing custom column resize policy of you was help me.
Thanks you!
Your code.
if (col.isResizable() && col.isVisible()) {
double newWidth = (tvWidth - fixedColumnsWidths) / numColsToSize;
col.setPrefWidth(newWidth);
lastCol = col;
}
I change to
if (col.isResizable() && col.isVisible()) {
double newWidth = (tvWidth - fixedColumnsWidths)*col.getPercentWidth();
col.setPrefWidth(newWidth);
lastCol = col;
}
With col is
public class PTableColumn<S, T> extends javafx.scene.control.TableColumn<S, T>
And getPercentWidth is
private DoubleProperty percentWidth = new SimpleDoubleProperty(1);