How to create two scenes in scalafx - scene

I am new to creating GUI using scalafx. I am trying to create two scenes with the following code but getting some error
import com.sun.glass.ui.Application
import scalafx.event.ActionEvent
import scalafx.event.EventHandler
import scalafx.scene.Scene
import scalafx.scene.control.Button
import scalafx.scene.control.Label
import scalafx.scene.layout.StackPane
import scalafx.scene.layout.VBox
import scalafx.stage.Stage
class example extends Application {
var scene1: Scene = null
var scene2: Scene = null
override def start(primaryStage: Stage): Unit = { primaryStage.setTitle("My First JavaFX GUI")
//Scene 1
val label1 = new Label("This is the first scene")
val button1 = new Button("Go to scene 2"){
onAction = (e: ActionEvent) => {
primaryStage.setScene(scene2)
}
}
val layout1 = new VBox(20)
layout1.getChildren.addAll(label1, button1)
scene1 = new Scene(layout1, 300, 250)
//Scene 2
val label2 = new Label("This is the second scene")
val button2 = new Button("Go to scene 1") {
onAction = (e: ActionEvent) => {
primaryStage.setScene(scene1)
}
}
val layout2 = new VBox(20)
layout2.getChildren.addAll(label2, button2)
scene2 = new Scene(layout2, 300, 250)
primaryStage.setScene(scene1)
primaryStage.show()
}
}
The error is:
found : scalafx.event.ActionEvent => Unit
[error] required: javafx.event.EventHandler[javafx.event.ActionEvent]
[error] onAction = (e: ActionEvent) => {}
How can I declare the action events to switch between the scenes?
It would be really helpful if anyone can help

In ScaleFX, your first troubleshooting is to check if you included the ScaleFX implicit conversion magic:
import scalafx.Includes._
In your case, that will fix the issue with the action handler.
Additionally, you should not use com.sun packages neither in ScalaFX nor in JavaFX code. In ScalaFX you should use JFXApp3 instead. Here is your code corrected to use JFXApp3 with some minor corrections:
import scalafx.Includes._
import scalafx.application.JFXApp3
import scalafx.application.JFXApp3.PrimaryStage
import scalafx.event.{ActionEvent, EventHandler}
import scalafx.scene.Scene
import scalafx.scene.control.{Button, Label}
import scalafx.scene.layout.VBox
import scalafx.stage.Stage
object CreteTwoScenes1App extends JFXApp3 {
var scene1: Scene = _
var scene2: Scene = _
override def start(): Unit = {
stage = new PrimaryStage {
title = "My First JavaFX GUI"
}
// Scene 1
val label1 = new Label("This is the first scene")
val button1 = new Button("Go to scene 2") {
onAction = (e: ActionEvent) => {
stage.setScene(scene2)
}
}
val layout1 = new VBox(20)
layout1.children ++= Seq(label1, button1)
scene1 = new Scene(layout1, 300, 250)
// Scene 2
val label2 = new Label("This is the second scene")
val button2 = new Button("Go to scene 1") {
onAction = (e: ActionEvent) => {
stage.setScene(scene1)
}
}
val layout2 = new VBox(20)
layout2.children ++= Seq(label2, button2)
scene2 = new Scene(layout2, 300, 250)
stage.setScene(scene1)
}
}
You can also rewrite that in more idiomatic ScalaFX builder style. Using Scala 3 can make it much more compact too (no curly braces needed):
import scalafx.Includes.*
import scalafx.application.JFXApp3
import scalafx.scene.Scene
import scalafx.scene.control.{Button, Label}
import scalafx.scene.layout.VBox
object CreteTwoScenes2App extends JFXApp3:
override def start(): Unit =
lazy val scene1: Scene = new Scene(300, 200):
root = new VBox(20):
children = Seq(
new Label("This is the first scene"),
new Button("Go to scene 2"):
onAction = () => stage.setScene(scene2)
)
lazy val scene2: Scene = new Scene(300, 200):
root = new VBox(20):
children = Seq(
new Label("This is the second scene"),
new Button("Go to scene 1"):
onAction = () => stage.setScene(scene2)
)
stage = new JFXApp3.PrimaryStage:
title = "My First JavaFX GUI"
scene = scene1

Related

how to spark streaming use connection pool for impala(JDBC to kudu)

i use impala(JDBC) twice to get kafka offset and save data in foreachRDD.
but impala and kudu always shutdown. now i want to set connect pool, but little for scala.
it's my pseudo-code:
#node-1
val newOffsets = getNewOffset() // JDBC read kafka offset in kudu
val messages = KafkaUtils.createDirectStream(*,newOffsets,)
messages.foreachRDD(rdd => {
val spark = SparkSession.builder.config(rdd.sparkContext.getConf).getOrCreate()
#node-2
Class.forName(jdbcDriver)
val con = DriverManager.getConnection("impala url")
val stmt = con.createStatement()
stmt.executeUpdate(sql)
#node-3
val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
offsetRanges.foreach { r => {
val rt_upsert = s"UPSert into ${execTable} values('${r.topic}',${r.partition},${r.untilOffset})"
stmt.executeUpdate(rt_upsert)
stmt.close()
conn.close()
}}
}
how to code by c3p0 or other ? I'll appreciate your help.
Below is the code for reading data from kafka and inserting the data to kudu.
import kafka.message.MessageAndMetadata
import kafka.serializer.StringDecoder
import org.apache.kudu.client.KuduClient
import org.apache.kudu.client.KuduSession
import org.apache.kudu.client.KuduTable
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.streaming.Milliseconds,
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.kafka.KafkaUtils
import scala.collection.immutable.List
import scala.collection.mutable
import scala.util.control.NonFatal
import org.apache.spark.sql.{Row, SQLContext}
import org.apache.spark.sql.types._
import org.apache.kudu.Schema
import org.apache.kudu.Type._
import org.apache.kudu.spark.kudu.KuduContext
import scala.collection.mutable.ArrayBuffer
object KafkaKuduConnect extends Serializable {
def main(args: Array[String]): Unit = {
try {
val TopicName="TestTopic"
val kafkaConsumerProps = Map[String, String]("bootstrap.servers" -> "localhost:9092")
val KuduMaster=""
val KuduTable=""
val sparkConf = new SparkConf().setAppName("KafkaKuduConnect")
val sc = new SparkContext(sparkConf)
val sqlContext = new SQLContext(sc)
import sqlContext.implicits._
val ssc = new StreamingContext(sc, Milliseconds(1000))
val kuduContext = new KuduContext(KuduMaster, sc)
val kuduclient: KuduClient = new KuduClient.KuduClientBuilder(KuduMaster).build()
//Opening table
val kudutable: KuduTable = kuduclient.openTable(KuduTable)
// getting table schema
val tableschema: Schema = kudutable.getSchema
// creating the schema for the data frame using the table schema
val FinalTableSchema =generateStructure(tableschema)
//To create the schema for creating the data frame from the rdd
def generateStructure(tableSchema:Schema):StructType=
{
var structFieldList:List[StructField]=List()
for(index <-0 until tableSchema.getColumnCount)
{
val col=tableSchema.getColumnByIndex(index)
val coltype=col.getType.toString
println(coltype)
col.getType match {
case INT32 =>
structFieldList=structFieldList:+StructField(col.getName,IntegerType)
case STRING =>
structFieldList=structFieldList:+StructField(col.getName,StringType)
case _ =>
println("No Class Type Found")
}
}
return StructType(structFieldList)
}
// To create the Row object with values type casted according to the schema
def getRow(schema:StructType,Data:List[String]):Row={
var RowData=ArrayBuffer[Any]()
schema.zipWithIndex.foreach(
each=>{
var Index=each._2
each._1.dataType match {
case IntegerType=>
if(Data(Index)=="" | Data(Index)==null)
RowData+=Data(Index).toInt
case StringType=>
RowData+=Data(Index)
case _=>
RowData+=Data(Index)
}
}
)
return Row.fromSeq(RowData.toList)
}
val messages = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, kafkaConsumerProps, Set(TopicName))
messages.foreachRDD(
//we are looping through eachrdd
eachrdd=>{
//we are creating the Rdd[Row] to create dataframe with our schema
val StructuredRdd= eachrdd.map(eachmessage=>{
val record=eachmessage._2
getRow(FinalTableSchema, record.split(",").toList)
})
//DataFrame with required structure according to the table.
val DF = sqlContext.createDataFrame(StructuredRdd, FinalTableSchema)
kuduContext.upsertRows(DF,KuduTable)
}
)
}
catch {
case NonFatal(e) => {
print("Error in main : " + e)
}
}
}
}

page X of Y with re-ordered TOC: X will start from 1 again after the TOC

I could create seprately the "page x of y" and re-ordered the TOC with the official examples. "Page x of y" is created according to iText 7: Building Blocks Chapter 7: Handling events; setting viewer preferences and writer properties with the examples Solving the "Page X of Y" problem; and TOC is created with reference to iText 7 examples TOC as first page.
Now I want the generated PDF to have both "page x of y" and re-ordered TOC. And "page x of y" shall be shown on all pages, i.e. on the 1st page (the TOC page), it shall show "Page 1 of 35", the 2nd page (start page of the main text) shall show "Page 2 of 35" (In this Jekyll and Hyde example, TOC has one page).
But when I tried to put "page x of y" and re-order TOC together, I found a problem in the generated PDF: the 1st page (the TOC page) showed correctly "Page 1 of 35", but the 2nd page (start page of the main text) showed also "Page 1 of 35".
What is the tricks to let the 2nd page to show "Page 2 of 35" with re-ordered TOC?
==code for Page X of Y and re-order TOC==
package main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
import com.itextpdf.io.IOException;
import com.itextpdf.io.font.FontConstants;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfOutline;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfString;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.action.PdfAction;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.canvas.draw.DottedLine;
import com.itextpdf.kernel.pdf.navigation.PdfDestination;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Tab;
import com.itextpdf.layout.element.TabStop;
import com.itextpdf.layout.hyphenation.HyphenationConfig;
import com.itextpdf.layout.layout.LayoutContext;
import com.itextpdf.layout.layout.LayoutResult;
import com.itextpdf.layout.property.AreaBreakType;
import com.itextpdf.layout.property.TabAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.renderer.ParagraphRenderer;
public class CreateTOC {
public static final String SRC = "D:/work/java_workspace/result/jekyll_hyde.txt";
public static final String DEST = "D:/work/java_workspace/result/test_toc.pdf";
public static void main(String args[]) throws IOException, Exception {
File file = new File(DEST);
file.getParentFile().mkdirs();
new CreateTOC().createPdf(DEST);
}
public void createPdf(String dest) throws IOException, java.io.IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
pdf.getCatalog().setPageMode(PdfName.UseOutlines);
PageXofY event = new PageXofY(pdf);
pdf.addEventHandler(PdfDocumentEvent.END_PAGE, event);
PdfFont font = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
PdfFont bold = PdfFontFactory.createFont(FontConstants.HELVETICA_BOLD);
Document document = new Document(pdf);
document.setTextAlignment(TextAlignment.JUSTIFIED)
.setHyphenation(new HyphenationConfig("en", "uk", 3, 3))
.setFont(font)
.setFontSize(11);
// // add the cover
// document.add(new Paragraph("this is the cover 1"));
// document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
//
//
// document.add(new Paragraph("this is the cover 2"));
// document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
// parse text to PDF
BufferedReader br = new BufferedReader(new FileReader(SRC));
String name, line;
Paragraph p;
boolean title = true;
int counter = 0;
PdfOutline outline = null;
List<SimpleEntry<String,SimpleEntry<String, Integer>>> toc = new ArrayList<>();
while ((line = br.readLine()) != null) {
p = new Paragraph(line);
p.setKeepTogether(true);
if (title) {
name = String.format("title%02d", counter++);
outline = createOutline(outline, pdf, line, name);
int pagesWithoutCover = pdf.getNumberOfPages();
SimpleEntry<String, Integer> titlePage = new SimpleEntry(line, pagesWithoutCover);
p.setFont(bold).setFontSize(12)
.setKeepWithNext(true)
.setDestination(name)
.setNextRenderer(new UpdatePageRenderer(p, titlePage));
title = false;
document.add(p);
toc.add(new SimpleEntry(name, titlePage));
}
else {
p.setFirstLineIndent(18);
if (line.isEmpty()) {
p.setMarginBottom(12);
title = true;
}
else {
p.setMarginBottom(0);
}
document.add(p);
}
}
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
// create table of contents
int startToc = pdf.getNumberOfPages();
p = new Paragraph().setFont(bold).add("Table of Contents").setDestination("toc");
document.add(p);
toc.remove(0);
List<TabStop> tabstops = new ArrayList();
tabstops.add(new TabStop(580, TabAlignment.RIGHT, new DottedLine()));
for (SimpleEntry<String, SimpleEntry<String, Integer>> entry : toc) {
SimpleEntry<String, Integer> text = entry.getValue();
p = new Paragraph()
.addTabStops(tabstops)
.add(text.getKey())
// .setFixedLeading(150)
.add(new Tab())
.add(String.valueOf(text.getValue()))
.setAction(PdfAction.createGoTo(entry.getKey()));
document.add(p);
}
int tocPages = pdf.getNumberOfPages() - startToc;
// reorder pages
PdfPage page;
for (int i = 0; i <= tocPages; i++) {
page = pdf.removePage(startToc + i);
pdf.addPage(i + 1, page);
}
event.writeTotal(pdf);
document.close();
}
protected class UpdatePageRenderer extends ParagraphRenderer {
protected SimpleEntry<String, Integer> entry;
public UpdatePageRenderer(Paragraph modelElement, SimpleEntry<String, Integer> entry) {
super(modelElement);
this.entry = entry;
}
#Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult result = super.layout(layoutContext);
entry.setValue(layoutContext.getArea().getPageNumber());
return result;
}
}
public PdfOutline createOutline(PdfOutline outline, PdfDocument pdf, String title, String name) {
if (outline == null) {
outline = pdf.getOutlines(false);
outline = outline.addOutline(title);
outline.addDestination(PdfDestination.makeDestination(new PdfString(name)));
return outline;
}
PdfOutline kid = outline.addOutline(title);
kid.addDestination(PdfDestination.makeDestination(new PdfString(name)));
return outline;
}
protected class PageXofY implements IEventHandler {
protected PdfFormXObject placeholder;
protected float side = 20;
protected float x = 300;
protected float y = 25;
protected float space = 4.5f;
protected float descent = 3;
public PageXofY(PdfDocument pdf) {
placeholder = new PdfFormXObject(new Rectangle(0, 0, side, side));
}
#Override
public void handleEvent(Event event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdf = docEvent.getDocument();
PdfPage page = docEvent.getPage();
int pageNumber = pdf.getPageNumber(page);
Rectangle pageSize = page.getPageSize();
PdfCanvas pdfCanvas = new PdfCanvas(
page.newContentStreamBefore(), page.getResources(), pdf);
Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
Paragraph p = new Paragraph().add("Page ").add(String.valueOf(pageNumber)).add(" of");
canvas.showTextAligned(p, x, y, TextAlignment.RIGHT);
pdfCanvas.addXObject(placeholder, x + space, y - descent);
pdfCanvas.release();
}
public void writeTotal(PdfDocument pdf) {
Canvas canvas = new Canvas(placeholder, pdf);
canvas.showTextAligned(String.valueOf(pdf.getNumberOfPages()),
0, descent, TextAlignment.LEFT);
}
}
}
In general
You will obviously run into trouble if you first create pages including a "page x/y" using the current page number of each page and then re-order the pages.
If you know beforehand how many pages you will move up front, you can take this re-ordering into account by adding this number as offset to the page number in your event listener. Be sure to reset that offset when you start creating the TOC pages.
If you don't know that number, it does not make sense to try to number the pages before re-ordering at all. Instead add page numbers afterwards as described in the iText 7: Building Blocks Chapter 2: Working with the RootElement example Adding a Page X of Y footer, i.e. loop over every page in the document and add a "Page X of Y" Paragraph to each page:
int n = pdf.getNumberOfPages();
Paragraph footer;
for (int page = 1; page <= n; page++) {
footer = new Paragraph(String.format("Page %s of %s", page, n));
document.showTextAligned(footer, 297.5f, 20, page,
TextAlignment.CENTER, VerticalAlignment.MIDDLE, 0);
}
document.close();
Don't forget to set immediateFlush to false as described right after that example.
Using an offset
In a comment you indicated that you did not want to use the solution from chapter 2 referenced above as you didn't want to keep the whole PDF in memory. Then you posted your code.
Thus, let's try and implement the offset mentioned above in your code.
The offset variable is best located right in the event listener. Having added it, it might looks like this:
protected class PageXofY implements IEventHandler
{
// vvv added
int offset = 0;
// ^^^ added
protected PdfFormXObject placeholder;
protected float side = 20;
protected float x = 300;
protected float y = 25;
protected float space = 4.5f;
protected float descent = 3;
public PageXofY(PdfDocument pdf)
{
placeholder = new PdfFormXObject(new Rectangle(0, 0, side, side));
}
#Override
public void handleEvent(Event event)
{
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdf = docEvent.getDocument();
PdfPage page = docEvent.getPage();
int pageNumber = pdf.getPageNumber(page);
Rectangle pageSize = page.getPageSize();
PdfCanvas pdfCanvas = new PdfCanvas(
page.newContentStreamBefore(), page.getResources(), pdf);
Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
// vvv changed
Paragraph p = new Paragraph().add("Page ").add(String.valueOf(pageNumber + offset)).add(" of");
// ^^^ changed
canvas.showTextAligned(p, x, y, TextAlignment.RIGHT);
pdfCanvas.addXObject(placeholder, x + space, y - descent);
pdfCanvas.release();
}
public void writeTotal(PdfDocument pdf)
{
Canvas canvas = new Canvas(placeholder, pdf);
canvas.showTextAligned(String.valueOf(pdf.getNumberOfPages()),
0, descent, TextAlignment.LEFT);
}
}
(PageXofY)
(You might want to add getters and setters for the offset.)
When importing the text body your page numbers currently are created off-by-one as the TOC page will later be pulled up to the front. Thus, you need to use an offset of 1 (1 page TOC) during that import.
Afterwards, before starting the TOC page, you will have to reset the offset to 0 as nothing will be pulled before the TOC page thereafter.
Id est:
public void createPdf(Reader reader, String dest) throws IOException
{
[...]
Document document = new Document(pdf);
document.setTextAlignment(TextAlignment.JUSTIFIED)
.setHyphenation(new HyphenationConfig("en", "uk", 3, 3))
.setFont(font)
.setFontSize(11);
// vvv added
event.offset = 1;
// ^^^ added
// // add the cover
[...]
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
// vvv added
event.offset = 0;
// ^^^ added
// create table of contents
int startToc = pdf.getNumberOfPages();
[...]
}
(CreateTOC method createPdf)
In the current iText 7 development 7.0.3-SNAPSHOT version this results in desired page numbering.
Beware: There had been reports on delayed page event execution. Probably the event timing meanwhile has been changed. With older versions, therefore, the code might still apply wrong page numbers.

how to add image in table(XSLFTable) cell in powerpoint poi api in java

how to add image in table(XSLFTable) cell in powerpoint poi api in java, we are not able to get the CTBlipFillProperties through poi latest jar poi-3.15.jar
how to add image in table(XSLFTable) cell in powerpoint poi api in java, we are not able to get the CTBlipFillProperties through poi latest jar poi-3.15.jar
public static void main(String[] args) throws Exception {
XMLSlideShow pptx = new XMLSlideShow();
XSLFSlide slide = pptx.createSlide();
// you need to include ooxml-schemas:1.1 for this to work!!!
// otherwise an empty table will be created
// see https://issues.apache.org/bugzilla/show_bug.cgi?id=49934
XSLFTable table = slide.createTable();
table.setAnchor(new Rectangle2D.Double(50, 50, 500, 20));
XSLFTableRow row = table.addRow();
row.addCell().setText("Cell 1");
XSLFTableCell cell = row.addCell();
cell.setText("Cell 2");
CTBlipFillProperties blipPr = cell.getXmlObject().getTcPr().addNewBlipFill();
blipPr.setDpi(72);
// http://officeopenxml.com/drwPic-ImageData.php
CTBlip blib = blipPr.addNewBlip();
blipPr.addNewSrcRect();
CTRelativeRect fillRect = blipPr.addNewStretch().addNewFillRect();
fillRect.setL(30000);
fillRect.setR(30000);
PackagePartName partName = PackagingURIHelper.createPartName("/ppt/media/100px.gif");
PackagePart part = pptx.getPackage().createPart(partName, "image/gif");
OutputStream partOs = part.getOutputStream();
FileInputStream fis = new FileInputStream("src/test/resources/100px.gif");
byte buf[] = new byte[1024];
for (int readBytes; (readBytes = fis.read(buf)) != -1; partOs.write(buf, 0, readBytes));
fis.close();
partOs.close();
PackageRelationship prs = slide.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
blib.setEmbed(prs.getId());
FileOutputStream fos = new FileOutputStream("test2.pptx");
pptx.write(fos);
fos.close();
}
You were quite close ... the following was tested on the POI trunk (POI 3.16-beta2), but should work on POI 3.15 too ...
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileOutputStream;
import org.apache.poi.POIXMLDocumentPart.RelationPart;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFPictureData;
import org.apache.poi.xslf.usermodel.XSLFRelation;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTable;
import org.apache.poi.xslf.usermodel.XSLFTableCell;
import org.apache.poi.xslf.usermodel.XSLFTableRow;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRelativeRect;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
public class TablePics {
public static void main(String[] args) throws Exception {
XMLSlideShow pptx = new XMLSlideShow();
XSLFPictureData pd = pptx.addPicture(new File("wrench.emf"), PictureType.EMF);
XSLFSlide slide = pptx.createSlide();
XSLFTable table = slide.createTable();
table.setAnchor(new Rectangle2D.Double(50, 50, 500, 20));
XSLFTableRow row = table.addRow();
row.addCell().setText("Cell 1");
XSLFTableCell cell = row.addCell();
cell.setText("Cell 2");
CTBlipFillProperties blipPr = ((CTTableCell)cell.getXmlObject()).getTcPr().addNewBlipFill();
blipPr.setDpi(72);
// http://officeopenxml.com/drwPic-ImageData.php
CTBlip blib = blipPr.addNewBlip();
blipPr.addNewSrcRect();
CTRelativeRect fillRect = blipPr.addNewStretch().addNewFillRect();
fillRect.setL(30000);
fillRect.setR(30000);
RelationPart rp = slide.addRelation(null, XSLFRelation.IMAGES, pd);
blib.setEmbed(rp.getRelationship().getId());
FileOutputStream fos = new FileOutputStream("test2.pptx");
pptx.write(fos);
fos.close();
}
}

Annotating an Image in AS3 with a Rectangle and Save Result

I am currently looking at a face detection example found in a zip file here:
Marilena_mod10.zip
The example loads an image and then highlights the face with a black rectangle.
I would like to save the resulting image, in other words, annotate the image with a square and nothing else (just the image and square, not the entire stage).
So far I can save the image by processing it as bitmap data and resaving it, but I cannot save the 'square'. I've tried copying the line that draws the square and drawing it to another bitmap object, tried drawing it on a sprite, and I've tried using a matrix figuring it was being drawn out of bounds. No luck.
Below is the original code followed by my futile attempts (I realize it saves a blank white image, I was trying to see if I could just draw a square):
package
{
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Sprite;
import flash.display.Loader;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.text.TextField;
import jp.maaash.ObjectDetection.ObjectDetector;
import jp.maaash.ObjectDetection.ObjectDetectorOptions;
import jp.maaash.ObjectDetection.ObjectDetectorEvent;
import flash.utils.getTimer;
public class FaceDetector extends Sprite{
private var debug :Boolean = true;
private var detector :ObjectDetector;
private var options :ObjectDetectorOptions;
private var faceImage :Loader;
private var bmpTarget :Bitmap;
private var view :Sprite;
private var faceRectContainer :Sprite;
private var tf :TextField;
private var lastTimer:int = 0;
public function FaceDetector() {
initUI();
initDetector();
faceImage.load( new URLRequest("013.jpg") );
}
private function initUI():void{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
view = new Sprite;
addChild(view);
faceImage = new Loader;
faceImage.contentLoaderInfo.addEventListener( Event.COMPLETE, function(e :Event) :void {
startDetection();
});
view.addChild( faceImage );
faceRectContainer = new Sprite;
view.addChild( faceRectContainer );
tf = new TextField;
tf.x = 256;
tf.width = 600;
tf.height = 300;
tf.textColor = 0x000000;
tf.multiline = true;
view.addChild( tf );
}
private function initDetector():void{
detector = new ObjectDetector;
detector.options = getDetectorOptions();
detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE,function( e :ObjectDetectorEvent ):void{
logger("[ObjectDetectorEvent.COMPLETE]");
tf.appendText( "\ntime: "+(new Date)+" "+e.type );
detector.removeEventListener( ObjectDetectorEvent.DETECTION_COMPLETE, arguments.callee );
if( e.rects ){
var g :Graphics = faceRectContainer.graphics;
g.clear();
g.lineStyle( 2 ); // black 2pix
e.rects.forEach( function( r :Rectangle, idx :int, arr :Array ) :void {
g.drawRect( r.x, r.y, r.width, r.height );
});
}
});
detector.addEventListener( ObjectDetectorEvent.DETECTION_START, function(e :ObjectDetectorEvent) :void {
tf.appendText( "\ntime: "+(new Date)+" "+e.type );
});
}
private function startDetection():void{
logger("[startDetection]");
bmpTarget = new Bitmap( new BitmapData( faceImage.width, faceImage.height, false ) )
bmpTarget.bitmapData.draw( faceImage );
detector.detect( bmpTarget.bitmapData );
}
private function getDetectorOptions() :ObjectDetectorOptions {
options = new ObjectDetectorOptions();
options.min_size = 50;
return options;
}
private function logger(... args):void{
if(!debug){ return; }
trace( args, getTimer(), getTimer() - lastTimer);
lastTimer = getTimer();
}
}
}
My code:
package
{
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Sprite;
import flash.display.Loader;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.events.Event;
import flash.geom.*;//Rectangle;
import flash.net.URLRequest;
import flash.text.TextField;
import jp.maaash.ObjectDetection.ObjectDetector;
import jp.maaash.ObjectDetection.ObjectDetectorOptions;
import jp.maaash.ObjectDetection.ObjectDetectorEvent;
import com.adobe.images.*;
import flash.utils.getTimer;
////
import flash.filesystem.*;
import flash.utils.ByteArray;
////
public class FaceDetector extends Sprite{
private var debug :Boolean = true;
private var detector :ObjectDetector;
private var options :ObjectDetectorOptions;
private var faceImage :Loader;
private var bmpTarget :Bitmap;
private var view :Sprite;
private var faceRectContainer :Sprite;
private var tf :TextField;
private var lastTimer:int = 0;
public function FaceDetector() {
initUI();
initDetector();
faceImage.load( new URLRequest("013.jpg") );
}
private function initUI():void{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
view = new Sprite;
addChild(view);
faceImage = new Loader;
faceImage.contentLoaderInfo.addEventListener( Event.COMPLETE, function(e :Event) :void {
startDetection();
});
view.addChild( faceImage );
faceRectContainer = new Sprite;
view.addChild( faceRectContainer );
tf = new TextField;
tf.x = 256;
tf.width = 600;
tf.height = 300;
tf.textColor = 0x000000;
tf.multiline = true;
view.addChild( tf );
}
private function initDetector():void{
detector = new ObjectDetector;
detector.options = getDetectorOptions();
detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE,function( e :ObjectDetectorEvent ):void{
logger("[ObjectDetectorEvent.COMPLETE]");
tf.appendText( "\ntime: "+(new Date)+" "+e.type );
detector.removeEventListener( ObjectDetectorEvent.DETECTION_COMPLETE, arguments.callee );
var rt:Sprite = new Sprite();
var bmprt:Bitmap = new Bitmap( new BitmapData( faceImage.width, faceImage.height, false ) );
var matrix:Matrix = new Matrix();
var rect:Rectangle = new Rectangle();
if( e.rects ){
var g :Graphics = faceRectContainer.graphics;
g.clear();
g.lineStyle( 2 ); // black 2pix
e.rects.forEach( function( r :Rectangle, idx :int, arr :Array ) :void {
g.drawRect( r.x, r.y, r.width, r.height );
matrix.translate(-r.x, -r.y);
rect = r;
rt.graphics.drawRect(r.x, r.y, r.width, r.height );
});
}
var file:File = File.applicationStorageDirectory.resolvePath("testoutput.jpg");
var fs:FileStream = new FileStream();
var byteArray:ByteArray;
var jpgEncoder:JPGEncoder = new JPGEncoder( 90 );
//rt.graphics.draw(g);
bmpTarget.bitmapData.draw(rt);
bmprt.bitmapData.draw(rt, matrix);
byteArray = jpgEncoder.encode( bmprt.bitmapData );
fs.open(file, FileMode.WRITE);
fs.writeBytes(byteArray);
fs.close();
});
detector.addEventListener( ObjectDetectorEvent.DETECTION_START, function(e :ObjectDetectorEvent) :void {
tf.appendText( "\ntime: "+(new Date)+" "+e.type );
});
}
private function startDetection():void{
logger("[startDetection]");
bmpTarget = new Bitmap( new BitmapData( faceImage.width, faceImage.height, false ) )
bmpTarget.bitmapData.draw( faceImage );
detector.detect( bmpTarget.bitmapData );
}
private function getDetectorOptions() :ObjectDetectorOptions {
options = new ObjectDetectorOptions();
options.min_size = 50;
return options;
}
private function logger(... args):void{
if(!debug){ return; }
trace( args, getTimer(), getTimer() - lastTimer);
lastTimer = getTimer();
}
}
}
TL;DR:
How do you load an image, draw a square on it, and then save the result, assuming you already know how to load and save images?
Any help is appreciated, thanks in advance.
EDIT
Here is the final code for anyone interested:
package
{
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Sprite;
import flash.display.Loader;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.events.Event;
import flash.geom.*;//Rectangle;
import flash.net.URLRequest;
import flash.text.TextField;
import jp.maaash.ObjectDetection.ObjectDetector;
import jp.maaash.ObjectDetection.ObjectDetectorOptions;
import jp.maaash.ObjectDetection.ObjectDetectorEvent;
import com.adobe.images.*;
import flash.utils.getTimer;
////
import flash.filesystem.*;
import flash.utils.ByteArray;
////
public class FaceDetector extends Sprite{
private var debug :Boolean = true;
private var detector :ObjectDetector;
private var options :ObjectDetectorOptions;
private var faceImage :Loader;
private var bmpTarget :Bitmap;
private var view :Sprite;
private var faceRectContainer :Sprite;
private var tf :TextField;
private var lastTimer:int = 0;
public function FaceDetector() {
initUI();
initDetector();
faceImage.load( new URLRequest("013.jpg") );
}
private function initUI():void{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
view = new Sprite;
addChild(view);
faceImage = new Loader;
faceImage.contentLoaderInfo.addEventListener( Event.COMPLETE, function(e :Event) :void {
startDetection();
});
view.addChild( faceImage );
faceRectContainer = new Sprite;
view.addChild( faceRectContainer );
tf = new TextField;
tf.x = 256;
tf.width = 600;
tf.height = 300;
tf.textColor = 0x000000;
tf.multiline = true;
view.addChild( tf );
}
private function initDetector():void{
detector = new ObjectDetector;
detector.options = getDetectorOptions();
detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE,function( e :ObjectDetectorEvent ):void{
logger("[ObjectDetectorEvent.COMPLETE]");
tf.appendText( "\ntime: "+(new Date)+" "+e.type );
detector.removeEventListener( ObjectDetectorEvent.DETECTION_COMPLETE, arguments.callee );
var bmprt:Bitmap = new Bitmap( new BitmapData( faceImage.width, faceImage.height, false ) );
if( e.rects ){
var g :Graphics = faceRectContainer.graphics;
g.clear();
g.lineStyle(3, 0xFF0000, 1); // black 2pix--- parameters(thicknes in pixels, color in hex, alpha (0-1))
e.rects.forEach( function( r :Rectangle, idx :int, arr :Array ) :void {
g.drawRect( r.x, r.y, r.width, r.height );
});
}
var file:File = File.applicationStorageDirectory.resolvePath("testoutput.jpg");
var fs:FileStream = new FileStream();
var byteArray:ByteArray;
var jpgEncoder:JPGEncoder = new JPGEncoder( 90 );
bmprt.bitmapData.draw(faceImage);
bmprt.bitmapData.draw(faceRectContainer);
byteArray = jpgEncoder.encode( bmprt.bitmapData );
fs.open(file, FileMode.WRITE);
fs.writeBytes(byteArray);
fs.close();
});
detector.addEventListener( ObjectDetectorEvent.DETECTION_START, function(e :ObjectDetectorEvent) :void {
tf.appendText( "\ntime: "+(new Date)+" "+e.type );
});
}
private function startDetection():void{
logger("[startDetection]");
bmpTarget = new Bitmap( new BitmapData( faceImage.width, faceImage.height, false ) )
bmpTarget.bitmapData.draw( faceImage );
detector.detect( bmpTarget.bitmapData );
}
private function getDetectorOptions() :ObjectDetectorOptions {
options = new ObjectDetectorOptions();
options.min_size = 50;
return options;
}
private function logger(... args):void{
if(!debug){ return; }
trace( args, getTimer(), getTimer() - lastTimer);
lastTimer = getTimer();
}
}
}
Thanks to Vesper for the help.
Well, you load the image as a Bitmap, then determine where to draw the rectangle, create a Shape and draw the rectangle on its graphics, then call bitmap.bitmapData.draw(shape) to draw the rectangle over the loaded bitmap, then save the bitmap. In your code, after you've prepared the rectangles, you do something like this:
bmprt.bitmapData.copyPixels(faceImage.bitmapData,faceImage.bitmapData.rect,new Point());
bmprt.bitmapData.draw(faceRectContainer);
Then save bmprt as you do.

How to play the drop failed animation in ScalaFX/JavaFX 2?

In ScalaFX if I drop a TreeCell onto a control other than the containing TreeView then a short animation is played showing the dragged item returning to its original position.
The same happens if I drop the TreeCell outside of the application - e.g. onto the desktop.
If I drop the TreeCell onto the containing TreeView in a location that shouldn't be accepted I want the same animation to play, but setting:
event.dropCompleted = false
isn't enough to produce this effect.
Is there a way to play the drop failed animation from inside the TreeCell's onDragDropped event handler?
Edit
Added code sample as requested. Drag an entry and drop it outside the control and you will see the drop failed animation. Drag an entry and drop it below the list and the animation doesn't play. The question is how to make the animation play in the second case.
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.paint.Color
import scalafx.scene.layout.Pane
import scalafx.Includes._
import scalafx.scene.input.{TransferMode, DataFormat, DragEvent, MouseEvent}
import scalafx.scene.control._
import javafx.scene.control.{TreeItem => jfxTreeItem}
import java.nio.ByteBuffer
import java.util
import scalafx.beans.value.ObservableValue
class StringRootItem(text: String) extends TreeItem[String](text) {
override def toString() = text
}
class StringTreeItem(text: String) extends TreeItem[String](text) {
override def toString() = text
}
object DragAndDropControl {
def apply(rootNodeName: String, entries: List[String]): DragAndDropControl = {
val rootItem = new StringRootItem(rootNodeName)
rootItem.setExpanded(true)
val children = rootItem.getChildren
entries.foreach(entry => {
children.add(new StringTreeItem(entry))
})
new DragAndDropControl(rootItem)
}
}
class DragAndDropControl(rootItem: StringRootItem) extends TreeView[String](rootItem) {
showRoot = false
cellFactory = (tree: TreeView[String]) => {
new StringDragAndDropCell(tree)
}
object StringDragAndDropCell {
val customFormat: DataFormat = new DataFormat("string.entry.custom")
var transferItem: TreeItem[String] = null
def toBuffer(entry: String): ByteBuffer = ByteBuffer.allocate(10)
def fromBuffer(buffer: ByteBuffer): String = null
}
class StringDragAndDropCell(tree: TreeView[String]) extends TreeCell[String] {
import StringDragAndDropCell._
private var stringEntry: String = null
onDragDetected = (event: MouseEvent) => {
val db = startDragAndDrop(TransferMode.MOVE)
import scala.collection.JavaConversions._
if ((treeItem ne null) && (treeItem.value ne null) && (treeItem.value.getValue ne null)) {
transferItem = treeItem.value
val content: Map[javafx.scene.input.DataFormat, AnyRef] = Map(customFormat.delegate -> toBuffer(transferItem.value()))
val contentMap: util.Map[javafx.scene.input.DataFormat, AnyRef] = mapAsJavaMap(content)
db.setContent(contentMap)
}
event.consume()
}
onDragOver = (event: DragEvent) => {
val db = event.getDragboard
if (db.hasContent(customFormat))
event.acceptTransferModes(TransferMode.MOVE)
event.consume()
}
onDragDone = (event: DragEvent) => {
if (event.transferMode == TransferMode.MOVE)
event.dragboard.clear()
event.consume()
}
onDragDropped = (event: DragEvent) => {
val db = event.getDragboard
var success = false
if (db.hasContent(customFormat))
success = stringEntry ne null
if (success)
if (event.gestureSource != event.delegate.getGestureTarget) {
treeItem().getParent.getChildren.removeAll(transferItem)
treeItem().getParent.getChildren.add(index(), transferItem)
}
event.dropCompleted = success
event.consume()
}
/*
* Change handler for the treeItem property.
*
* The treeItem property is set by JavaFX after construction and at any time when the cell is recycled for UI virtualization.
*
* The text property must be updated when the treeItem is set in order for the cell to render correctly (without this the cell will appear blank.)
*/
super.treeItem.onChange((observable: ObservableValue[jfxTreeItem[String], jfxTreeItem[String]], oldValue: jfxTreeItem[String], newValue: jfxTreeItem[String]) => {
if (newValue ne null) {
stringEntry = newValue.getValue
text = stringEntry
}
else
stringEntry = null
})
override def toString(): String = {
if (stringEntry == null)
null
else
s"ScalaFX string tree cell ${stringEntry.toString}"
}
}
}
object TestDragAndDrop extends JFXApp
{
println("javafx.runtime.version: " + System.getProperties.get("javafx.runtime.version"))
println("java.runtime.version: " + System.getProperties.get("java.runtime.version"))
stage = new JFXApp.PrimaryStage {
title = "Test Drag and Drop"
width = 600
height = 472
scene = new Scene {
fill = Color.LIGHTGREEN
root = new Pane {
content = DragAndDropControl("Numbers", List("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"))
}
}
}
}

Resources