TableView: Only some column data showing up [duplicate] - javafx

This question already has answers here:
Javafx PropertyValueFactory not populating Tableview
(2 answers)
Javafx tableview not showing data in all columns
(3 answers)
Closed 5 years ago.
So I'm trying to get some TableViews to work and I've managed to get some of them working but some of my columns' data is missing and I don't quite get what's the difference that make some of the columns show up and others not. Here's the code for the initialisation of the tables:
void initTables(TableView<Layer> layerTable, TableView<Section> sectionTable, TableView<Edge> edgeTable){
// Columnas de tabla ejes
TableColumn<Edge, Integer> indexEdgeCol = new TableColumn<>("Numero"); //Not showing up
indexEdgeCol.setMaxWidth(80.);
indexEdgeCol.setCellValueFactory(new PropertyValueFactory<Edge, Integer>("Id"));
TableColumn<Edge, Double> sepEdgeCol = new TableColumn<>("Separación"); //Not showing up
sepEdgeCol.setMinWidth(110.);
sepEdgeCol.setCellValueFactory(new PropertyValueFactory<Edge, Double>("Separación"));
TableColumn<Edge, Double> loadEdgeCol = new TableColumn<>("Carga");
loadEdgeCol.setMinWidth(110.);
loadEdgeCol.setCellValueFactory(new PropertyValueFactory<Edge, Double>("Carga"));
edgeTable.setItems(getData().getEdges());
// Columnas de tabla tramos
TableColumn<Section, Integer> indexSectionCol = new TableColumn<>("Número");
indexSectionCol.setMaxWidth(100.);
indexSectionCol.setCellValueFactory(new PropertyValueFactory<Section, Integer>("Id"));
TableColumn<Section, Double> lengthSectionCol = new TableColumn<>("Longitud"); //Not showing up
lengthSectionCol.setMinWidth(120.);
lengthSectionCol.setCellValueFactory(new PropertyValueFactory<Section, Double>("Longitud"));
TableColumn<Section, Integer> slabSectionCol = new TableColumn<>("Num. Losas"); //Not showing up
slabSectionCol.setMinWidth(125.);
slabSectionCol.setCellValueFactory(new PropertyValueFactory<Section, Integer>("losas"));
sectionTable.setItems(getData().getSections());
// Columnas de tabla capas
TableColumn<Layer, Integer>indexLayerCol = new TableColumn<>("ID");
indexLayerCol.setMaxWidth(40.);
indexLayerCol.setCellValueFactory(new PropertyValueFactory<Layer, Integer>("Id"));
TableColumn<Layer, String>nameLayerCol = new TableColumn<>("Nombre");
nameLayerCol.setMinWidth(130.);
nameLayerCol.setCellValueFactory(new PropertyValueFactory<Layer, String>("Name"));
TableColumn<Layer, Double> modYoungLayerCol = new TableColumn<>("Mod. de Young");
modYoungLayerCol.setMinWidth(101.);
modYoungLayerCol.setCellValueFactory(new PropertyValueFactory<Layer, Double>("Young"));
TableColumn<Layer, Double> thickLayerCol = new TableColumn<>("Espesor");
thickLayerCol.setMinWidth(101.);
thickLayerCol.setCellValueFactory(new PropertyValueFactory<Layer, Double>("Espesor"));
layerTable.setItems(getData().getLayers());
edgeTable.getColumns().setAll(indexEdgeCol, sepEdgeCol, loadEdgeCol);
sectionTable.getColumns().setAll(indexSectionCol, lengthSectionCol, slabSectionCol);
layerTable.getColumns().setAll(indexLayerCol, nameLayerCol, modYoungLayerCol, thickLayerCol);
}
As far as I know, data is as it should be, it's only that it's not getting shown in said tables and I don't quite know what I'm doing wrong, so any help would be appreciated. Thanks in advance!
EDIT: As requested, here are my Section and Edge classes:
Section.java:
import java.util.ArrayList;
public class Section extends Object{
private final int id;
private int bloques;
private double length;
public Section(int id, int bloques, double length) {
super();
this.id = id;
this.bloques = bloques;
this.length = length;
// this.start = start;
// end = length + start;
}
public int getId(){
return id;
}
public int getBloques(){
return bloques;
}
public void setBloques(int bloques){
this.bloques = bloques;
}
public double getLength() {
return length;
}
public void setLength(double longitud) {
this.length = longitud;
}
#Override
public String toString() {
return "Section [id=" + id + ", length=" + length + ", bloques=" + bloques + "]";
}
}
Edge.java:
public class Edge extends Object{
private final int index;
private double sep;
private double carga;
public Edge(int index, double sep, double carga){
this.index = index;
this.sep = sep;
this.carga = carga;
}
public int getIndex(){
return index;
}
public void setSep(double s){
sep = s;
}
public double getSep(){
return sep;
}
public void setCarga(double c){
carga = c;
}
public double getCarga(){
return carga;
}
#Override
public String toString() {
return "Edge [index=" + index + ", separación=" + sep + ", carga=" + carga + "]";
}
}

Related

Showing the values of an ArrayList<List<String>> in a TableView (JavaFX)

I' m trying to create a TableView from a dataset consisting of a doublenested ArrayList with String values. Unfortunately, I cannot display all values in a TableView. The rows are not numbered according to the data set.
The most solutions of the internet demonstrate, that I should use a specific object instance. However, I do not work that way. Instead, I use a matrix of Strings that has an indefinite size. The data is structured as follows:
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for(int r=0; r<rows; r++) {
List<String> line = new ArrayList<String>();
for(int c=0; c<cols; c++)
line.add("r: "+r+", c: "+c);
values.add(line);
}
My best (but wrong) result was achieved with the following code:
import java.util.ArrayList;
import java.util.List;
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.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class TestApplication extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
// create values
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for (int r = 0; r < rows; r++) {
List<String> line = new ArrayList<String>();
for (int c = 0; c < cols; c++)
line.add("r: " + r + ", c: " + c);
values.add(line);
}
// show values in table
TableView<List<StringProperty>> tableView = new TableView<List<StringProperty>>();
ObservableList<List<StringProperty>> data = FXCollections.observableArrayList();
for (int c = 0; c < cols; c++) {
TableColumn<List<StringProperty>, String> col = new TableColumn<>("Col: " + c);
tableView.getColumns().add(col);
}
for (int r = 0; r < values.size(); r++) {
List<StringProperty> row = new ArrayList<StringProperty>();
for (int c = 0; c < values.get(r).size(); c++) {
TableColumn<List<StringProperty>, String> col = (TableColumn<List<StringProperty>, String>) tableView.getColumns().get(c);
String val = values.get(r).get(c);
col.setCellValueFactory(cl -> new SimpleStringProperty(new String(val)));
}
data.add(row);
}
tableView.setItems(data);
stage.setScene(new Scene(tableView, 300, 500));
stage.show();
}
}
It gives the following result:
However, the table does not show the numbered rows. I have already tried many things. But I did not get a satisfactory result. What is my mistake?
The cellValueFactory for a given column is a function that takes a wrapper containing the data for a row (i.e. the List<StringProperty>) and generates the ObservableValue (e.g. a Property) whose value is to be displayed in that row and column.
In your code you change the cellValueFactory every time you add a row, so the resulting cellValueFactory is just the one from the last row you add, and you see only the data from the last row.
You should set the cellValueFactory just once per column, and it should be a function mapping the row data to the specific value for that column.
For example, the following will give you what you need:
#Override
public void start(Stage stage) throws Exception {
// create values
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for (int r = 0; r < rows; r++) {
List<String> line = new ArrayList<String>();
for (int c = 0; c < cols; c++)
line.add("r: " + r + ", c: " + c);
values.add(line);
}
// show values in table
TableView<List<StringProperty>> tableView = new TableView<>();
ObservableList<List<StringProperty>> data = FXCollections.observableArrayList();
for (int c = 0; c < cols; c++) {
TableColumn<List<StringProperty>, String> col = new TableColumn<>("Col: " + c);
final int colIndex = c ;
col.setCellValueFactory(cd -> cd.getValue().get(colIndex));
tableView.getColumns().add(col);
}
for (int r = 0; r < values.size(); r++) {
List<StringProperty> row = new ArrayList<StringProperty>();
for (int c = 0; c < values.get(r).size(); c++) {
row.add(new SimpleStringProperty(values.get(r).get(c)));
}
data.add(row);
}
tableView.setItems(data);
stage.setScene(new Scene(tableView, 300, 500));
stage.show();
}
If the data are not going to change, you might prefer to use something lighter weight than a StringProperty, though the benefit to this small performance saving is debatable:
#Override
public void start(Stage stage) throws Exception {
// create values
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for (int r = 0; r < rows; r++) {
List<String> line = new ArrayList<String>();
for (int c = 0; c < cols; c++)
line.add("r: " + r + ", c: " + c);
values.add(line);
}
// show values in table
TableView<List<String>> tableView = new TableView<>();
for (int c = 0; c < cols; c++) {
TableColumn<List<String>, String> col = new TableColumn<>("Col: " + c);
final int colIndex = c ;
col.setCellValueFactory(cd -> new ObservableValue<String>() {
// If data are immutable, there's nothing for a listener to do, so we ignore them:
#Override
public void addListener(InvalidationListener listener) {}
#Override
public void removeListener(InvalidationListener listener) {}
#Override
public void addListener(ChangeListener<? super String> listener) {}
#Override
public void removeListener(ChangeListener<? super String> listener) {}
#Override
public String getValue() {
return cd.getValue().get(colIndex);
}
});
tableView.getColumns().add(col);
}
tableView.setItems(FXCollections.observableList(values));
stage.setScene(new Scene(tableView, 300, 500));
stage.show();
}
That's how it seems to work...i have been guided by
this.
#Override
public void start(Stage stage) throws Exception {
// create values
List<List<String>> values = new ArrayList<List<String>>();
int rows = 10;
int cols = 4;
for (int r = 0; r < rows; r++) {
List<String> line = new ArrayList<String>();
for (int c = 0; c < cols; c++)
line.add("r: " + r + ", c: " + c);
values.add(line);
}
List<String> colHeads = new ArrayList<String>();
for (int c = 0; c < cols; c++) {
String ch = "Col: " + c;
colHeads.add(ch);
}
// show values in table
List<TableColumn<Map<String, String>, String>> tcs = new ArrayList<TableColumn<Map<String, String>, String>>();
for (int c = 0; c < cols; c++) {
String ch = colHeads.get(c);
TableColumn<Map<String, String>, String> col = new TableColumn<>(ch);
col.setCellValueFactory(new MapValueFactory(ch));
tcs.add(col);
}
TableView<Map<String, String>> tableView = new TableView<>(generateDataInMap(colHeads, values));
tableView.getColumns().setAll(tcs);
stage.setScene(new Scene(tableView, 300, 500));
stage.show();
}
private ObservableList<Map<String, String>> generateDataInMap(List<String> colHeads, List<List<String>> values ) {
ObservableList<Map<String, String>> allData = FXCollections.observableArrayList();
for(int r=0; r<values.size(); r++) {
Map<String, String> dataRow = new HashMap<String, String>();
for(int c=0; c<values.get(r).size(); c++) {
String val = values.get(r).get(c);
dataRow.put(colHeads.get(c), val);
}
allData.add(dataRow);
}
return allData;
}

How to show desired number of setTickLabelsVisible false in line chart javafx

I am trying to build a time series line chart for stock market data. I am getting the input dynamically, and its been plotted on the line chart.
All I want is to plot every tick data on the graph but want to show only desired number of tick labels.
Ex: Say I started to build the graph on 10 AM, and i am plotting on 3 sec, so after 4 hours, i.e 1 PM, i want every tick to be plotted but the the label on Xaxis should be of my choice, say only 4 tick labels (10AM,11AM,12AM,1PM).
Kindly see the desired graph:
Thanks a lot in advance. :)
Code:
#FXML
private void buttonGraph(ActionEvent event) throws ParseException{
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalTime initTime = LocalTime.now();
Cluster cluster = Cluster.builder().addContactPoint("127.0.0.1").build();
Session session = cluster.connect("pass_master");
lineChart.getData().clear();
ResultSet results2 = session.execute("select count(*) as ct from pass8 where tkn ="+basic.get(tkn.getText())+" and timestmp <= "+etDate+" and timestmp >= "+stDate);
String total = null;
for( Row row : results2){
total = row.toString();
}
System.out.println(total);
System.out.println(total.substring(4, total.length()-1));
int totalrows = Integer.valueOf(total.substring(4, total.length()-1));
System.out.println("This is int value : "+totalrows);
XYChart.Series<String,Double> series = new XYChart.Series<>();
y.setAutoRanging(false);
y.setSide(Side.RIGHT);
if (graphUpdater == null) {
graphUpdater =new Thread(new Runnable() {
double min = 10000000;
double max = 0;
String chartData ="";
String invisible = "";
int i = 0;
XYChart.Data item;
public void run() {
while(running) {
try {
Quote quote = MulticastReciever.getInstance().getQuote(tkn.getText());
if (quote!=null) {
LocalDateTime now = LocalDateTime.now();
double value = quote.getLast();
if (value < min) {
min = value;
}
if (value > max) {
max = value;
}
i++;
a1.add(value);
if (i % 5 == 0 ){
chartData = dtf.format(now);
x.setTickLabelFill(Color.RED);
item = new XYChart.Data<>(chartData, value);
}
else {
invisible += (char)32;
chartData = dtf.format(now);
x.setTickMarkVisible(false);
item = new XYChart.Data<>(chartData, value);
}
series.getData().add(item);
lineChart.setCreateSymbols(false);
lineChart.setLegendVisible(false);
y.setLowerBound(min-(.001*min));
y.setUpperBound(max+(.001*max));
y.setTickLabelFill(Color.RED);
x.setTickMarkVisible(false);
y.setTickMarkVisible(false);
}
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
graphUpdater.start();
}
System.out.println("previousToken:"+previousToken+", GC:"+this);
int currentToken = Integer.valueOf(basic.get(tkn.getText()));
if (previousToken!=null) {
System.out.println("Going to unsubscribe token:"+previousToken);
MulticastReciever.getInstance().unsubscribeMarketData(previousToken);
}
MulticastReciever.getInstance().subscribeMarketData(tkn.getText(), currentToken);
previousToken = currentToken;
int factor=10;
if(totalrows>300){
factor =totalrows/300;
}
else
{
factor=1;
}
System.out.println(factor);
int count = 0;
x.setTickLabelRotation(45.0);
System.out.println("This is the property: "+x.isTickLabelsVisible());
x.setTickLabelGap(5000.0);
System.out.println("getTickLabelGap:"+x.getTickLabelGap());
x.setTickLabelGap(10.0);
System.out.println("getTickLabelGap:"+x.getTickLabelGap());
lineChart.getData().addAll(series);
a1.clear();
for(final XYChart.Data<String,Double> data :series.getData()){
data.getNode().addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
lbl.setText("X :"+data.getXValue()+"\nY :"+ String.valueOf(data.getYValue()));
Tooltip.install(data.getNode(), new Tooltip("X :"+data.getXValue()+"\nY :"+ String.valueOf(data.getYValue())));
}
});
}
cluster.close();
}

asp.net Modify list from FindAll or Where without modifying original list searched

I'm trying to create a new list from findall or where and modify that new list without it making changes to the original. When creating list2 from FindAll and a change is made to list2, it should not affect list1. How come?
Edit... Used combination of both answers which seems to be working. Any foreseen issues??? Working code edited
Edit... It's not working. A class that is a property of the object does not have its data copied... Any ideas??? I can't see why just copy or clone isn't plain and simple for a list.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Started");
List<SampleData> list1 = SampleData.MakeList(3);
for (int i = 0; i < list1.Count; i++)
{
Console.WriteLine("list1.Number => " + list1[i].Number);
Console.WriteLine("list1.Person => " + list1[i].Person);
}
List<SampleData> list2 = new List<SampleData>(list1.FindAll(m => m.Number == 1).Select(x => new SampleData().ShallowCopy())).ToList();
for (int i = 0; i < list2.Count; i++)
{
list2[i].Person = "Person " + list2[i].Number;
Console.WriteLine("list2.Number => " + list2[i].Number);
Console.WriteLine("list2.Person => " + list2[i].Person);
}
SampleData sd = list2.Find(s => s.Number == 1);
Console.WriteLine("Apartment Number" + sd.apartment.BuildingLetter); // <<<<------------------- THROWING NULL EXCEPTION FOR APARTMENT
Console.WriteLine("-------AFTER MODIFYING NEW LIST----LIST1.Person SHOULD BE NULL---");
for (int i = 0; i < list1.Count; i++)
{
Console.WriteLine("--list1.Number => " + list1[i].Number);
Console.WriteLine("--list1.Person => " + list1[i].Person);
}
for (int i = 0; i < list2.Count; i++)
{
Console.WriteLine("--list2.Number => " + list2[i].Number);
Console.WriteLine("--list2.Person => " + list2[i].Person);
}
Console.ReadLine();
System.Environment.Exit(0);
}
}
class SampleData
{
public int Number { get; set; }
public String Person { get; set; }
public Apartment apartment { get; set; }
public static List<SampleData> MakeList(int count)
{
List<SampleData> l = new List<SampleData>();
for (int i = 0; i < count; i++)
{
SampleData d = new SampleData();
d.apartment = new Apartment { RoomNumber = i, BuildingLetter = "letter-" + i };
d.Number = i;
l.Add(d);
}
return l;
}
public SampleData ShallowCopy()
{
return (SampleData)this.MemberwiseClone();
}
}
class Apartment
{
public int RoomNumber { get; set; }
public String BuildingLetter { get; set; }
}
You can use . AsNoTracking() Method in case Entity Query wheen select from DbContext or ObjectContext
List<SampleData> list2 = new List<SampleData>(list1.Where(m => m.Number == 1).AsNoTracking().ToList());
or use a Copy Contractor like that
class SampleData
{
public int Number { get; set; }
public String Person { get; set; }
public SampleData(SampleData obj)
{
This.Number=obj.Number;
This.Person=obj.Person;
..
..
}
public static List<SampleData> MakeList(int count)
{
List<SampleData> l = new List<SampleData>();
for (int i = 0; i < count; i++)
{
SampleData d = new SampleData();
d.Number = i;
l.Add(d);
}
return l;
}
}
Then
List<SampleData> list2 = new List<SampleData>(list1.Where(m => m.Number == 1).Select(x=>new SampleData(x)).ToList());
ShallowCopy is your friend.
Define a ShallowCopy() method within your SampleData class like this.
class SampleData
{
public int Number { get; set; }
public String Person { get; set; }
public static List<SampleData> MakeList(int count)
{
List<SampleData> l = new List<SampleData>();
for (int i = 0; i < count; i++)
{
SampleData d = new SampleData();
d.Number = i;
l.Add(d);
}
return l;
}
public SampleData ShallowCopy()
{
return (SampleData)this.MemberwiseClone();
}
}
Then populate list2 as follows...
List<SampleData> list2 = new List<SampleData>();
foreach (SampleData sd in list1.Where(m => m.Number == 1))
{
list2.Add(sd.ShallowCopy());
}

JavaFX TableView not Updating UI

I have a Tableview<ObservableList<Item>>, which is not updating when the underlying data is updated. Through debugging, I know that the underlying ObservableList<Item>> is being properly updated. I have ensured that all of Item's properties are visible, and in the format myFieldProperty().
Here is my table creation:
pattern= new TableView<>(mainApp.getItemList());
for (ObservableList<Item> row : pattern.getItems()) {
for (int i= pattern.getColumns().size(); i<row.size(); i++){
final int columnIndex = i ;
TableColumn<ObservableList<Item>, Color> column = new TableColumn<>();
column.setCellValueFactory( rowData ->
rowData.getValue()
.get(columnIndex).displayColorProperty()); // the Item for this cell
column.setCellFactory(col -> {
ItemCell cell = new ItemCell();
cell.setOnMouseEntered( e -> {
if (cell.getItem() != null) {
#SuppressWarnings("unchecked")
ObservableList<Item> stitchRow =
(ObservableList<Item>) cell.getTableRow().getItem();
mainApp.getRLController().setItemLabel(itemRow.get(columnIndex).toString());
}
});
cell.setOnMouseExited( e -> {
mainApp.getRLController().setItemLabel(null);
});
cell.setOnMouseClicked((MouseEvent e) -> {
Item newItem = mainApp.getTBController().getSelectedItem();
if (e.getButton() == MouseButton.PRIMARY && newItem != null) {
ObservableList<Item> itemRow =
(ObservableList<Item>) cell.getTableRow().getItem();
itemRow.set(columnIndex, newItem);
mainApp.getRLController().setItemLabel(itemRow.get(columnIndex).toString());
}
});
return cell;
});
column.setMinWidth(7);
column.setPrefWidth(7);
column.setMaxWidth(7);
pattern.getColumns().add(column);
}
}
pattern.setFixedCellSize(7);
pattern.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);`
Code for my Custom Cell Factory:
public class ItemCell extends TableCell<ObservableList<Item>, Color> {
#Override
protected void updateItem(Color color, boolean empty) {
super.updateItem(color, empty);
if (empty || color == null) {
setText(null);
setStyle(null);
} else {
int r = (int) (color.getRed() * 255);
int g = (int) (color.getGreen() * 255);
int b = (int) (color.getBlue() * 255);
this.setStyle("-fx-background-color: rgb(" + r + "," + g + "," + b + ");"
+ "-fx-border-color: black; -fx-table-cell-border-color: black;");
}
}
}
The basic problem is that the object you are changing (the item which is an element of the list representing the row) is not the property that the cell is observing for changes (the displayColorProperty() belonging to the item). You need to arrange to change the value of a property that the cell is observing.
Three possible solutions:
If possible, just change the displayColor (and other data too) of the item displayed by the cell. I.e.
cell.setOnMouseClicked((MouseEvent e) -> {
if (e.getButton() == MouseButton.PRIMARY && newItem != null) {
ObservableList<Item> itemRow =
(ObservableList<Item>) cell.getTableRow().getItem();
Item item = itemRow.get(columnIndex);
item.setDisplayColor(...);
item.set...(...);
// ...
mainApp.getRLController().setItemLabel(item.toString());
}
});
Or, replace the entire row:
cell.setOnMouseClicked((MouseEvent e) -> {
Item newItem = mainApp.getTBController().getSelectedItem();
if (e.getButton() == MouseButton.PRIMARY && newItem != null) {
ObservableList<Item> itemRow =
(ObservableList<Item>) cell.getTableRow().getItem();
ObservableList<Item> newRow = FXCollections.observableArrayList(itemRow);
newRow.set(columnIndex, newItem);
pattern.getItems().set(cell.getTableRow().getIndex(), newRow);
mainApp.getRLController().setItemLabel(newRow.get(columnIndex).toString());
}
});
Otherwise, you could make your table a TableView<ObservableList<ObjectProperty<Item>>>. This gets a little tricky but it's not too bad. This way you can just set the value of the object property to your new item.
Here's a complete example using the third technique:
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class ColorTableExample extends Application {
#Override
public void start(Stage primaryStage) {
TableView<ObservableList<ObjectProperty<Item>>> table = new TableView<>();
int NUM_ROWS = 20 ;
int NUM_COLS = 15 ;
ObservableList<ObservableList<ObjectProperty<Item>>> data = table.getItems() ;
for (int y = 0 ; y < NUM_ROWS; y++) {
ObservableList<ObjectProperty<Item>> row = FXCollections.observableArrayList();
data.add(row);
double saturation = (1.0 * y) / NUM_ROWS ;
for (int x = 0 ; x < NUM_COLS; x++) {
double hue = x * 360.0 / NUM_COLS ;
Color color = Color.hsb(hue, saturation, 1.0);
row.add(new SimpleObjectProperty<>(new Item(color)));
}
}
for (ObservableList<ObjectProperty<Item>> row : table.getItems()) {
for (int i = table.getColumns().size() ; i < row.size(); i++) {
int columnIndex = i ;
TableColumn<ObservableList<ObjectProperty<Item>>, Item> column = new TableColumn<>(Integer.toString(i+1));
column.setCellValueFactory(rowData -> rowData.getValue().get(columnIndex));
column.setCellFactory(c -> {
TableCell<ObservableList<ObjectProperty<Item>>, Item> cell = new TableCell<ObservableList<ObjectProperty<Item>>, Item>() {
#Override
public void updateItem(Item item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setStyle("");
} else {
Color color = item.getDisplayColor() ;
int r = (int) (color.getRed() * 255) ;
int g = (int) (color.getGreen() * 255) ;
int b = (int) (color.getBlue() * 255) ;
String style = String.format(
"-fx-background-color: rgb(%d, %d, %d);"
+ "-fx-border-color: black ;"
+ "-fx-table-cell-border-color: black ;"
,r, g, b);
setStyle(style);
}
}
};
cell.setOnMousePressed(evt -> {
if (! cell.isEmpty()) {
ObservableList<ObjectProperty<Item>> rowData = (ObservableList<ObjectProperty<Item>>) cell.getTableRow().getItem();
Color currentColor = cell.getItem().getDisplayColor();
double newHue = ( currentColor.getHue() + 15 ) % 360 ;
Color newColor = Color.hsb(newHue, currentColor.getSaturation(), currentColor.getBrightness());
rowData.get(columnIndex).set(new Item(newColor));
}
});
return cell ;
});
table.getColumns().add(column);
}
}
BorderPane root = new BorderPane(table, null, null, null, null);
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
}
public static class Item {
private final ObjectProperty<Color> displayColor = new SimpleObjectProperty<>() ;
public Item(Color color) {
this.displayColorProperty().set(color);
}
public final ObjectProperty<Color> displayColorProperty() {
return this.displayColor;
}
public final javafx.scene.paint.Color getDisplayColor() {
return this.displayColorProperty().get();
}
public final void setDisplayColor(final javafx.scene.paint.Color displayColor) {
this.displayColorProperty().set(displayColor);
}
}
public static void main(String[] args) {
launch(args);
}
}
(At some point, it might be easier to refactor everything so that you have an actual class representing each row in the table, instead of using a list.)
There may also be a clever workaround using an extractor for the list, but I couldn't make that work.

An interview question - implement Biginteger Multiply

Implement Biginteger Multiply
use integer array to store a biginteger
like 297897654 will be stored as {2,9,7,8,9,7,6,5,4}
implement the multiply function for bigintegers
Expamples: {2, 9, 8, 8, 9, 8} * {3,6,3,4,5,8,9,1,2} = {1,0,8,6,3,7,1,4,1,8,7,8,9,7,6}
I failed to implement this class and thought it for a few weeks, couldn't get the answer.
Anybody can help me implement it using C#/Java?
Thanks a lot.
Do you know how to do multiplication on paper?
123
x 456
-----
738
615
492
-----
56088
I would just implement that algorithm in code.
C++ Implementation:
Source Code:
#include <iostream>
using namespace std;
int main()
{
int a[10] = {8,9,8,8,9,2};
int b[10] = {2,1,9,8,5,4,3,6,3};
// INPUT DISPLAY
for(int i=9;i>=0;i--) cout << a[i];
cout << " x ";
for(int i=9;i>=0;i--) cout << b[i];
cout << " = ";
int c[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for(int i=0;i<10;i++)
{
int carry = 0;
for(int j=0;j<10;j++)
{
int t = (a[j] * b[i]) + c[i+j] + carry;
carry = t/10;
c[i+j] = t%10;
}
}
// RESULT DISPLAY
for(int i=19;i>=0;i--) cout << c[i];
cout << endl;
}
Output:
0000298898 x 0363458912 = 00000108637141878976
There is a superb algorithm called Karatsuba algorithm..Here
Which uses divide and conquer startegy..Where you can multiply large numbers..
I have implemented my it in java..
Using some manipulation..
package aoa;
import java.io.*;
public class LargeMult {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException
{
// TODO code application logic here
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter 1st number");
String a=br.readLine();
System.out.println("Enter 2nd number");
String b=br.readLine();
System.out.println("Result:"+multiply(a,b));
}
static String multiply(String t1,String t2)
{
if(t1.length()>1&&t2.length()>1)
{
int mid1=t1.length()/2;
int mid2=t2.length()/2;
String a=t1.substring(0, mid1);//Al
String b=t1.substring(mid1, t1.length());//Ar
String c=t2.substring(0, mid2);//Bl
String d=t2.substring(mid2, t2.length());//Br
String s1=multiply(a, c);
String s2=multiply(a, d);
String s3=multiply(b, c);
String s4=multiply(b, d);
long ans;
ans=Long.parseLong(s1)*(long)Math.pow(10,
b.length()+d.length())+Long.parseLong(s3)*(long)Math.pow(10,d.length())+
Long.parseLong(s2)*(long)Math.pow(10, b.length())+Long.parseLong(s4);
return ans+"";
}
else
{
return (Integer.parseInt(t1)*Integer.parseInt(t2))+"";
}
}
}
I hope this helps!!Enjoy..
Give the number you want to multiply in integer type array i.e. int[] one & int[] two.
public class VeryLongMultiplication {
public static void main(String args[]){
int[] one={9,9,9,9,9,9};
String[] temp=new String[100];
int c=0;
String[] temp1=new String[100];
int c1=0;
int[] two={9,9,9,9,9,9};
int car=0,mul=1; int rem=0; int sum=0;
String str="";
////////////////////////////////////////////
for(int i=one.length-1;i>=0;i--)
{
for(int j=two.length-1;j>=0;j--)
{
mul=one[i]*two[j]+car;
rem=mul%10;
car=mul/10;
if(j>0)
str=rem+str;
else
str=mul+str;
}
temp[c]=str;
c++;
str="";
car=0;
}
////////////////////////////////////////
for(int jk=0;jk<c;jk++)
{
for(int l=c-jk;l>0;l--)
str="0"+str;
str=str+temp[jk];
for(int l=0;l<=jk-1;l++)
str=str+"0";
System.out.println(str);
temp1[c1]=str;
c1++;
str="";
}
///////////////////////////////////
String ag="";int carry=0;
System.out.println("========================================================");
for(int jw=temp1[0].length()-1;jw>=0;jw--)
{
for(int iw=0;iw<c1;iw++)
{
int x=temp1[iw].charAt(jw)-'0';
sum+=x;
}
sum+=carry;
int n=sum;
sum=n%10;carry=n/10;
ag=sum+ag;
sum=0;
}
System.out.println(ag);
}
}
Output:
0000008999991
0000089999910
0000899999100
0008999991000
0089999910000
0899999100000
______________
0999998000001
If you do it the long-hand way, you'll have to implement an Add() method too to add up all the parts at the end. I started there just to get the ball rolling. Once you have the Add() down, the Multipy() method gets implemented along the same lines.
public static int[] Add(int[] a, int[] b) {
var maxLen = (a.Length > b.Length ? a.Length : b.Length);
var carryOver = 0;
var result = new List<int>();
for (int i = 0; i < maxLen; i++) {
var idx1 = a.Length - i - 1;
var idx2 = b.Length - i - 1;
var val1 = (idx1 < 0 ? 0 : a[idx1]);
var val2 = (idx2 < 0 ? 0 : b[idx2]);
var addResult = (val1 + val2) + carryOver;
var strAddResult = String.Format("{0:00}", addResult);
carryOver = Convert.ToInt32(strAddResult.Substring(0, 1));
var partialAddResult = Convert.ToInt32(strAddResult.Substring(1));
result.Insert(0, partialAddResult);
}
if (carryOver > 0) result.Insert(0, carryOver);
return result.ToArray();
}
Hint: use divide-and-conquer to split the int into halves, this can effectively reduce the time complexity from O(n^2) to O(n^(log3)). The gist is the reduction of multiplication operations.
I'm posting java code that I wrote. Hope, this will help
import org.junit.Test;
import static org.junit.Assert.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by ${YogenRai} on 11/27/2015.
*
* method multiply BigInteger stored as digits in integer array and returns results
*/
public class BigIntegerMultiply {
public static List<Integer> multiply(int[] num1,int[] num2){
BigInteger first=new BigInteger(toString(num1));
BigInteger result=new BigInteger("0");
for (int i = num2.length-1,k=1; i >=0; i--,k=k*10) {
result = (first.multiply(BigInteger.valueOf(num2[i]))).multiply(BigInteger.valueOf(k)).add(result);
}
return convertToArray(result);
}
private static List<Integer> convertToArray(BigInteger result) {
List<Integer> rs=new ArrayList<>();
while (result.intValue()!=0){
int digit=result.mod(BigInteger.TEN).intValue();
rs.add(digit);
result = result.divide(BigInteger.TEN);
}
Collections.reverse(rs);
return rs;
}
public static String toString(int[] array){
StringBuilder sb=new StringBuilder();
for (int element:array){
sb.append(element);
}
return sb.toString();
}
#Test
public void testArray(){
int[] num1={2, 9, 8, 8, 9, 8};
int[] num2 = {3,6,3,4,5,8,9,1,2};
System.out.println(multiply(num1, num2));
}
}

Resources