How to achieve anti aliasing in javaFX ? I have applied some tricks... but it didn't work - javafx-2

after reading the question it looks like I have asked the question which was already asked but believe me I have tried the possible solutions where in I didn't get the desired output....
First of all What I want to achieve ?
To achieve the AntiAliasing , I have tried some of the way like
new Scene(,,,,SceneAntialiasing.BALANCED);
shape[object].setSmooth(true);
System.setProperty("prism.lcdtext", "false"); from the link
How to force anti-aliasing in JavaFX fonts?
I have tried to use SubScene as well , but it was somewhat improper way to go...
But none of the above solutions works for me ... So Now, I am posting the
SSCVE ...
Please help me on this ...
Thanks in advance...
SSCVE
the CreateScene method in UI class which extends JFXPanel looks like ....
private Scene createScene()
{
Group rootNode = new Group();
//System.setProperty("prism.lcdtext", "false");
double StrokeWidth = 1.0;
double yPosition = 20.0;
//textFontsize = textFontsize + 0.7 ;
// straight Vertical Lines
rootNode.getChildren().add(createLines(35.0, yPosition+20, 35.0, yPosition+150, StrokeWidth,"GREEN"));
rootNode.getChildren().add(createLines(25.0, yPosition+20, 25, yPosition+150, StrokeWidth,"BLACK"));
rootNode.getChildren().add(createLines(30.0, yPosition+20, 30, yPosition+150, StrokeWidth,"BLUE"));
// straight horizontal lines
rootNode.getChildren().add(createLines(80.0, yPosition+30, 240, yPosition+30, StrokeWidth,"RED"));
rootNode.getChildren().add(createLines(80.0, yPosition+40, 240, yPosition+40, StrokeWidth,"GREEN"));
rootNode.getChildren().add(createLines(80.0, yPosition+50, 240, yPosition+50, StrokeWidth,"BLACK"));
// create slope lines
rootNode.getChildren().add(createLines(420.0, yPosition+20, 470, yPosition+150, StrokeWidth,"BLACK"));
rootNode.getChildren().add(createLines(430.0, yPosition+20, 480, yPosition+150, StrokeWidth,"RED"));
rootNode.getChildren().add(createLines(440.0, yPosition+20, 490, yPosition+150, StrokeWidth,"BLUE"));
rootNode.getChildren().add(createLines(450.0, yPosition+20, 500, yPosition+150, StrokeWidth,"GREEN"));
double textFontsize = 12.0;
String fontColor = "RED";
String font ="Arial";
int count = 5;
String newLine = null;
if(count == 5)
{
newLine = "\n\n\n\n\n";
}
rootNode.getChildren().add(createText(50,yPosition+230,font,textFontsize, newLine+"15352465 \n"
+ "Circle is "+StrokeWidth+" . "+"Font name is "+font+" . Minimum visible font size is 0.7 ."
+ "\n The Font size for text is "+textFontsize+". ",fontColor, StrokeWidth));
ScrollPane scroll = new ScrollPane();
scroll.setHbarPolicy(ScrollBarPolicy.ALWAYS);
scroll.setVbarPolicy(ScrollBarPolicy.NEVER);
scroll.setContent(rootNode);
//iv.setClip(new Rectangle(0,20,250,200));
Scene sc = new Scene(scroll, 500,500,false,SceneAntialiasing.BALANCED);
SceneAntialiasing value = sc.getAntiAliasing();
return sc;
}
public Line createLines(double startX, double startY, double endX, double endY, double strokeWidth, String strokeColor)
{
Line line = new Line(startX-0.5, startY-0.5, endX-0.5, endY-0.5);
if(strokeColor.equals("BLUE"))
{
line.setStroke(javafx.scene.paint.Color.BLUE);
}
else if(strokeColor.equals("RED"))
{
line.setStroke(javafx.scene.paint.Color.RED);
}
else if(strokeColor.equals("GREEN"))
{
line.setStroke(javafx.scene.paint.Color.GREEN);
}
else if(strokeColor.equals("BLACK"))
{
line.setStroke(javafx.scene.paint.Color.BLACK);
}
line.setStrokeWidth(strokeWidth);
//line.setSmooth(true);
return line;
}
public Text createText(double xParam, double yParam, String fontType, double fontSize, String text, String strokeColor, double StrokeWidth)
{
Text txt = new Text(text);
txt.setX(xParam);
txt.setY(yParam);
if(fontType.equals("Comic Sans MS"))
{
txt.setFont(Font.font(fontType,FontWeight.BOLD, fontSize));
}
else
{
txt.setFont(Font.font(fontType, fontSize));
}
//txt.setStrokeWidth(StrokeWidth);
if(strokeColor.equals("BLUE"))
{
txt.setFill(Color.BLUE);
}
else if(strokeColor.equals("RED"))
{
txt.setFill(javafx.scene.paint.Color.RED);
}
else if(strokeColor.equals("GREEN"))
{
txt.setFill(javafx.scene.paint.Color.GREEN);
}
else if(strokeColor.equals("BLACK"))
{
txt.setFill(javafx.scene.paint.Color.BLACK);
}
else if(strokeColor.equals("BROWN"))
{
txt.setFill(javafx.scene.paint.Color.BROWN);
}
// txt.setFontSmoothingType(FontSmoothingType.LCD);
// txt.setStrokeType(StrokeType.INSIDE);
return txt;
}

Related

MQL4 Drawing a Dynamic Rectangle_Label with a Text in It

I am trying to draw a Rectangle Label with a text in it every tick.. I want a text to fit exactly in to a Rectangle_Label.. As a text i am using Label.. But cant get it to work exactly.. It is not correctly situated..
In Fact i would like to create a class that would do it all in one... Just like a rectangle with text in it that would be always having same co ordinance and size etc..
Any help would be greatly appreciated...
bool createRectangleLabel(long chart_ID,string name,string labelName,int shift,double price,string text,double xSize,double ySize,double xOffSet,double yOffSet,double xDistance,double yDistance)
{
if(ObjectCreate(chart_ID,labelName,OBJ_RECTANGLE_LABEL,0,TimeCurrent()-shift,price))
{
Print(xDistance+" "+yDistance);
ObjectSetInteger(chart_ID,labelName,OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(chart_ID,labelName,OBJPROP_XDISTANCE,xDistance);
ObjectSetInteger(chart_ID,labelName,OBJPROP_YDISTANCE,yDistance);
ObjectSetInteger(chart_ID,labelName,OBJPROP_YSIZE,ySize);
ObjectSetInteger(chart_ID,labelName,OBJPROP_XSIZE,xSize);
ObjectSetString(chart_ID,labelName,OBJPROP_TEXT,text);
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
return true;
}
else
{
Print("createRectangleLabel return error code: ",GetLastError());
Print("+--------------------------------------------------------------+");
return false;
}
}
bool createLineText(long chart_ID,string name,string labelName,int shift,double price,string text)
{
int xDistance=0;
int yDistance=0;
int xSize,xOffSet;
int ySize,yOffSet;
bool i=ChartTimePriceToXY(chart_ID,0,TimeCurrent(),price,xDistance,yDistance);
if(ObjectCreate(chart_ID,name,OBJ_LABEL,0,TimeCurrent()-shift,price))
{
ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,clrWhite);
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,xDistance);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,yDistance);
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clrWhite);
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,10);
xSize = ObjectGet(name,OBJPROP_XSIZE);
ySize = ObjectGet(name,OBJPROP_YSIZE);
xOffSet = ObjectGet(name,OBJPROP_XOFFSET);
yOffSet = ObjectGet(name,OBJPROP_YOFFSET);
TextGetSize(name,xSize,ySize);
createRectangleLabel(chart_ID,name,labelName,shift,price,text,xSize,ySize,xOffSet,yOffSet,xDistance,yDistance);
return true;
}
else
{
Print("createLineText return error code: ",GetLastError());
Print("+--------------------------------------------------------------+");
return false;
}
}
You cannot call ObjectCreate() every tick - it would return an error 4200.
If you check the object exists before creating, that would help. Alternative approach would be to try to create the object and assign it with some necessary properties (e.g., color of the object, anchor etc) in one block, and move it in another.
if(ObjectFind(chart_id,labelName)<0){
if(ObjectCreate(chart_ID,labelName,OBJ_RECTANGLE_LABEL,0,TimeCurrent()-shift,price)){
ObjectSetInteger(chart_ID,labelName,OBJPROP_BGCOLOR,clrBlack);//etc.
}
ObjectSetInteger(chart_ID,labelName,OBJPROP_XDISTANCE,xDistance);
ObjectSetInteger(chart_ID,labelName,OBJPROP_YDISTANCE,yDistance);//if you need to move the object or take other steps each tick, e.g. update text - do it here
}
You're thinking along the right lines when you say that you'd like to create a class. Fortunately for you, the standard library already includes all the classes you need to make chart objects. Documentation
Example Indicator:
#property strict
#property indicator_chart_window
#include <ChartObjects\ChartObjectsTxtControls.mqh>
class MyRectLabel : public CChartObjectRectLabel
{
CChartObjectLabel m_label;
public:
bool Create(long chart, const string name, const int window,
const int X, const int Y, const int sizeX, const int sizeY)
{
if(!CChartObjectRectLabel::Create(chart,name,window,X,Y,sizeX,sizeY))
return false;
return m_label.Create(chart, name + "_", window, X + 8, Y + 12);
}
bool Color(const color clr){
return m_label.Color(clr);
}
bool Description(const string text){
return m_label.Description(text);
}
bool FontSize(const int size){
return m_label.FontSize(size);
}
bool ToolTip(const string text){
return (this.ToolTip(text) && m_label.Tooltip(text));
}
};
//+------------------------------------------------------------------+
MyRectLabel rect_label;
//+------------------------------------------------------------------+
int OnInit()
{
if(!rect_label.Create(0, "rlabel", 0, 5, 25, 100, 50)
|| !rect_label.BackColor(clrWhiteSmoke)
|| !rect_label.Description("LABEL!")
|| !rect_label.Tooltip("I am a rectangle label")
|| !rect_label.Color(clrBlack)
|| !rect_label.FontSize(18)
)
return INIT_FAILED;
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
int start()
{
static double last_price = 0.;
rect_label.Description(DoubleToString(Bid, _Digits));
if(Bid > last_price)
rect_label.Color(clrLimeGreen);
else
rect_label.Color(clrRed);
last_price = Bid;
return 0;
}

Arduino+processing and string information in an "if" statment

I am using an arduino to read out information from a scale into Processing.
Now I want certain things to happen depending on the weight registered. The weight is read out in a String. I have found out that >= does not work for strings. I have tried if (val >= str ("20.00")) but that doesnt work either.
I have also tried to convert it into a float using float scale = Float.parseFloat(val); But that doesnt work either. Does anyone have an idea. That would be great!
PImage pictureday;
import processing.serial.*;
import cc.arduino.*;
import org.firmata.*;
Serial myPort;
String val;
color textcolor = color(0, 50, 50, 240);
color textcolor2 = color(255, 0, 0);
void setup()
{
fullScreen();
background (189, 215, 239);
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}
void draw()
{
if ( myPort.available() > 0)
{ // If data is available,
val = myPort.readStringUntil('\n');
}
if (scale >= 20.00)
{
image(pictureday, 0, 0);
textSize(50);
fill(textcolor);
text(val, 900, 360);
text("KG ", 1030, 360);
println (val);
}
}
Like you've discovered, you can't compare Strings like that. Processing isn't smart enough to know the String contains a number.
Instead, use the float() function:
String val = "123.456";
float f = float(val);
if(f > 100){
println("here!");
}

How do I create an editable Label in javafx 2.2

I am looking to create an editable label at an arbitrary position on the pane on which I am writing. I am under the impression that TextField or TextArea objects are what I could use to implement that capability. There is obviously more to it as I don't know how to position the object when I create it. I have found an example on the "Chaotic Java" website but I need to do a bit more work to understand what's going on there. http://chaoticjava.com/posts/another-javafx-example-the-editable-label/
I am looking for more input from this group.
(There are no errors because I have not written any code.)
I was kind of curious about how to achieve this, so I gave it a try. This is what I came up with.
The approach used is pretty the same as that suggested by James in his comment:
I would start with a Pane, . . ., TextFields to represent text while being edited. Register mouse listeners with the Pane and Text objects, and use the layoutX and layoutY properties to position things . . . just to use text fields, and to use CSS to make them look like labels when not focused and text fields when focused.
The only significantly tricky part was working out how to correctly size the text fields as the Text inside the text field is not exposed via public API to allow you to listen to it's layout bounds. You could perhaps use a css lookup function to get at the enclosed Text, but I chose to use a private sun FontMetrics API (which may be deprecated in the future), to get the size of the text. In the future with Java 9, you should be able to perform the task without using the private API.
The solution doesn't try to do anything tricky like deal with multi-format or multi-line text, it is just for short, single line comments of a few words that can be placed over a scene.
TextCreator.java
// ## CAUTION: beware the com.sun imports...
import com.sun.javafx.tk.FontMetrics;
import com.sun.javafx.tk.Toolkit;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* Displays a map of the lonely mountain upon which draggable, editable labels can be overlaid.
*/
public class TextCreator extends Application {
private static final String MAP_IMAGE_LOC =
"http://images.wikia.com/lotr/images/archive/f/f6/20130209175313!F27c_thorins_map_from_the_hobbit.jpg";
public static void main(String[] args) throws Exception {
launch(args);
}
#Override
public void start(final Stage stage) throws Exception {
Pane pane = new Pane();
pane.setOnMouseClicked(event -> {
if (event.getTarget() == pane) {
pane.getChildren().add(
new EditableDraggableText(event.getX(), event.getY())
);
}
});
EditableDraggableText cssStyled =
new EditableDraggableText(439, 253, "Style them with CSS");
cssStyled.getStyleClass().add("highlighted");
pane.getChildren().addAll(
new EditableDraggableText(330, 101, "Click to add a label"),
new EditableDraggableText(318, 225, "You can edit your labels"),
cssStyled,
new EditableDraggableText(336, 307, "And drag them"),
new EditableDraggableText(309, 346, "Around The Lonely Mountain")
);
StackPane layout = new StackPane(
new ImageView(
new Image(
MAP_IMAGE_LOC
)
),
pane
);
Scene scene = new Scene(layout);
scene.getStylesheets().add(getClass().getResource(
"editable-text.css"
).toExternalForm());
stage.setScene(scene);
stage.setResizable(false);
stage.show();
}
/**
* A text field which has no special decorations like background, border or focus ring.
* i.e. the EditableText just looks like a vanilla Text node or a Label node.
*/
class EditableText extends TextField {
// The right margin allows a little bit of space
// to the right of the text for the editor caret.
private final double RIGHT_MARGIN = 5;
EditableText(double x, double y) {
relocate(x, y);
getStyleClass().add("editable-text");
//** CAUTION: this uses a non-public API (FontMetrics) to calculate the field size
// the non-public API may be removed in a future JavaFX version.
// see: https://bugs.openjdk.java.net/browse/JDK-8090775
// Need font/text measurement API
FontMetrics metrics = Toolkit.getToolkit().getFontLoader().getFontMetrics(getFont());
setPrefWidth(RIGHT_MARGIN);
textProperty().addListener((observable, oldTextString, newTextString) ->
setPrefWidth(metrics.computeStringWidth(newTextString) + RIGHT_MARGIN)
);
Platform.runLater(this::requestFocus);
}
}
/**
* An EditableText (a text field which looks like a label), which can be dragged around
* the screen to reposition it.
*/
class EditableDraggableText extends StackPane {
private final double PADDING = 5;
private EditableText text = new EditableText(PADDING, PADDING);
EditableDraggableText(double x, double y) {
relocate(x - PADDING, y - PADDING);
getChildren().add(text);
getStyleClass().add("editable-draggable-text");
// if the text is empty when we lose focus,
// the node has no purpose anymore
// just remove it from the scene.
text.focusedProperty().addListener((observable, hadFocus, hasFocus) -> {
if (!hasFocus && getParent() != null && getParent() instanceof Pane &&
(text.getText() == null || text.getText().trim().isEmpty())) {
((Pane) getParent()).getChildren().remove(this);
}
});
enableDrag();
}
public EditableDraggableText(int x, int y, String text) {
this(x, y);
this.text.setText(text);
}
// make a node movable by dragging it around with the mouse.
private void enableDrag() {
final Delta dragDelta = new Delta();
setOnMousePressed(mouseEvent -> {
this.toFront();
// record a delta distance for the drag and drop operation.
dragDelta.x = mouseEvent.getX();
dragDelta.y = mouseEvent.getY();
getScene().setCursor(Cursor.MOVE);
});
setOnMouseReleased(mouseEvent -> getScene().setCursor(Cursor.HAND));
setOnMouseDragged(mouseEvent -> {
double newX = getLayoutX() + mouseEvent.getX() - dragDelta.x;
if (newX > 0 && newX < getScene().getWidth()) {
setLayoutX(newX);
}
double newY = getLayoutY() + mouseEvent.getY() - dragDelta.y;
if (newY > 0 && newY < getScene().getHeight()) {
setLayoutY(newY);
}
});
setOnMouseEntered(mouseEvent -> {
if (!mouseEvent.isPrimaryButtonDown()) {
getScene().setCursor(Cursor.HAND);
}
});
setOnMouseExited(mouseEvent -> {
if (!mouseEvent.isPrimaryButtonDown()) {
getScene().setCursor(Cursor.DEFAULT);
}
});
}
// records relative x and y co-ordinates.
private class Delta {
double x, y;
}
}
}
editable-text.css
.editable-text {
-fx-background-color: transparent;
-fx-background-insets: 0;
-fx-background-radius: 0;
-fx-padding: 0;
}
.editable-draggable-text:hover .editable-text {
-fx-background-color: yellow;
}
.editable-draggable-text {
-fx-padding: 5;
-fx-background-color: rgba(152, 251, 152, 0.2); // translucent palegreen
}
.editable-draggable-text:hover {
-fx-background-color: orange;
}
.highlighted {
-fx-background-color: rgba(255, 182, 93, 0.3); // translucent mistyrose
-fx-border-style: dashed;
-fx-border-color: firebrick;
}
If you have time, you could clean the sample implementation up and donate it to the ControlsFX project.
You can use a function of label: setGraphic().
Here is my code:
public void editableLabelTest(Stage stage){
Scene scene = new Scene(new VBox(new EditableLabel("I am a label"),
new EditableLabel("I am a label too")));
stage.setScene(scene);
stage.show();
}
class EditableLabel extends Label{
TextField tf = new TextField();
/***
* backup is used to cancel when press ESC...
*/
String backup = "";
public EditableLabel(){
this("");
}
public EditableLabel(String str){
super(str);
this.setOnMouseClicked(e -> {
if(e.getClickCount() == 2){
tf.setText(backup = this.getText());
this.setGraphic(tf);
this.setText("");
tf.requestFocus();
}
});
tf.focusedProperty().addListener((prop, o, n) -> {
if(!n){
toLabel();
}
});
tf.setOnKeyReleased(e -> {
if(e.getCode().equals(KeyCode.ENTER)){
toLabel();
}else if(e.getCode().equals(KeyCode.ESCAPE)){
tf.setText(backup);
toLabel();
}
});
}
void toLabel(){
this.setGraphic(null);
this.setText(tf.getText());
}
}

Wrong results when trying to get sizes of a pane with css-formattings

I came across a strange behaviour of JavaFX when i tried to obtain the bordersizes (bounds) of a pane that has some css-effects//formattings applied to it. In my application i have to lookup the exact sizes of different objects in order to connect them with lines (imagine some sort of UML-diagramm editor, the start and endpoints of the lines are the border coordinates of the objects).
Now to my problem: whenever i try to get the bordersizes of an object in the same method where this object is put on the scene graph, the result does not include any css attributes like padding, bordersize, strokes and so on. The exact result gets returned if the object already exists on the scene graph before i lookup the size. It seems to be that JavaFX has to wait for one rendering pass (16,7ms) to actually update the real bounds and sizes on an object. Is there any way to get the size of an object (especially those which extend Pane) in the same method as it is created? I don't really like the workaround with waiting for 16,7ms, because it creates some unwanted behaviour in my application.
The following code shows the problem. The size when creating the pane containing the rectangle does not equal the size when pressing the "show size" button.
public class SzenarioView extends GridPane
{
private Group paintingLayer;
public SzenarioView()
{
super();
paintingLayer = new Group();
paintingLayer.getStylesheets().add(TestStarter.class.getResource("ReprBox.css").toString());
Rectangle r1 = new Rectangle(0, 0, 1000, 1000);
r1.setFill(Color.AZURE);
paintingLayer.getChildren().add(r1);
Button b1 = new Button("Show Size");
b1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
for(Node n : paintingLayer.getChildren())
{
System.out.println("Border...");
System.out.println(getNodeBorderCoords(n, BorderTypes.RIGHT)[0]);
System.out.println(getNodeBorderCoords(n, BorderTypes.RIGHT)[1]);
System.out.println("End Border");
}
}
});
Button b2 = new Button("Add CCSBTN");
b2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
BorderPane bp = new BorderPane();
bp.getStylesheets().add(TestStarter.class.getResource("ReprBox.css").toString());
Rectangle rcss = new Rectangle(50, 50);
bp.setTop(rcss);
bp.getStyleClass().add("my-box");
setObjectOnScreen(bp, 100, 100);
System.out.println(getNodeBorderCoords(bp, BorderTypes.RIGHT)[0]);
System.out.println(getNodeBorderCoords(bp, BorderTypes.RIGHT)[1]);
}
});
this.add(b1, 0, 0);
this.add(b2, 1, 0);
this.add(paintingLayer, 1, 1);
this.setMaxHeight(500);
this.setMaxWidth(700);
this.setHgap(10);
this.setVgap(10);
this.setPadding(new Insets(10, 10, 10, 10));
}
public void setObjectOnScreen(Node obj, double toX, double toY)
{
obj.setLayoutX(toX);
obj.setLayoutY(toY);
paintingLayer.getChildren().add(obj);
}
public double[] getNodeBorderCoords(Node n, BorderTypes type)
{
double x = 0;
double y = 0;
double bx = n.getBoundsInLocal().getWidth();
double by = n.getBoundsInLocal().getHeight();
switch (type)
{
case LEFT:
x = n.getLayoutX();
y = n.getLayoutY() + by / 2;
break;
case RIGHT:
x = n.getLayoutX() + bx ;
y = n.getLayoutY() + by / 2;
break;
case TOP:
x = n.getLayoutX() + bx / 2;
y = n.getLayoutY();
break;
case BOTTOM:
x = n.getLayoutX() + bx / 2;
y = n.getLayoutY() + by;
break;
}
double[] ret =
{ x, y, };
return ret;
}
}
The CSS-File
#CHARSET "ISO-8859-1";
.my-box {
-fx-border-color: rgb(255, 0, 0);
-fx-border-radius: 2;
-fx-padding: 1 1 1 1;
-fx-border-width: 5 5 5 5;
}
By the way, it doesn't matter if use getBoundsInLocal() or getBoundsInParent() .
UPDATE
Here are two workarounds that can be used:
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
Platform.runLater(new Runnable() {
#Override
public void run() {
System.out.println(getNodeBorderCoords(bp, BorderTypes.RIGHT)[0]);
System.out.println(getNodeBorderCoords(bp, BorderTypes.RIGHT)[1]);
}
});
}
});
t.start();
But delaying the call might cause some strange behaviour like i stated in my post. But i found another "solution" recently.
bp.snapshot(new SnapshotParameters(), new WritableImage(5, 5));
System.out.println(getNodeBorderCoords(bp, BorderTypes.RIGHT)[0]);
System.out.println(getNodeBorderCoords(bp, BorderTypes.RIGHT)[1]);
The snapshot() method applies all css effects (and all other layout work) on the node. After that, the returned values of the borders are correct.
There are 2 approaches:
You can use binding instead of static size call. It gives benefits of additional support for update after resize but adds a bit of listeners handling burden on FX enging.
Wrapping size reading logic into Platform.runLater() will put it later into event queue and should address premature size access issue.

iPhone 4.2 airprint Print job fails

No matter which printer I select, I get "Print-job failed: Unsupported document format "application/pdf".
I am trying to print on HP printers only.
I see no place in code to change the output type.
I am using UISimpleTextFormatter to format the string.
Not sure how to get around this one.
Edit : Code below is straight up from Miguel's example. with the only difference being, I tried out the markupformatter to see whether it gets output in a different format than application/pdf.
The print dialog comes up with the list of HP printers, I select a printer but nothing gets printed and in debug mode, the error specified at the top gets logged.
Other than UIPrintInfoOutputType.General, I have also tried UIPrintInfoOutputType.GrayScale but with the same effect.
public partial class AppDelegate : UIApplicationDelegate
{
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window.MakeKeyAndVisible ();
var button = UIButton.FromType (UIButtonType.RoundedRect);
button.Frame = new RectangleF (100, 100, 120, 60);
button.SetTitle ("Print", UIControlState.Normal);
button.TouchDown += delegate {
Print ();
};
window.AddSubview (button);
return true;
}
void Print ()
{
var printInfo = UIPrintInfo.PrintInfo;
printInfo.JobName = "Test :";
printInfo.OutputType = UIPrintInfoOutputType.General;
printInfo.JobName = "Test: My first Print Job";
/*
var textFormatter = new UISimpleTextPrintFormatter ("Once upon a time...") {
StartPage = 0,
ContentInsets = new UIEdgeInsets (72, 72, 72, 72),
MaximumContentWidth = 6 * 72,
};
*/
var htmlFormatter = new UIMarkupTextPrintFormatter("<html><body>Test : Hi There!!</body></html>");
htmlFormatter.StartPage = 0;
htmlFormatter.ContentInsets = new UIEdgeInsets (72, 72, 72, 72); // 1 inch margins
htmlFormatter.MaximumContentWidth = 6 * 72;
var printer = UIPrintInteractionController.SharedPrintController;
printer.PrintInfo = printInfo;
printer.PrintFormatter = htmlFormatter;
printer.ShowsPageRange = true;
printer.Present (true, (handler, completed, err) => {
if (!completed && err != null){
Console.WriteLine ("error");
}
});
}
public override void OnActivated (UIApplication application)
{
}
}
I was expecting the print dialog to come up with only the air print enabled printers. But it comes up with non airprint enabled HP printers as well. That amde me think, it could print to those printers and that they are air print enabled.
But that was not the case.

Resources