Gregorian Calendar JavaFX - java

I am stuck trying to figure out this question. It is about JavaFX control choosing the name of the day for the month, number day and year when pressing enter.. I even tried using object oriented to solve the problem. The question is in a picture link. Here is the question in this link.
New EDIT and Code: I am off by one day for getting the day of the week for example January 1, 2012 should be day 1 as the answer in console: Day of Week: 1 not 2.
public class DayOfWeek extends Application {
private String[] months = { "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER",
"OCTOBER", "NOVEMBER", "DECEMBER" };
private String[] days = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16",
"17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31" };
String s1 = "";
int k = 0;
String s2 = "";
int x = 0;
#Override
public void start(Stage primaryStage) {
// add a gridpane
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
// add a label for original message top left side
Label label1 = new Label("Month: ");
GridPane.setConstraints(label1, 0, 0);
ListView<String> lv = new ListView<>(FXCollections.observableArrayList(months));
lv.setPrefSize(100, 100);
lv.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
GridPane.setConstraints(lv, 1, 0);
Label label2 = new Label("Day: ");
GridPane.setConstraints(label2, 2, 0);
ListView<String> lvdays = new ListView<>(FXCollections.observableArrayList(days));
lvdays.setPrefWidth(50);
lvdays.setPrefHeight(75);
lv.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
GridPane.setConstraints(lvdays, 3, 0);
Label label3 = new Label("Year: ");
GridPane.setConstraints(label3, 4, 0);
TextField textfield3 = new TextField();
GridPane.setConstraints(textfield3, 5, 0);
lv.setOnMouseClicked(e -> {
s1 = lv.getSelectionModel().getSelectedItem();
k = lv.getSelectionModel().getSelectedIndex();
System.out.println(lv.getSelectionModel().getSelectedItem());
});
lvdays.setOnMouseClicked(e2 -> {
s2 = lvdays.getSelectionModel().getSelectedItem();
x = lvdays.getSelectionModel().getSelectedIndex();
System.out.println(lvdays.getSelectionModel().getSelectedItem());
});
textfield3.setOnKeyPressed(e3 -> {
if (e3.getCode() == KeyCode.ENTER) {
GregorianCalendar cal2 = new GregorianCalendar(textfield3.getLength(), k, x);
System.out.println("Day of Week: " + cal2.get(Calendar.DAY_OF_WEEK));
}
});
// add it to the parent
grid.getChildren().addAll(label1, lv, label2, lvdays, label3, textfield3);
// set a scene and place show it
Scene scene = new Scene(grid, 600, 200);
primaryStage.setTitle("Day of Week");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}

First, don’t fill strings into your list views. Fill the month list view from Month.values() and the days of the month with Integer objects. This will be more convenient when taking the selected item out and will save you of declaring the arrays at the top of the class.
In the following I am assuming that instead of s1 you have a variable named m of type Month for the month and s2 has type Integer (you should find a better name).
String yearText = textfield3.getText();
try {
int year = Integer.parseInt(yearText);
LocalDate date = LocalDate.of(year, m, s2);
System.out.println("Day of Week: " + date.getDayOfWeek());
} catch (NullPointerException | NumberFormatException | DateTimeException e) {
System.out.format("Not a valid date: %s %s %d", yearText, m, s2);
}
Avoid using GregorianCalendar. That class was poorly designed and is fortunately long outdated. Instead use LocalDate from java.time, the modern Java date and time API.
Opposite the GregorianCalendar constructor the LocalDate.of method will throw an exception if you pass invalid values to it, such as for example 29 of February 2019. This will help you report the invalid date to the user as required.
What went wrong in your code?
You were using textfield3.getLength() for the year. Assuming a four digit year was entered this would give you year 4 (that’s a couple of millennia ago now).
When you used lvdays.getSelectionModel().getSelectedIndex() for the day of month, you got the 0-based index in the list in the list view. So when the user picked 1 you were getting 0, etc.
Other tip: Learn to invent good variable names. It really makes the difference between valuable and worthless code. Also when asking a question on Stack Overflow, people will be more likely to help you if they can read your code easily, which they cannot with the variable names s1, s2, k and x.
Link
Oracle tutorial: Date Time explaining how to use java.time.

Related

Unable to sort date in java using android studio

I want to sort my array based on their latest dates. I am retrieving the date as a string from a text file. My text file is a follows:
title:High Five
date:02-04-2019
title:Roly Poly
date:04-07-2019
title:Barney
date:11-01-2016
I want to display them as follows:
title:Roly Poly
date:04-07-2019
title:High Five
date:02-04-2019
title:Barney
date:11-01-2016
I have use the following method:
public class mydateCompare implements Comparator<Cartoon>
{
#Override
public int compare(Cartoon o1, Cartoon o2) {
SimpleDateFormat dateFormat=new SimpleDateFormat("dd-mm-yyyy");
String dateinString = o1.getDate();
String dateinS = o2.getDate();
try {
Date date = dateFormat.parse(dateinString);
Date dt = dateFormat.parse(dateinS);
} catch (ParseException e) {
e.printStackTrace();
}
return dateinString.compareTo(dateinS);
}
}
My output from the above method is:
title:High Five
date:02-04-2019
title:Roly Poly
date:04-07-2019
title:Barney
date:11-01-2016
Can you guys tell me what I need to do the get my desired output? Thank you.
Currently, you are comparing the strings which sorts the entries incorrectly. I suggest that you parse the strings to LocalDate from the Java 8 Date/Time API with a custom formatter. The (unchecked) exception should be handled outside the comparator since you cannot compare the entries without the parsed date.
As a side-note, it would be better to already use parsed dates in your Cartoon object.
Here is an example for the comparator:
public class CartoonDescendingDateComparator implements Comparator<Cartoon> {
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy");
#Override
public int compare(Cartoon o1, Cartoon o2) {
LocalDate d1 = LocalDate.parse(o1.getDate(), DATE_FORMATTER);
LocalDate d2 = LocalDate.parse(o2.getDate(), DATE_FORMATTER);
return d2.compareTo(d1); // descending order
}
}
Here is a test case with your data:
List<Cartoon> cartoons = new ArrayList<>();
cartoons.add(new Cartoon("High Five", "02-04-2019"));
cartoons.add(new Cartoon("Roly Poly", "04-07-2019"));
cartoons.add(new Cartoon("Barney", "11-01-2016"));
cartoons.sort(new CartoonDescendingDateComparator());
cartoons.forEach(c -> System.out.println("title:" + c.getTitle() + "\ndate:" + c.getDate()));
Output:
title:Barney
date:11-01-2016
title:High Five
date:02-04-2019
title:Roly Poly
date:04-07-2019
Copy the class below,
internal class CartoonsSorter : Comparator<Cartoon> {
private val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.getDefault())
override fun compare(o1: Cartoon, o2: Cartoon): Int {
var firstObjDate = Date()
var secondObjDate = Date()
try {
firstObjDate = dateFormat.parse(o1.date) ?: Date()
secondObjDate = dateFormat.parse(o2.date) ?: Date()
} catch (e: ParseException) {
e.printStackTrace()
}
return secondObjDate.compareTo(firstObjDate)
}
}
Use it in the below way,
Collections.sort(yourArray, CartoonsSorter())
Output for the above:
Before Sorting:
[
{
"date": "02-04-2019",
"title": "High Five"
},
{
"date": "04-07-2019",
"title": "Roly Poly"
},
{
"date": "11-01-2016",
"title": "Barney"
}
]
After Sorting:
[
{
"date": "04-07-2019",
"title": "Roly Poly"
},
{
"date": "02-04-2019",
"title": "High Five"
},
{
"date": "11-01-2016",
"title": "Barney"
}
]

Java - Read data from a json with the JSON library according to an object

I have a JSON with some data and I would like to print as follows
10 REGISTER 1, KP SUM 2081,606
20 REGISTER 2 CH SUM 0,22
Where the general sum is calculated by the total sum of the items according to the code.
Following the rule, first multiply the quantity by the unit and then add all the items that have the same code.
Example:
code 10
SUM = 0,0200000 * 7,40 + 10,0000000 * 200,31 + 0,5690000 * 40,19 + 0,7890000 * 70,33
The same goes for the other codes that appear in JSON
My JSON
[
{
"code": 10,
"description": "REGISTER 1",
"unity": "KP",
"typeItem": "I",
"itemCode": 1,
"descriptionItem": "ITEM",
"unityItem": "UN",
"quantity": "0,0200000",
"valueUnity": "7,40"
},
{
"code": 10,
"description": "REGISTER 1",
"unity": "KP",
"typeItem": "I",
"codeItem": 2,
"descriptionItem": "ITEM 2",
"unityItem": "UN",
"quantity": "10,0000000",
"valueUnity": "200,31"
},
{
"code": 10,
"description": "REGISTER 1",
"unity": "KP",
"typeItem": "I",
"codeItem": 88248,
"descriptionItem": "ITEM 3",
"unityItem": "H",
"quantity": "0,5690000",
"valueUnity": "40,19"
},
{
"code": 10,
"description": "REGISTER 1",
"unity": "KP",
"typeItem": "I",
"codeItem": 88267,
"descriptionItem": "ITEM 4",
"unityItem": "N",
"quantity": "0,7890000",
"valueUnity": "70,33"
},
{
"code": 20,
"description": "REGISTER 2",
"unity": "CH",
"typeItem": "I",
"codeItem": 1,
"descriptionItem": "ITEM 1",
"unityItem": "H",
"quantity": "30,0000000",
"valueUnity": "0,17"
},
{
"code": 20,
"description": "REGISTER 2",
"unity": "CH",
"typeItem": "I",
"codeItem": 2,
"descriptionItem": "ITEM 2",
"unityItem": "H",
"quantity": "3,0000000",
"valueUnity": "0,07"
}
]
My class Java
public class MyJson {
#SerializedName("code")
#Expose
private Integer code;
#SerializedName("description")
#Expose
private String description;
#SerializedName("unity")
#Expose
private String unity;
#SerializedName("typeItem")
#Expose
private String typeItem;
#SerializedName("codeItem")
#Expose
private Integer codeItem;
#SerializedName("descriptionItem")
#Expose
private String descriptionItem;
#SerializedName("unityItem")
#Expose
private String unityItem;
#SerializedName("quantity")
#Expose
private String quantity;
#SerializedName("valueUnity")
#Expose
private String valueUnity;
private Double total;
}
My Program
public static void main(String[] args) {
Gson gson = new Gson();
try {
File jsonFile = new File("C:\\my_json.json");
InputStreamReader reader = new InputStreamReader(new FileInputStream(jsonFile), "UTF-8");
BufferedReader jsonBuffer = new BufferedReader(reader);
MyJson[] myJsonArray = gson.fromJson(jsonBuffer, MyJson[].class);
BigDecimal valueUnity = BigDecimal.ZERO;
BigDecimal sumTotal = BigDecimal.ZERO;
//
Set<MyJson> list = new HashSet<>();
for(MyJson myJson : myJsonArray) {
if(checkStringNullOrEmpty(myJson.getQuantity()) && checkStringNullOrEmpty(myJson.getValueUnity())) {
if(myJson.getCode().equals(myJson.getCode())) {
String value1 = myJson.getQuantity().replaceAll( "," , "." ).trim();
String value2 = myJson.getValueUnity.replaceAll( "," , "." ).trim();
BigDecimal quantity = new BigDecimal(value1);
BigDecimal valueUnit = new BigDecimal(value2);
valueUnity = quantity.multiply(valueUnit);
somaTotal = sumTotal.add(valueUnity);
String resultado = String.format(Locale.getDefault(), "%.2f", valueUnity);
String sumTotal2 = String.format(Locale.getDefault(), "%.2f", sumTotal);
myJson.setTotal(new Double(sumTotal2.replaceAll( "," , "." ).trim()));
list.add(myJson);
}
}
}
for(MyJson myJson : list) {
StringBuilder builer = new StringBuilder();
builer.append(myJson.getCode()).append(" ");
builer.append(myJson.getDescription().toUpperCase()).append(" ");
builer.append(myJson.getUnity().toUpperCase()).append(" ");
builer.append(myJson.getTotal());
System.out.println(builer.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static boolean checkStringNullOrEmpty(String value) {
if(!value.isEmpty()) {
return true;
} else {
return false;
}
}
Exit program
The calculation is being done wrong when using the Set
10 REGISTER 1, KP SUM 130,33
20 REGISTER 2 CH SUM 439,18
You cannot keep track of multiple running totals (i.e. one for each code) using one total. Instead you will need one total for each different code.
I would recommend that you use a Map<Integer, MyJson> for this purpose. This would store a number of MyJson objects which you could look up by their code. When handling each MyJson object, you check to see if you already have a MyJson object with the same code: if you do then you add to its total, otherwise you add your MyJson object to the map.
Get rid of your Set<MyJson> variable (which you have somewhat confusingly named list) and replace it with the following
Map<Integer, MyJson> jsonsByCode = new LinkedHashMap<>();
(You can use a HashMap<> instead of a LinkedHashMap<> here: I chose to use a LinkedHashMap<> because it keeps its entries in the same order they were inserted into it.)
Then, replace all lines from somaTotal = sumTotal.add(valueUnity); to list.add(myJson); with
if (jsonsByCode.containsKey(myJson.getCode())) {
// We've seen this code before, so add the value
// to the total.
MyJson matchingJson = jsonsByCode.get(myJson.getCode());
matchingJson.setTotal(matchingJson.getTotal() + valueUnity.doubleValue());
} else {
// First time seeing this code, so set its total
// and add it to the map.
myJson.setTotal(valueUnity.doubleValue());
jsonsByCode.put(myJson.getCode(), myJson);
}
(Note that BigDecimal values such as valueUnity have a .doubleValue() method on them, which is the easiest way to convert them to a double.)
Then, in the for loop below, where you are printing out the values, replace list with jsonsByCode.values().
I made these changes to your program and it generated the following output:
10 REGISTER 1 KP 2081.60648
20 REGISTER 2 CH 5.31
Incidentally, your code also contains the following if statement:
if(myJson.getCode().equals(myJson.getCode())) {
// ....
}
You are comparing myJson.getCode() against itself, so this condition will always be true (unless of course myJson.getCode() returns null, in which case you get a NullPointerException). You can just get rid of this check, it doesn't do anything useful.

.net list group by in java 8?

I got a task that migrate code from C# to java 8.
And I have a problem with the C# codes below.
List<Log> lst = LogRepository.GetLogs(DateTime.Now.AddDays(-2), DateTime.Now);
return lst
.GroupBy(x => new { x.Title, x.ID })
.Select(x => x.OrderByDescending(y => y.DataChangeTime).FirstOrDefault())
.ToList();
Yes ,the method GroupBy is easy,I know what is it doing.
But ,I can't figure out what is this series methods doing and what results will it return ?
Finally,can anyone give me a java version solution ?
The C#-code is already explained by #Rango. Assuming the following design for the Log-class in C#
class Log
{
public String title;
public String ID;
public DateTime dataChangeTime;
public String whatever;
...
}
and an analogous Java-class (with e.g. LocalDateTime instead of DateTime), a Java-expression providing the same result is:
Comparator<Log> comparator = (Log l1, Log l2) -> l2.dataChangeTime.compareTo(l1.dataChangeTime); // sort descending
List<Log> resultantList = initialList.stream()
.collect(Collectors.groupingBy(l -> l.title + l.ID)).values().stream() // group according to title and id
.map(logs -> logs.stream().sorted(comparator).findFirst().get()) // sort and take the first
.collect(Collectors.toList()); // create the list
The expression groups all Log-objects together having the same title and ID, i.e. the same value of l.title + l.ID. If the grouping-condition is more complex then it might make more sense to define a class which represents the grouping, e.g.
class LogGroup {
private String Title;
private String ID;
public LogGroup(String Title, String ID) {
this.Title = Title;
this.ID = ID;
}
#Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof LogGroup)) {
return false;
}
LogGroup logGroup = (LogGroup) o;
return Objects.equals(Title, logGroup.Title) &&
Objects.equals(ID, logGroup.ID);
}
#Override
public int hashCode() {
return Objects.hash(Title, ID);
}
}
It's crucial that the class implements both, the equals- and the hashCode-method (i.e the implementation of the equals-method alone is not enough).
Using that class the Java-expression becomes:
Comparator<Log> comparator = (Log l1, Log l2) -> l2.dataChangeTime.compareTo(l1.dataChangeTime);
List<Log> resultantList = initialList.stream()
.collect(Collectors.groupingBy(l -> new LogGroup(l.title, l.ID))).values().stream()
.map(logs -> logs.stream().sorted(comparator).findFirst().get())
.collect(Collectors.toList());
A list like
private static List<Log> getInitialList() {
List<Log> initialList = new ArrayList<>();
initialList.add(new Log("Title 6", "ID 6", LocalDateTime.of(2017, 1, 18, 23, 15, 12), "A"));
initialList.add(new Log("Title 3", "ID 3", LocalDateTime.of(2005, 4, 20, 16, 10, 10), "B"));
initialList.add(new Log("Title 1", "ID 1", LocalDateTime.of(2010, 10, 25, 3, 5, 2), "C"));
initialList.add(new Log("Title 2", "ID 2", LocalDateTime.of(2018, 2, 18, 21, 13, 32), "D"));
initialList.add(new Log("Title 3", "ID 3", LocalDateTime.of(2016, 5, 16, 15, 23, 15), "E"));
initialList.add(new Log("Title 1", "ID 1", LocalDateTime.of(2012, 2, 8, 14, 46, 28), "F"));
initialList.add(new Log("Title 6", "ID 6", LocalDateTime.of(1996, 1, 28, 22, 26, 34), "G"));
initialList.add(new Log("Title 3", "ID 3", LocalDateTime.of(2007, 4, 15, 2, 5, 55), "H"));
initialList.add(new Log("Title 6", "ID 3", LocalDateTime.of(2018, 1, 15, 20, 15, 10), "I"));
return initialList;
}
is processed by both expressions as follows
Title 1 ID 1 2012-02-08 14:46:28 F
Title 3 ID 3 2016-05-16 15:23:15 E
Title 2 ID 2 2018-02-18 21:13:32 D
Title 6 ID 6 2017-01-18 23:15:12 A
Title 6 ID 3 2018-01-15 20:15:10 I
The resultant list itself isn't sorted (which would be easy to implement with Collections.sort(...)), but that applies also to the C#-output.

Setting bar colors in Vaadin Charts for ListSeries (on BasicColumn)

Using Vaadin 6.x and Vaadin Charts, I am playing around with BasicColumn (http://demo.vaadin.com/charts/#BasicColumn).
I want the user to choose bar column colors on the screen. I correctly get the color from user however I couldn't manage to set colors of the column bars dynamically.
I know it is pretty simple with DataSeriesItem however there is no color attribute for ListSeries.
Is there a way to set the colors of bars on BasicColumn?
This is my implementation for DataSeries. But as you set the color on PlotOptionsColumn it should as well work for ListSeries:
pingDropoutSr=new DataSeries();
PlotOptionsColumn dropOptions= new PlotOptionsColumn();
dropOptions.setColor( SolidColor.GREEN ); //Color is an interface only
pingDropoutSr.setPlotOptions(dropOptions);
I faced the same issue here, and found a solution using PlotOptionsColumn.
//Hard Coded Values
String months[] = { "DataSet 1", "DataSet 2", "DataSet 3", "DataSet 4", "DataSet 5"};
int dataArray[][] = {
{ 8, 13, 7, 4 },
{ 23, 1, 30, 7 },
{ 37, 3, 22, 2 },
{ 13, 23, 4, 3 },
{ 3, 10, 9, 5 },
};
int counter = 0;
// Data series for each numeric column in the table
for (int month = 0; month < 4; month++) {
ListSeries series = new ListSeries();
PlotOptionsColumn options = new PlotOptionsColumn();
options.setColor(colors[counter++]);
series.setPlotOptions(options);
series.setName(months[month]);
// The rows of the table
for (int data = 0; data < dataArray.length; data++) {
series.addData(dataArray[data][month]);
}
conf.addSeries(series);
}

Inserting object with different values in a ArrayList

I have a JFrame where I insert some informations, these informations I send to a object called "macro". When I hit a JButton "macro" is insert in a ArrayList, called "listaJFP". When I enter with the first informations like, name "Murilo", id "1", and hit the button, my ArrayList receives the correct information, but when I try to insert another name like "Joao", id "2", my ArrayList receives in the first index [0] Joao, 2, and second index[1] Joao, 2. Instead of [0]Murilo,1 and [1]Joao,2. I looked for this problem and I saw someone talking about the reference of the object, in other words, when I change the values of my object "macro" at the same time the values of my ArrayList are changed. Can someone help me, please ? Thanks for the attention !
This is in my class JFramePrincipal:
Macro macro = new Macro();
private List<Macro> listaJFP = new ArrayList<Macro>();
This is in my JButton actionPerformed:
listaJFP.add(macro);
JFrameTabela jfT = new JFrameTabela(listaJFP);
I will try to put more code:
public class JFramePrincipal extends javax.swing.JFrame {
private List<Macro> listaJFP = new ArrayList<Macro>();
Macro macro = new Macro();
String[] arrayNodeName;
String[] listaVelocidade = new String[]{"1024", "1984"};
String[] listaSlot = new String[]{"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"};
String[] listaModule86x0 = new String[]{"0", "1"};
String[] listaModule8609 = new String[]{"3", "4"};
String[] listaPort = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"};
String[] listaPortFeGe = new String[]{"0", "1", "2", "3", "4", "5", "6", "7"};
String[] nodeType = new String[]{"8609", "8630", "8660"};
private void jButtonGerarMacroActionPerformed(java.awt.event.ActionEvent evt) {
try {
if (jCheckBoxFSP.isSelected() == true) {
macro.setVpnName(jFormattedTextFieldFSP.getValue().toString());
} else if (jCheckBoxSP.isSelected() == true) {
macro.setVpnName(jFormattedTextFieldSP.getValue().toString());
}
macro.velocidade = jComboBoxVelocidade.getSelectedItem().toString();
if (jTextVLAN.isEnabled() == true) {
int vlanInt;
boolean ok = false;
vlanInt = Integer.parseInt(jTextVLAN.getText());
do {
if (vlanInt >= 1 && vlanInt <= 4094) {
macro.vlan = jTextVLAN.getText();
gerar();
jButtonExecutarMacro.setEnabled(true);
} else {
JOptionPane.showMessageDialog(null, "VLAN deve ser maior do que 0 e menor do que 4094", "Mensagem", JOptionPane.ERROR_MESSAGE);
jTextVLAN.grabFocus();
jButtonExecutarMacro.setEnabled(false);
}
} while (ok);
} else {
macro.vlan = null;
gerar();
jButtonExecutarMacro.setEnabled(true);
jButtonGerarMacro.setEnabled(false);
}
private void jButtonExibirResultadoActionPerformed(java.awt.event.ActionEvent evt) {
if(jCheckBoxE1.isSelected() == true){
listaJFP.add(macro);
Macro macro = new Macro();
JFrameTabela jfT = new JFrameTabela(listaJFP);
}
Did you make sure to create a new Macro for every input from GUI
You have to Create a new Macro like this
public void actionPerformed(ActionEvent e){
Macro macro = new Macro();
listaJFP.add(macro);
}
// so it create a totally new Macro object everytime
Edit: After OP edit with more code
You need to create to new Macro inside to the first ActionPerformed because that's where you're manipulating the data. And why do you have two different actionperformed for a similar task?

Categories