I'm getting a "TableView(ScrollView).calculateVerticalScrollAmount(XYRect)" exception when trying to create a table using the following code. I've tried simplifying the fields, but nothing seems to help, any thoughts? The code is similar to that in the Tables Demo supplied with the BB 6 SDK.
It looks like a layout issue, but I can't seem to pin down the error.
// Create and apply style
RegionStyles style = new RegionStyles(BorderFactory.createSimpleBorder(new XYEdges(1, 1, 1, 1), Border.STYLE_SOLID), null, null,
null, RegionStyles.ALIGN_LEFT, RegionStyles.ALIGN_TOP);
// Create the view and controller
TableView tableView = new TableView(_tableModel);
TableController tableController = new TableController(_tableModel, tableView);
// Set the controller focus policy to highlight rows
tableController.setFocusPolicy(TableController.ROW_FOCUS);
// Set the behaviour of the controller when a table item is clicked
tableController.setCommand(new CommandHandler()
{
/**
* #see CommandHandler#execute(ReadOnlyCommandMetadata, Object)
*/
public void execute(ReadOnlyCommandMetadata metadata, Object context)
{
Dialog.alert("Command Executed");
}
}, null, null);
tableView.setController(tableController);
// Create a DataTemplate that suppresses the third column
DataTemplate dataTemplate = new DataTemplate(tableView, 2, 3)
{
/**
* #see DataTemplate#getDataFields(int)
*/
public Field[] getDataFields(int modelRowIndex)
{
Object[] data = (Object[]) ((TableModel) getView().getModel()).getRow(modelRowIndex);
Field[] fields = new Field[4];
fields[0] = new BitmapField((Bitmap) data[0]);
fields[1] = new LabelField(data[1], Field.FOCUSABLE);
fields[2] = new LabelField(data[2], Field.FOCUSABLE);
fields[3] = new LabelField(data[3], Field.FOCUSABLE);
return fields;
}
};
// Set up regions
dataTemplate.createRegion(new XYRect(0, 0, 1, 2), style);
dataTemplate.createRegion(new XYRect(1, 0, 2, 1), style);
dataTemplate.createRegion(new XYRect(1, 1, 1, 1), style);
dataTemplate.createRegion(new XYRect(2, 1, 1, 1), style);
// Specify the size of each column by percentage, and the height of a row
dataTemplate.setColumnProperties(0, new TemplateColumnProperties(15, TemplateColumnProperties.PERCENTAGE_WIDTH));
dataTemplate.setColumnProperties(1, new TemplateColumnProperties(15, TemplateColumnProperties.PERCENTAGE_WIDTH));
dataTemplate.setColumnProperties(2, new TemplateColumnProperties(70, TemplateColumnProperties.PERCENTAGE_WIDTH));
dataTemplate.setRowProperties(0, new TemplateRowProperties(ROW_HEIGHT));
dataTemplate.setRowProperties(1, new TemplateRowProperties(ROW_HEIGHT));
// Apply the template to the view
tableView.setDataTemplate(dataTemplate);
dataTemplate.useFixedHeight(true);
add(tableView);
Not sure if you are still struggling with this - may be benefits for others
in the statement
DataTemplate dataTemplate = new DataTemplate(tableView, 2, 3)
you have initialized the DataTemplate with 2 rows and 3 columns (assuming you want to suppress 4th column). But inside the function getDataFields you are returning 4 fields.
This is causing the crash (the internal code is not monkey proof).
Drop the 4th field from array and it should work.
Related
I hope the kind people here can help me with my CSV situation. I only need to read the first 3 columns in the CSV that i'm using. I have no control in the number of columns that the CSV file has and there are no headers available. I tried using the partial read with CSVBeanReader (https://super-csv.github.io/super-csv/examples_partial_reading.html) but I keep getting the "nameMapping array and the number of columns read" error. I would like to ask if the partial reading example works for the supercsv version 2.4.0 which i'm currently using. See below the code I used which I patterned similar to the partial read example
public class MainPartialRead {
public void partialRead() throws Exception {
ICsvBeanReader beanReader = null;
String csv_filename = "test2.csv";
try {
beanReader = new CsvBeanReader(new FileReader(csv_filename), CsvPreference.STANDARD_PREFERENCE);
beanReader.getHeader(true); // skip past the header (we're defining our own)
System.out.println("beanreader Length: " + beanReader.length());
// only map the first 3 columns - setting header elements to null means those columns are ignored
final String[] header = new String[]{"column1", "column2", "column3", null, null, null, null, null,
null, null};
// no processing required for ignored columns
final CellProcessor[] processors = new CellProcessor[]{new NotNull(), new NotNull(),
new NotNull(), null, null, null, null, null, null, null};
beanCSVReport customer;
while ((customer = beanReader.read(beanCSVReport.class, header, processors)) != null) {
System.out.println(String.format("lineNo=%s, rowNo=%s, customer=%s", beanReader.getLineNumber(),
beanReader.getRowNumber(), customer));
}
} finally {
if (beanReader != null) {
beanReader.close();
}
}
}
Here is the sample CSV file i'm using:
466,24127,abc,53516
868,46363,hth,249
you did not mention the complete error message.
Exception in thread "main" java.lang.IllegalArgumentException: the nameMapping array and the number of columns read should be the same size
(nameMapping length = 10, columns = 4)
From this it is very clear what the issue is. You have just 4 columns in the csv file but you have mentioned mapping for 10 columns, 7 of them null.
Removing 6 nulls from header and processors fixes the issue.
another point to note. The following code skips the first line assuming it to be header as you instructed but in fact it is not a header row. You should not call this method.
beanReader.getHeader(true);
I am developing an Application in Android Studio to that prints how many of each item you can buy with the given amount of currency. It printed flawlessly when run as a Java program in Eclipse but I can not get it to print more than one line in the TextView Box.
I've noticed it will pick the most Expensive item you can afford 1 of and print it alone, leading me to believe it runs through the list and only prints the last one that passes as affordable. I've read about needing to use a StringBuilder and such but have found little information on how to convert my Array.asList over to this. Here is my code.
gCalc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText diamondInput = (EditText) findViewById(R.id.diamondInput);
try {
int diamonds = Integer.parseInt(diamondInput.getText().toString());
List<Gifts> gift = Arrays.asList(new Gifts[]{new Gifts("Gold star", 10), new Gifts("Love Bear", 10), new Gifts("Lillies", 10), new Gifts("Box Of Chocolate", 20), new Gifts("Taco", 20), new Gifts("Thumbs Up", 30), new Gifts("Panda", 40), new Gifts("Beer", 40), new Gifts("Patriot", 52), new Gifts("Eagle", 52), new Gifts("Gold Chain", 80), new Gifts("Roses", 100), new Gifts("Champagne", 100), new Gifts("Snow", 100), new Gifts("Candy", 100), new Gifts("Kiss", 200), new Gifts("Candy Hearts", 250), new Gifts("Peach", 300), new Gifts("EggPlant", 300), new Gifts("Fireworks", 500), new Gifts("GemDrop", 600), new Gifts("Crown", 600), new Gifts("Cupcakes", 700), new Gifts("Heart Balloon", 800), new Gifts("Sports Car", 1000), new Gifts("Smoke Rings", 1000), new Gifts("purple Diamond", 2500), new Gifts("Cupid", 5000), new Gifts("Gold Watch", 5000), new Gifts("Castle", 5000), new Gifts("Yacht", 10000), new Gifts("Jet", 20000)});
double coins = (double) diamonds / 2.5D;
Iterator var5 = gift.iterator();
while(var5.hasNext()) {
Gifts Gifts = (Gifts)var5.next();
int qty = (int)Gifts.getQty(coins);
if(qty > 0) {
result.setText("You can buy " + qty + " " + Gifts.name);
}
}
}
catch (Exception e) {
// friendly error to the user: field is incorrect
}
I need it to print as this EX:
You can buy X amount of Y
You can buy X amount of Y
You can buy X amount of Y
:end
Printing every item that can be bought and it's quantity.
If you look into Android API documentation (https://developer.android.com/reference/android/widget/TextView.html) , this is what it states:
void setText (CharSequence text) - sets the text to be displayed. - this means that each time you call this method, new text overrides the old one.
It seems that you are looking for append() method:
void append(CharSequence text) - convenience method to append the specified text to the TextView's display buffer, upgrading it to EDITABLE if it was not already editable. append() method doesn't override previously set text.
Another way to append text to the previously stored in TextView is to combine these methods:
result.setText(result.getText() + "text that you want to append to the previous one")
I am unable to populate a JavaFX TableView object with my own data. I have attempted to modify the code found here to suit the needs of my program.
I added the table used in that tutorial, and it displays properly. I copied that code to create a second table, but cannot get my data to display in that second table.
I believe that I have properly modified the code to accept data from my SNMPInterface class. I attempt to populate my table with static data, and later with data read in from a file. Neither process works, though either will create the columns with the proper headers.
My full project can be found on GitHub.
Initially, I create a TableView object of 'SNMPInterface' class objects:
private TableView< SNMPInterface > interfaceTableView = new TableView<>();
I then create an ObservableList of SNMPInterface objects:
private final ObservableList< SNMPInterface > interfaceData =
FXCollections.observableArrayList(
new SNMPInterface( "99", "testlo" ),
new SNMPInterface( "98", "testeth1" ),
new SNMPInterface( "97", "testeth2" ),
new SNMPInterface( "96", "testbond0" )
);
Later, I create a column for the 'ifIndex' data member:
TableColumn< SNMPInterface, String > ifIndexCol = new TableColumn<>( "Index" );
ifIndexCol.setCellValueFactory( new PropertyValueFactory<>( "ifIndex" ) );
...and the second column for 'ifDescr':
TableColumn ifDescrCol = new TableColumn( "Description" );
ifDescrCol.setCellValueFactory( new PropertyValueFactory<>( "ifDescr" ) );
I then try to add it to the GridPane (named rootNode):
interfaceTableView.setItems( interfaceData );
interfaceTableView.getColumns().setAll( ifIndexCol, ifDescrCol );
rootNode.add( interfaceTableView, 0, 7, 2, 1 );
...but that does not work.
I have a loop to verify that the data is available to the method, and a second that verifies that the data is properly read in from the files. Both containers seem to have valid data, but neither makes it into my table.
My table seems to be effectively the same as the tutorial table, but obviously I am making an error somewhere. Does anyone see where my error is?
The getters and setters on the SNMPInterface class that you use for input to PropertyValueFactory should be marked public, not no modifier (otherwise the reflection logic inherent in the PropertyValueFactory won't find them).
public static class SNMPInterface {
private final SimpleStringProperty ifIndex;
private final SimpleStringProperty ifDescr;
SNMPInterface( String ifIndex, String ifDescr ) {
this.ifIndex = new SimpleStringProperty( ifIndex );
this.ifDescr = new SimpleStringProperty( ifDescr );
}
public String getIfIndex() {
return ifIndex.get();
}
public void setIfIndex( String index ) {
ifIndex.set( index );
}
public String getIfDescr() {
return ifDescr.get();
}
public void setIfDescr( String descr ) {
ifDescr.set( descr );
}
}
The following screen shot demonstrates the problem I am experiencing:
NOTE: I want to have that green table only on the very end of the whole pdf file, not on every single page!
Is there some elegant solution to find the X,Y location on the page and manually create new page?
This is my code (using iText):
private static PdfPTable createHeaderTable() throws DocumentException {
int[] columnWidths = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
PdfPTable datatable = new PdfPTable(columnWidths.length);
datatable.setWidthPercentage(100);
datatable.setWidths(columnWidths);
datatable.getDefaultCell().setPadding(5);
datatable.getDefaultCell().setHorizontalAlignment(alignment);
datatable.getDefaultCell().setVerticalAlignment(alignment);
for (int i = 0; i < 90; i++) {
addCellToTable(datatable, horizontalAlignmentLeft,
verticalAlignmentMiddle,"Přehledová tabulka", columnWidths.length,
1, fontTypeBold, fontSizeRegular,cellLayout_Bottom);
}
private static PdfPTable createFooterTable() throws DocumentException {
int[] columnWidths = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
PdfPTable datatable = new PdfPTable(columnWidths.length);
// datatable.setKeepTogether(true);
datatable.setWidthPercentage(100);
datatable.setWidths(columnWidths);
datatable.getDefaultCell().setPadding(5);
datatable.getDefaultCell().setHorizontalAlignment(alignment);
datatable.getDefaultCell().setVerticalAlignment(alignment);
//.... added cells identically as by header table (higher here) ...
return datatable;
}
public static void main(String[] args)
throws FileNotFoundException, DocumentException {
Document document = new Document(PageSize.A4);
PdfWriter writer = null;
try {
writer = PdfWriter.getInstance(document,
new FileOutputStream("C:/radek-folder/calendar.pdf"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
document.open();
PdfPTable datatable = createHeaderTable();
document.add(datatable);
datatable = createFooterTable();
drawTableAtTheEndOfPage(document, writer, datatable);
document.close();
System.out.println("done");
}
private static void drawTableAtTheEndOfPage(Document document, PdfWriter writer,
PdfPTable datatable) {
datatable.setTotalWidth(
document.right(document.rightMargin()) -
document.left(document.leftMargin()));
datatable.writeSelectedRows(0, -1, document.left(document.leftMargin()),
datatable.getTotalHeight() + document.bottom(document.bottomMargin()),
writer.getDirectContent());
}
I closed your question as a duplicate of Why is my content overlapping with my footer? because I (wrongly) assumed that you wanted to add a table to each page of the document.
You updated your question with a clarification, and it is now a duplicate of this question: How to find out the current cursor position on a page?
Stack Overflow doesn't allow me to close a question as duplicate twice, hence I have to copy/paste my previous answer here:
There is a very old method called getVerticalPosition() that takes a
boolean as parameter. I'm not proud of that method as it is a
getter method that not only will give you the Y position on the page after using a series of document.add() operations, it can also
change the current Y position (and that is not what a getter method
should do).
If you pass false as a parameter, it will give you the current Y,
which could be the position of the baseline of the last Chunk you've
added.
If you pass true as a parameter, the method will first add a newline
and give you the position of the baseline of the "next" line of text
you'll be adding.
Note that many design flaws (some of which that date back to my original design of iText dating from the year 2000) are fixed in iText 7; iText 7 is a complete rewrite of iText.
My solution:
private static void drawTableAtTheEndOfPageAndWholeDocument
(Document document, PdfWriter writer, PdfPTable datatable)
{
datatable.setTotalWidth(document.right() - document.left());
if (writer.getVerticalPosition(false) - datatable.getTotalHeight()
- document.bottom() < 0) {
// new page if there is too little space for the final table on
// current page
document.newPage();
}
datatable.writeSelectedRows(0, -1, document.left(),
datatable.getTotalHeight() + document.bottom(),
writer.getDirectContent());
}
I am unable to add row to an existing spreadsheet.
I'm trying the steps from here: https://developers.google.com/google-apps/spreadsheets/data
The following line throws the exception below:
row = service.insert(listFeedUrl, row);
Exception:
Exception in thread "main" com.google.gdata.util.InvalidEntryException: Bad Request
Blank rows cannot be written; use delete instead.
at com.google.gdata.client.http.HttpGDataRequest.handleErrorResponse(HttpGDataRequest.java:602)
at com.google.gdata.client.http.GoogleGDataRequest.handleErrorResponse(GoogleGDataRequest.java:564)
at com.google.gdata.client.http.HttpGDataRequest.checkResponse(HttpGDataRequest.java:560)
at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:538)
at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:536)
at com.google.gdata.client.Service.insert(Service.java:1409)
at com.google.gdata.client.GoogleService.insert(GoogleService.java:613)
at TestGoogle.main(TestGoogle.java:93)
The full story short: The above example is quite similar with the code in the application that I need to fix, and the application worked some times ago.
I managed to pass the OAuth2 authentication.
The reason you get this error message is probably because you're trying to add to a blank spreadsheet and the header doesn't exist.
If we add the headers first, then it should work.
Using the "Add a list row" example from the documentation you linked; add the headers like this before adding a list row
CellQuery cellQuery = new CellQuery(worksheet.CellFeedLink);
CellFeed cellFeed = service.Query(cellQuery);
CellEntry cellEntry = new CellEntry(1, 1, "firstname");
cellFeed.Insert(cellEntry);
cellEntry = new CellEntry(1, 2, "lastname");
cellFeed.Insert(cellEntry);
cellEntry = new CellEntry(1, 3, "age");
cellFeed.Insert(cellEntry);
cellEntry = new CellEntry(1, 4, "height");
cellFeed.Insert(cellEntry);
Then the list entry example should add to the spreadsheet properly
// Fetch the list feed of the worksheet.
ListQuery listQuery = new ListQuery(listFeedLink.HRef.ToString());
ListFeed listFeed = service.Query(listQuery);
// Create a local representation of the new row.
ListEntry row = new ListEntry();
row.Elements.Add(new ListEntry.Custom() { LocalName = "firstname", Value = "Joe" });
row.Elements.Add(new ListEntry.Custom() { LocalName = "lastname", Value = "Smith" });
row.Elements.Add(new ListEntry.Custom() { LocalName = "age", Value = "26" });
row.Elements.Add(new ListEntry.Custom() { LocalName = "height", Value = "176" });
// Send the new row to the API for insertion.
service.Insert(listFeed, row);