I want to add the data from ObservableList batchNumber to a tableview which only contains one column yet im stucked because all the tutorials i found is about adding object type, not string type.
This is a function i used to generate a random batch number of format AAA0000
public String generateBatch(){
Random rand = new Random();
String[] alphabet = "Q W E R T Y U I O P A S D F G H J K L Z X C V B N M".split(" ");
String batch = new String();
batch = alphabet[rand.nextInt(0, 26)] + alphabet[rand.nextInt(0, 26)] + alphabet[rand.nextInt(0, 26)] + rand.nextInt(1000, 9999);
return batch;
}
and then i add bunch of batch number into a ObservableList
ObservableList<String> batchNumber = FXCollections.observableArrayList();
for(int i = 0; i < 10; i++){
batchNumber.add(generateBatch());
}
so now batchNumber is loaded with bunch of Strings and then i tried to assign them to a tableView
TableView<String> batchNumberTableView = new TableView<>();
TableColumn<String, ?> batchColumn = new TableColumn<>("Vaccine Batch Number");
batchNumberTableView.getColumns().add(batchColumn);
and here is where im stucked, i've had successfully added a column into the tableview but i have no idea how to assign the datas from batchNumber into the tableview.
You need
TableColumn<String, String> batchColumn = new TableColumn<>("Vaccine Batch Number");
batchColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue()));
Related
Read pptx template then use new data to replace it, there is a scatter chart
associated excel data
xVal and yVal could replace successfully but how to replace C column (extList) ?
xVal and yVal replace by below manner
final CTScatterSer ser = serList.get(0);
final CTAxDataSource xVal = ser.getXVal();
final CTNumDataSource yVal = ser.getYVal();
final CTExtension ctExtension = ser.getExtLst().getExtList().get(0);
final long ptCount = xVal.getNumRef().getNumCache().getPtCount().getVal();
for (int i = 0; i < scData.size(); i++) {
SCNameDouble data = scData.get(i);
CTNumVal xNumVal = ptCount > i ? xVal.getNumRef().getNumCache().getPtArray(i)
: xVal.getNumRef().getNumCache().addNewPt();
xNumVal.setIdx(i);
xNumVal.setV(String.format("%.2f", data.xValue));
CTNumVal yNumVal = ptCount > i ? yVal.getNumRef().getNumCache().getPtArray(i)
: yVal.getNumRef().getNumCache().addNewPt();
yNumVal.setIdx(i);
yNumVal.setV(String.format("%.2f", data.yValue));
}
final int newSize = scData.size();
xVal.getNumRef().setF(
replaceRowEnd(xVal.getNumRef().getF(),
ptCount,
newSize));
yVal.getNumRef().setF(
replaceRowEnd(yVal.getNumRef().getF(),
ptCount,
newSize));
xVal.getNumRef().getNumCache().getPtCount().setVal(newSize);
yVal.getNumRef().getNumCache().getPtCount().setVal(newSize);
Using current apache poi versions one should not trying manipulating charts using the low level CT... classes. There is XDDF for such cases now.
If it comes to PowerPoint charts, then the need is always updating the data in the embedded workbook and updating the data in the chart. See Java edit bar chart in ppt by using poi for an example using bar chart.
Of course a scatter chart is another case then as it not has a category axis but has two value axes. But this also can be updated using XDDF.
The biggest problem you have is the data labels. There is not full support for chart data labels in XDDF upto now. And since you are talkig about extLst and your Excel table shows the data labels in a cell range, I suspect you have set the data labels comming from a cell range. This is a new feature which was not present when Microsoft had published Office Open XML. So not even the low level CT... classes are able to support that feature.
The only way is to manipulate the XML using pure XML manupulating based on org.apache.xmlbeans.XmlObject.
The following shows this on sample of a template you seems to use according to your question.
ScatterChartSample.pptx:
Code:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.AreaReference;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumns;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
public class PowerPointChangeScatterChartData {
//patched version of XSSFTable.updateHeaders, see https://stackoverflow.com/questions/55532006/renaming-headers-of-xssftable-with-apache-poi-leads-to-corrupt-xlsx-file/55539181#55539181
static void updateHeaders(XSSFTable table) {
XSSFSheet sheet = (XSSFSheet)table.getParent();
CellReference ref = table.getStartCellReference();
if (ref == null) return;
int headerRow = ref.getRow();
int firstHeaderColumn = ref.getCol();
XSSFRow row = sheet.getRow(headerRow);
DataFormatter formatter = new DataFormatter();
if (row != null /*&& row.getCTRow().validate()*/) {
int cellnum = firstHeaderColumn;
CTTableColumns ctTableColumns = table.getCTTable().getTableColumns();
if(ctTableColumns != null) {
for (CTTableColumn col : ctTableColumns.getTableColumnList()) {
XSSFCell cell = row.getCell(cellnum);
if (cell != null) {
col.setName(formatter.formatCellValue(cell));
}
cellnum++;
}
}
}
}
static void updateScatterChart(XSLFChart chart, Object[][] data) throws Exception {
// get chart's data source which is a Excel sheet
XSSFWorkbook chartDataWorkbook = chart.getWorkbook();
String sheetName = chartDataWorkbook.getSheetName(0);
XSSFSheet chartDataSheet = chartDataWorkbook.getSheet(sheetName);
// current Office uses a table as data source
// so get that table if present
XSSFTable chartDataTable = null;
if (chartDataSheet.getTables().size() > 0) {
chartDataTable = chartDataSheet.getTables().get(0);
}
if (chart.getChartSeries().size() == 1) { // we will process only one chart data
XDDFChartData chartData = chart.getChartSeries().get(0);
if (chartData.getSeriesCount() == 1) { // we will process only templates having one series
int rMin = 1; // first row (0) is headers row
int rMax = data.length - 1;
// column 0 is X-Values
int c = 0;
// set new x data
XDDFDataSource xs = null;
for (int r = rMin; r <= rMax; r++) {
XSSFRow row = chartDataSheet.getRow(r); if (row == null) row = chartDataSheet.createRow(r);
XSSFCell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellValue((Double)data[r][c]); // in sheet
}
xs = XDDFDataSourcesFactory.fromNumericCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); // in chart
// set new x-title in sheet
String xTitle = (String)data[0][c];
chartDataSheet.getRow(0).getCell(c).setCellValue(xTitle); // in sheet
// column 1 is Y-Values
c = 1;
// set new y data in sheet and in chart
XDDFNumericalDataSource<Double> ys = null;
for (int r = rMin; r <= rMax; r++) {
XSSFRow row = chartDataSheet.getRow(r); if (row == null) row = chartDataSheet.createRow(r);
XSSFCell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellValue((Double)data[r][c]); // in sheet
}
ys = XDDFDataSourcesFactory.fromNumericCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c));
XDDFChartData.Series series1 = chartData.getSeries(0);
series1.replaceData(xs, ys); // in chart
// set new y-title in sheet and in chart
String yTitle = (String)data[0][c];
chartDataSheet.getRow(0).getCell(c).setCellValue(yTitle); // in sheet
series1.setTitle(yTitle, new CellReference(sheetName, 0, c, true, true)); // in chart
series1.plot();
// column 2 is data-labels-range
c = 2;
// set new data labels data in sheet and in chart
XDDFDataSource dataLabelsRangeSource = null;
for (int r = rMin; r <= rMax; r++) {
XSSFRow row = chartDataSheet.getRow(r); if (row == null) row = chartDataSheet.createRow(r);
XSSFCell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellValue((String)data[r][c]); // in sheet
}
dataLabelsRangeSource = XDDFDataSourcesFactory.fromStringCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); // in chart
updateDataLabelsRange(chart, dataLabelsRangeSource); // in chart
// set new data-labels-title in sheet
String descrTitle = (String)data[0][c];
chartDataSheet.getRow(0).getCell(c).setCellValue(descrTitle); // in sheet
// update the table if present
if (chartDataTable != null) {
CellReference topLeft = new CellReference(chartDataSheet.getRow(0).getCell(0));
CellReference bottomRight = new CellReference(chartDataSheet.getRow(rMax).getCell(c));
AreaReference tableArea = chartDataWorkbook.getCreationHelper().createAreaReference(topLeft, bottomRight);
chartDataTable.setArea(tableArea);
updateHeaders(chartDataTable);
}
}
}
}
static void updateDataLabelsRange(XDDFChart chart, XDDFDataSource dataLabelsRangeSource) {
String declareNameSpaces = "declare namespace c='http://schemas.openxmlformats.org/drawingml/2006/chart'; "
+ "declare namespace c15='http://schemas.microsoft.com/office/drawing/2012/chart' ";
org.apache.xmlbeans.XmlObject[] selectedObjects = chart.getCTChart().selectPath(
declareNameSpaces
+ ".//c:ext[c15:datalabelsRange]"); // needs net.sf.saxon - Saxon-HE (Saxon-HE-10.6.jar)
if (selectedObjects.length > 0) { // we have at least one ext containing datalabelsRange
org.apache.xmlbeans.XmlObject ext = selectedObjects[0]; // get first ext containing datalabelsRange
// get dataLabelsRange
org.apache.xmlbeans.XmlObject[] datalabelsRanges = ext.selectChildren(new javax.xml.namespace.QName("http://schemas.microsoft.com/office/drawing/2012/chart", "datalabelsRange", "c15"));
org.apache.xmlbeans.XmlObject dataLabelsRange = datalabelsRanges[0];
// set formula
org.apache.xmlbeans.XmlObject[] formulas = dataLabelsRange.selectChildren(new javax.xml.namespace.QName("http://schemas.microsoft.com/office/drawing/2012/chart", "f", "c15"));
org.apache.xmlbeans.XmlObject formula = formulas[0];
((org.apache.xmlbeans.impl.values.XmlObjectBase)formula).setStringValue(dataLabelsRangeSource.getFormula());
// get dlblRangeCache
org.apache.xmlbeans.XmlObject[] dlblRangeCaches = dataLabelsRange.selectChildren(new javax.xml.namespace.QName("http://schemas.microsoft.com/office/drawing/2012/chart", "dlblRangeCache", "c15"));
org.apache.xmlbeans.XmlObject dlblRangeCache = dlblRangeCaches[0];
// empty the cache
dlblRangeCache.newCursor().removeXmlContents();
// create new cache from dataLabelsRangeSource
org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData cache = org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData.Factory.newInstance();
dataLabelsRangeSource.fillStringCache(cache);
// set new cache
dlblRangeCache.set(cache);
}
}
public static void main(String[] args) throws Exception {
String filePath = "ScatterChartSample.pptx"; // has template scatter chart
String filePathNew = "ScatterChartSample_New.pptx";
Object[][] data = new Object[][] { // new data 1 series, 6 x-y-values and data labels
{"X-Values", "Y-Values", "DataLabels"}, // series title
{0.7d, 1.7d, "aa"}, // x1
{1.8d, 3.2d, "bb"}, // x2
{2.6d, 2.8d, "cc"}, // x3
{1.7d, 3.7d, "dd"}, // x4
{2.8d, 4.2d, "ee"}, // x5
{3.6d, 1.8d, "ff"} // x6
};
XMLSlideShow slideShow = new XMLSlideShow(new FileInputStream(filePath));
XSLFChart chart = slideShow.getCharts().get(0);
updateScatterChart(chart, data);
FileOutputStream out = new FileOutputStream(filePathNew);
slideShow.write(out);
out.close();
slideShow.close();
}
}
Resulting ScatterChartSample_New.pptx:
Note: Tested and works using current apache poi 5.2.0.
To be able to use XPath as .//c:ext[c15:datalabelsRange] it needs net.sf.saxon - Saxon-HE (Saxon-HE-10.6.jar in my case).
And it needs poi-ooxml-full-5.2.0.jar and not only the lite version of ooxml-schemas.
I am trying to pass checked items from one listview to another listview in a separate activity. Ideally, the user would click all of the items they wanted, then click a button; then, the button would take all of the items from the rows clicked to the new activity. The problem that I keep having is when I click on the row; all of the information shows up on the next activity instead of the individual rows there were selected.
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
adapterTwo.setCheckBox(position);
adapterTwo.notifyDataSetChanged();
}
});
practiceFinal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String entry = "";
String judge ="";
Integer points = 0;
Integer work = 0;
Integer design = 0;
Integer doc = 0;
Integer pres= 0;
Integer safety= 0;
Integer diff = 0;
String ribbon ="";
Intent intent = new Intent(CSS.this, FinalCSS.class);
for (Team hold: adapterTwo.getTeamArrayList())
{
if (hold.isChecked())
{
}
else
{
entry += " "+ hold.getEntryNumber();
judge += hold.getTeamJudgeNumber();
points+= hold.getTotalPoints();
work+= hold.getWorkmanship();
design += hold.getDesign();
doc += hold.getDocumnetation();
pres+= hold.getPresentation();
safety += hold.getSafety();
diff += hold.getDifficulty();
ribbon += hold.getRibbon();
intent.putExtra( "KeyEntry", entry);
intent.putExtra("KeyJudge", judge);
intent.putExtra("KeyPoints", points);
intent.putExtra("KeyWork", work);
intent.putExtra("KeyDesign", design);
intent.putExtra("KeyDoc",doc);
intent.putExtra("KeyPres", pres);
intent.putExtra("KeySafety", safety);
intent.putExtra("KeyRibbon", ribbon);
intent.putExtra("KeyDiff", diff);
}
}
startActivity(intent);
}
});
listView = findViewById(R.id.listViewFinal);
teamsList= new ArrayList<>();
String entry = getIntent().getStringExtra("KeyEntry");
String judge=getIntent().getStringExtra("KeyJudge");
Integer points= getIntent().getIntExtra("KeyPoints",0);
Integer workmanship=getIntent().getIntExtra("KeyWork",0);
Integer design=getIntent().getIntExtra("KeyDesign",0);
Integer documentation =getIntent().getIntExtra("KeyDoc",0);
Integer pres = getIntent().getIntExtra("KeyPres",0);
Integer difficulty =getIntent().getIntExtra("KeyDiff",0);
Integer safety =getIntent().getIntExtra("KeySafety",0);
String ribbon= getIntent().getStringExtra("KeyRibbon");
Team teams = null;
teams = new Team(judge,entry,points, workmanship,design,documentation,pres,difficulty,safety,ribbon,true);
teamsList.add(teams);
Team teamsT = null;
teamsT = new Team(judge,entry,points, workmanship,design,documentation,pres,difficulty,safety,ribbon,true);
teamsList.add(teamsT);
TeamAdapterTwo adapterTwo = new TeamAdapterTwo(FinalCSS.this, teamsList);
listView.setAdapter(adapterTwo);
Second ActivityFirst ActivitySecond Activity
You are concatenate the information on a global variable. Thus, if we trace the points attribute evolution, we have:
points = 0
points += 1 (points = 1)
points += 2 (points = 3)
points += 3 (points = 6)
points += 4 (points = 10)
Moreover, intent.putExtra erase the old value associated to a key, so at each iteration of the loop, you are replacing the old value of points by the new one. Therefore, at the end, you will give points = 10 to the second Activity.
You have two options:
Create a unique key for each hold but it will not be easy for the second Activity to know this unique key.
Instead of put an integer as extra, put an array of integers (I recommend this way)
However, you seem to have an other issue because the final value of points is the sum of all lines rather than the sum of the checked ones.
i'm having trouble reading in a text file which contains 9 sets of three integer values separated by commas. This is what i have done so far, but how would i be able to read through the data going down row one to get a max value?
very stuck with a program the data text file looks like
21,7,11
20,10,12
17,7,18
these represent temperature, height and carbon%
i have read in the file as so
{
string s;
System.IO.StreamReader inputFile = new System.IO.StreamReader(DataFile);
s = inputFile.ReadLine();
int noDataLines = int.Parse(s);
double[,] data = new double[noDataLines, 3];
string[] ss;
is this right if the data is stored in the debug folder as a .txt file?
from here how would i go about getting a max temp(ie only reading the first vertical column of data)?
We can simply use mixture of System.IO File.ReadLines() method and LINQ .ToList() in order to read all text lines to List<string>. At this point we can just iterate through the collection parsing double values from text lines :
List<string> lines = File.ReadLines("filepath").ToList();
List<int[]> values = new List<int[]>();
int[] temp = new int[3];
for (int i = 0; i < lines.Count; i++)
{
string[] strValues = lines[i].Split(',');
for (int i2 = 0; i2 < strValues.Length; i2++)
temp[i2] = Convert.ToInt32(strValues[i2]);
values.Add(temp.ToArray());
}
Or we can use LINQ :
List<string> lines = File.ReadLines("filepath").ToList();
List<int[]> values = new List<int[]>();
int[] temp = new int[3];
for (int i = 0; i < lines.Count; i++)
values.Add(lines[i].Split(',')
.Select(l => Convert.ToInt32(l)).ToArray());
I could not find a way to make a RTL paragraph in Docx using XWPFDocument (Apache POI) in my Java program. Here's my code that generates the XWPFDocument.
XWPFParagraph title = document.createParagraph();
title.setAlignment(ParagraphAlignment.CENTER);
title.setVerticalAlignment(TextAlignment.CENTER);
title.setWordWrap(true);
XWPFRun titleRun = title.createRun();
titleRun.setText(reportDesign.getName());
XWPFTable s = document.createTable(resultList.size()+1, columnList.size());
// declare a row object reference
XWPFTableRow r = s.getRow(0);
// declare a cell object reference
XWPFTableCell c = null;
// create columnList.size() cells (0-(columnList.size()-1))
for (int cellnum = 0; cellnum < columnList.size(); cellnum++) {
c = r.getCell(cellnum);
c.setColor("c9c9c9");
c.setVerticalAlignment(XWPFVertAlign.CENTER);
c.setText(columnList.get(cellnum).getColumnHeader());
}
// create a sheet with resultList.size() rows (1-resultList.size())
for (int rownum = 0; rownum < resultList.size(); rownum++) {
// create a row
r = s.getRow(rownum+1);
// create columnList.size() cells (0-(columnList.size()-1))
for (int cellnum = 0; cellnum < columnList.size(); cellnum++) {
c = r.getCell(cellnum);
Object value = resultList.get(rownum).get(columnList.get(cellnum).getColumnKey());
if (value != null) {
c.setText(value.toString());
} else {
c.setText("");
}
}
}
Would you please help me? Is there a logical way to extend POI (or similar solution) for gaining this feature?
A workaround that I found till now is using a template document.
Using this method, you make an empty document that "Normal" style in it, is configured to be RTL. This way, everything in your document will be RTL.
XWPFDocument document = new XWPFDocument(AbstractWordView.class.getClassLoader().getResourceAsStream("empty.docx"));
I have several independant int variables in my program. Is there a way I can feed randomly the value of one of them into a new int variable or an int array ? Thanks in Advance.
EDIT:
here's a pseudocode to demonstrate:
int A1 = 1;
int A2 = 3;
int RESULT = 0;
Random rand = new Random();
Result = rand.Next(0, A1 || A2)]; //Result holds the value/variable name of A1 or A2
You could put all the ints you want to choose from in a new array and then select a random value from it. For example:
int value1 = 3;
int anotherValue = 5;
int value2 = 1;
int[] selectableInts = new int[3] { value1, anotherValue, value2 };
Random rand = new Random();
int randomValue = selectableInts[rand.Next(0, selectableInts.Length)];
How about this:
// create an array of your variables
int[] A = new int[] {1,3};
// Instantiate Random object.
Random rand = new Random();
// Get a value between 0 and the lenght of your array.
// This is equivalent to select one of the elements of the array.
int index = rand.Next(0,A.Length);
// Get the value from the array that was selected at random.
int Result = A[index];
I had some trouble myself and found this thread, but its code is for Ints only, so I was stuck for some time to make it work for other than ints.
I think #David gave me some idea how to make it work.
This is my version for using types other than ints.
Vector2 down = new Vector2(0, 1);
Vector2 left = new Vector2(-1, 0);
Vector2 right = new Vector2(1, 0);
List<Vector2> possibleDirections = new List<Vector2>()
{
down,
left,
right
};
Random random = new Random();
Vector2 selectedRandomDirection = possibleDirections[random.Next(0, possibleDirections.Count)];
// this is the result
Vector2 direction = selectedRandomDirection;