getting the changed lines jtextarea - java

I am doing a text editor which needs custom validation. Since, the content is very large i thought of validating only the lines which are changed or added. The validation errors are shown by the line numbers, like "Line: 10 cannot exceed 15 chars"
For single lines, every time the user changes iam validating the current line, keeping the row number as reference. - solved
The user can copy text and paste - multiple lines. for this, thought of getSelectionStart and getSelectionEnd. Is there a way of getting the row numbers from getSelectionStart and getSelectionEnd, so i can get starting row and ending row?
After some exprements i thought selecting the lines which are visible will solve my above statated No. 2 problem.
Rectangle would solve in getting the x, y cordinates of viewable region and wrote the code, i think i am almost finished. But, i am not getting the end row number correctly,
[code]
//editor is jtextarea
Rectangle r = editor.getVisibleRect();
Point top = new Point(r.x, r.y);
Point bottom = new Point(r.x, r.y + r.height);
int startRow = editor.viewToModel(top); /* this is working. it shows 0 at initial, then after the line reaches the end and when the scrollbar gets displayed, it shows the numbers correctly, 1,2,3...*/
int endRow = editor.viewToModel(bottom); /* this is not working, when we type, it is taking column numbers */
editorLineNo.setText(" START ROW " + startRow + " END ROW" + endRow);
[/code]
What is needed is, start row number and end row number from the viewable area of jtextarea

Is there a way of getting the row numbers ...
Element root = textArea.getDocument().getDefaultRootElement();
int row = root.getElementIndex( selectionStart ) + 1;

Utilities.getRowStart() / getRowEnd() passing the offsets.

Related

java selenium how to use if else

There is a table with application numbers and user data. at the beginning of the table, the application number at the end is a green arrow. There can be an infinite number of fields in a table and it always changes.
I need to find the green arrow by the application number and click on it accordingly.
tried to do something like
String myorder = "629/0000/000000021059";
if (myorder.equalsIgnoreCase(driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div/div[1]/table/tbody/tr/td[5]\n")).getText())){
driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div[1]/table/tbody/tr/td[18]/a/img\n")).click();
} if (myorder.equalsIgnoreCase(driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div[2]/table/tbody/tr/td[5]\n")).getText())) {
driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div[2]/table/tbody/tr/td[18]/a/img\n")).click();
} if (myorder.equalsIgnoreCase(driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div[3]/table/tbody/tr/td[5]\n")).getText())) {
driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div[3]/table/tbody/tr/td[18]/a/img\n")).click();
and so on up to 100+
The first problem is that I really don't like the option of writing if else 100 times. And there is only one digit in the diva where the id of the application and one in the digit in the diva where the green arrow is different(img)
The second problem is that no matter how I insert break; when finding the right application, he clicks on the desired arrow, but after apparently trying to continue searching the page, but the page has already changed and the error falls
(WARNING: The server did not provide any stacktrace information)
if I use the code that was attached above or just an indication of the element (which goes right after the one that turned out to be correct and the page has changed) with a note that I can not find it, if I use else if with break;
tried to do so
for (int i = 1; i < 25; i++) {
String myorder = "629/6300/000000412067";
if (myorder.equalsIgnoreCase(driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div["+ i++ +"]/table/tbody/tr/td[5]\n")).getText())) {
driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div["+ i++ +"]/table/tbody/tr/td[18]/a/img\n")).click();
break;
}
But if the item is located, then it clicks on the very first arrow in the table, and not on the one in the same column as the application number
I would really appreciate your help!
XPaths are 1-based not 0, so you are correct in thinking you need to add one, however, these two are not equal as i++ modifies the value of i (even inline like you have it), which you do twice inside your loop. Therefore the 2nd iteration of your loop i will be 3, not 1 as expected. In your loop replace i++ with i + 1 and you should be good to go.
for (int i = 1; i < 25; i++) {
String myorder = "629/3500/000000329976";
if (myorder.equalsIgnoreCase(driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div[" + i + 1 + "]/table/tbody/tr/td[5]\n")).getText())) {
driver.findElement(By.xpath("/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div[" + i + 1 + "]/table/tbody/tr/td[18]/a/img\n")).click();
break;
}
}
Unable to locate element: {"method":"xpath","selector":"/html/body/table/tbody/tr[1]/td[2]/div[2]/div/div[2]/div[2]/div/div/div/div[1]/div[31]/table/tbody/tr/td[5]
"}
So it was searching untill 31. And it's strange because i used for i < 25 and there are only 25 rows in the table.
but still dont work for me;(

divide excel sheet based on spesific cell values

i have a data sheet in excel about 950000 row with 7 col.and i want to divide it based on V5 col data. V5 holds data for time in seconds into one hour so i need to divide the data into sheets each sheet contains all value related to one minute and so on until finish splitting
if any help in do it with micro VBA thats will be good.
this is what i could do in VBA
Sub SPLIT()
Dim ws1, ws2 As Worksheet
Dim row2 As Integer
Dim rw As Range
Dim dv, fv As Variant
Set ws1 = Sheets("sheet1")
Set ws2 = Sheets.Add
row2 = 1
For Each rw In ws1.Rows
If rw.Cells(1, 5).Value2 = 00:00:59 Then " and so on until i divide each minute data rows alone"
Exit For
End If
So I've put something together for you that will get you started. You'll likely have to adjust the code for the exact time bounds that fit your requirement (which will be a good learning oppurtunity!). Note that you can take an approach of setting these bounds as either fixed or variable (i.e.: increments of minutes/seconds/hours, or the fixed bounds I have now)
To set this up you'll need three sheets in your workpaper named (1) Hours, (2) Minutes, and (3) Seconds.
As the code is set up the rows get sorted and placed into bounds depending on if it's under one minute, under one hour, or greater than one hour.
Take a stab at adjusting the code to your exact requirements and if you have any questions feel free to let me know!
Function Last_Row(Sheet_Name As String)
Last_Row = Sheets(Sheet_Name).Range("A" & Sheets(Sheet_Name).Rows.Count).End(xlUp).Row
End Function
Sub AllocateSheet()
Dim Cell As Variant
Dim Cell_Range As Range
Set Cell_Range = Range("E2:E990000")
Seperator_Second = TimeValue("00:00:01")
Seperator_Minute = TimeValue("00:01:00")
Seperator_Hour = TimeValue("01:00:00")
For Each Cell In Cell_Range
If Cell.Value >= Seperator_Hour Then
Rows(Cell.Row).Copy Destination:=Sheets("Hours").Rows(Last_Row("Hours") + 1)
ElseIf Cell.Value <= Seperator_Hour And Cell.Value >= Seperator_Minute Then
Rows(Cell.Row).Copy Destination:=Sheets("Minutes").Rows(Last_Row("Minutes") + 1)
ElseIf Cell.Value <= Seperator_Minute And Cell.Value >= Seperator_Second Then
Rows(Cell.Row).Copy Destination:=Sheets("Seconds").Rows(Last_Row("Seconds") + 1)
End If
Next Cell
End Sub
I reach into deviding minutes uisng this code any help in edit this code so i can divide the total rows in the sheet about 1000000 row also the code make the loop only to 60000 row in E colunm. I dont know why it just took from 1 to 6000 E1:E6000 and make a loop on 60000 row any help. also how i can craete new sheet to
paste to it inside code.
Option Explicit
Sub Test()
ti=TimeValue("00:00:00")
Dim Cell As Range
With Sheets(1)
For Each Cell In .Range("E1:E6000" & .Cells(.Rows.Count, "E").End(xlUp).Row)
If Cell.Value <= ti Then
.Rows(Cell.Row).Copy Destination:=Sheets("first minute").Rows(Cell.Row)
End If
Next Cell
End With
End Sub

JTable getModel().setValueAt removing first element from array

I'm encountering an odd bug while updating the contents of a JTable. I've got a two dimensional array which is storing arrays of values to be displayed by the table (I'm only displaying one row of data at a time). When the user clicks a button, the next set of values (along with the next set of column headers) is displayed, and when the user clicks another button, it displays the previous set. The problem is that the first time I call getModel().setValueAt, on the first array in the two dimensional array, it is removed.
Here's the code that updates the JTable:
for(int i = 0; i < formattedData[displayedDataSet].length - 1; i++) {
TableColumn col = displayTable.getTableHeader().getColumnModel().getColumn(i);
col.setHeaderValue(WeatherData.WEATHER_MAP_KEYS[displayedDataSet * 5 + i]);
displayTable.getTableHeader().resizeAndRepaint();
displayTable.getModel().setValueAt(formattedData[displayedDataSet][i], 0, i);
}
for(String s: formattedData[0]) {
System.out.println(s);
}
I expect the output to be the first array in formattedData, but it is the second. However, commenting out the line with displayTable.getModel().setValueAt causes the correct result to be output. Why is this happening, and how can I update the JTable while preserving my array?

Applying Gravity : 2D arrays

My program consists of a grid composed by a 2D array.
The user input deletes certain elements of the grid, leaving blank spaces.
My issue is making the elements above the blank spaces drop down.
Originaly I had an array to check if a space is blank, and if is was blank, the element above would be deleted and recreated where there used to be a blank.
My problem is, the array I used to do this was Left->Right, Top->Down (i++, j++), this leaves me with the problem of having to repeat the whole code to get newly built blank spaces. (For example, if I delete something from the 3rd row, the 2nd row would be blank, but I'd have checked the 2nd row already.
Since it would be very uneffective (including overstack errors) I decided to do the reserve, bottom->top, right->left array (i--,j--), my issue with this is that I'm getting an array out of bounds error, even though I made sure its not possible for it to go out of bounds.
Here is the piece of code which is giving problems
public static void dropBall(){
for (i =Settings.row-1;i>=0;i--){
for (j =Settings.col-1;i>=0 ; j--){
if (i <0||j<0)break;
if (Settings.grid[i+1][j]==666){
//checking if the space below has the 666 ID (666 ID equals to blank)
Settings.grid[i+1][j]=Settings.grid[i][j]; //Deleting the current blank
}
}
}
}
Note:
Settings.row and Settings.col are similar to something.lenght, meaning they have the lenght of the grid, even though the grid starts at 0.
How can I avoid the outofBounds error in this situation?
On line3:
for (j =Settings.col-1;i>=0 ; j--){
change to:
for (j =Settings.col-1;j>=0 ; j--){
and you can remove the if line after.
and start your i on Settings.row-2 instead
try this:
public static void dropBall(){
for (i =Settings.row-1;i>=0;i--){
for (j =Settings.col-1;j>=0 ; j--){
if (Settings.grid[i+1][j]==666){
//checking if the space below has the 666 ID (666 ID equals to blank)
Settings.grid[i+1][j]=Settings.grid[i][j]; //Deleting the current blank
Settings.grid[i][j] = 666;
}
}
}
}
Start from the second row at the bottom, and not from the first (since there is no row below it):
for (i = Settings.row-2 ... // instead of row-1
Remove this line (it is redundant):
if (i <0||j<0)break;

iText formatting tables

I'm generating a PDF document (for those who have seen his before, yes still) using the iText5 library. Compliments to Bruno Lowagie; I've found it to be a really great API!
However, part of my task is to format some phrases. I used a nested PdfPTable to format the data, but I'm getting bizarre spacing issues. Here is an example of the problem I'm facing:
As you can see, rows with only a couple of phrases in them tend to have huge gaps in between them. I can understand why this is happening; the rows above are stretching the table. Is there a way to only make the table as big as it needs to be, and no larger?
Code
Generating the prices collection
I'm creating the prices with this snippet:
Paragraph pricePara = new Paragraph();
pricePara.add(price);
pricePara.add(generateBreakLine());
pricePara.add(time);
pricePara.add(generateBreakLine());
allPrices.add(pricePara);
where generateBreakLine() returns an empty Paragraph object.
Adding them into the cell
I add them into the cell with the following snippet:
// 5 is just the amount of prices we can fit on one line.
PdfPTable pricesCellValue = new PdfPTable(elements.size() > 5 ? 5 : elements.size());
// Make it appear that the prices are just horizontal, as opposed to in a table.
pricesCellValue.getDefaultCell().setBorder(PdfPCell.NO_BORDER);
// Cycle through each price. Add to cell. Add cell to the table.
for (com.lowagie.text.Element elem : elements) {
PdfPCell cell = new PdfPCell((Paragraph) elem);
cell.setBorder(PdfPCell.NO_BORDER);
cell.setPadding(2);
pricesCellValue.addCell(cell);
}
return pricesCellValue;
The above snippet, I believe, is where I can make sure the table is only as wide as it needs to be, as opposed to filling up all the space around it. How would I go about doing that?
Solved
Found a simple way of fixing it. In stead of changing the amount of columns based on the number of prices, I make sure the column number is always 5, and then append empty cells on:
if(elements.size() < 5)
{
int diff = 5 - elements.size();
for(int x = 0; x < diff; x++)
{
pricesCellValue.addCell(new Paragraph(" "));
}
}

Categories