Laziness in ScalaFX nodes - scala

Here is an example from Pro ScalaFX:
package proscalafx.ch02.stagecoach
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.beans.property.StringProperty
import scalafx.geometry.VPos
import scalafx.scene.control.{Button, CheckBox, Label, TextField}
import scalafx.scene.input.MouseEvent
import scalafx.scene.layout.{HBox, VBox}
import scalafx.scene.paint.Color
import scalafx.scene.shape.Rectangle
import scalafx.scene.text.Text
import scalafx.scene.{Group, Scene}
import scalafx.stage.{Screen, StageStyle}
/** Stage property example.
*
* Can be run with various command line parameters to control stage style:
* decorated - a solid white background and platform decorations (default).
* transparent - transparent background and no decorations.
* undecorated - a solid white background and no decorations.
* utility - a solid white background and minimal platform decorations used for a utility window.
* #author Rafael
*/
object StageCoachMain extends JFXApp {
val titleProperty = StringProperty("")
// Process command line parameters
val stageStyle = parameters.unnamed match {
case Seq("transparent") => StageStyle.TRANSPARENT
case Seq("undecorated") => StageStyle.UNDECORATED
case Seq("utility") => StageStyle.UTILITY
case _ => StageStyle.DECORATED
}
lazy val textStageX = new Text {
textOrigin = VPos.Top
}
lazy val textStageY = new Text {
textOrigin = VPos.Top
}
lazy val textStageW = new Text {
textOrigin = VPos.Top
}
lazy val textStageH = new Text {
textOrigin = VPos.Top
}
lazy val textStageF = new Text {
textOrigin = VPos.Top
}
lazy val checkBoxResizable = new CheckBox {
text = "resizable"
// disable = stageStyle == StageStyle.TRANSPARENT || stageStyle == StageStyle.UNDECORATED
}
lazy val checkBoxFullScreen = new CheckBox {
text = "fullScreen"
}
lazy val titleTextField = new TextField {
text = "Stage Coach"
prefColumnCount = 15
}
stage = new PrimaryStage {
resizable = false
title <== titleProperty
scene = new Scene(370, 370) {
fill = Color.Transparent
root = new Group {
children = List(
new Rectangle {
width = 350
height = 350
arcWidth = 50
arcHeight = 50
fill = Color.SkyBlue
},
new VBox {
layoutX = 30
layoutY = 20
spacing = 10
children = List(
textStageX,
textStageY,
textStageW,
textStageH,
textStageF,
checkBoxResizable,
checkBoxFullScreen,
new HBox {
spacing = 10
children = List(
new Label("title:"),
titleTextField)
},
new Button {
text = "toBack()"
onAction = handle {stage.toBack()}
},
new Button {
text = "toFront()"
onAction = handle {stage.toFront()}
},
new Button {
text = "close()"
onAction = handle {stage.close()}
}
)
}
)
}
}
}
//when mouse button is pressed, save the initial position of screen
val rootGroup = stage.scene().content(0)
var dragAnchorX = 0.0
var dragAnchorY = 0.0
rootGroup.onMousePressed = (me: MouseEvent) => {
dragAnchorX = me.screenX - stage.x.value
dragAnchorY = me.screenY - stage.y.value
}
rootGroup.onMouseDragged = (me: MouseEvent) => {
stage.x = me.screenX - dragAnchorX
stage.y = me.screenY - dragAnchorY
}
textStageX.text <== new StringProperty("x: ") + stage.x.asString
textStageY.text <== new StringProperty("y: ") + stage.y.asString
textStageW.text <== new StringProperty("width: ") + stage.width.asString
textStageH.text <== new StringProperty("height: ") + stage.height.asString
textStageF.text <== new StringProperty("focused: ") + stage.focused.asString
stage.resizable = false
// NOTE: Due to a bug in JavaFX (2.2.3+) Stage.resizableProperty(), cannot directly use binding here,
// see http://javafx-jira.kenai.com/browse/RT-25942
// TODO: Revert to binding once JavaFX bug is corrected
// stage.resizable <==> checkBoxResizable.selected
checkBoxResizable.selected.onChange {
// To avoid using resizableProperty, use delegate.setResizable()
// stage.resizable = checkBoxResizable.selected.get
stage.delegate.setResizable(checkBoxResizable.selected())
}
checkBoxFullScreen.onAction = handle {
stage.fullScreen = checkBoxFullScreen.selected()
}
stage.title <== titleTextField.text
stage.initStyle(stageStyle)
stage.onCloseRequest = handle {println("Stage is closing")}
val primScreenBounds = Screen.primary.visualBounds
stage.x = (primScreenBounds.width - stage.width()) / 2
stage.y = (primScreenBounds.height - stage.height()) / 2
}
If I remove lazy before these Text objects, the app seems to works exactly the same as before. For example the textStageX object should show x-coordinate of the stage in real-time, and it still does without being lazy. So, what purpose does lazy serve here?
Another problem is that these lines of code
val primScreenBounds = Screen.primary.visualBounds
stage.x = (primScreenBounds.width - stage.width()) / 2
stage.y = (primScreenBounds.height - stage.height()) / 2
seems to intend to place the window at the center of the primary screen, but fails to do so (on OS X 10.10, with Java 1.8 and Scala 2.11.7).

lazy in unnecessary here. It is used in JFXApp if there are initialization order issues.
For the centering to work. The stage has to be shown first. I am not sure it this new in JavaFX 8 or there was a bug in original StageCoachMain code. Just add:
stage.show()
before the last three lines. You can also replace them with simply:
stage.centerOnScreen()
Thanks for pointing this out. I cleaned up the code in ProScalaFX repo.

Related

How to properly display floating Buttons on top of BottomNavigationView?

I want to display 2 "floating buttons" a bit on top of a BottomNavigationView if one of its menu is clicked.
Here's my attempt. Basically it uses an AlertDialog supplied with a LinearLayout (full code: https://github.com/anta40/ButtonAnimTest)
bottomNav.setOnItemSelectedListener { menu ->
when (menu.itemId){
R.id.game_menu -> {
val dialogBuilder = AlertDialog.Builder(this)
val customView = layoutInflater.inflate(R.layout.custom_alert_layout, null)
dialogBuilder.setView(customView)
dialogBuilder.setCancelable(true)
val btnYes = customView.findViewById<Button>(R.id.btn_dialog_yes)
val btnNo = customView.findViewById<Button>(R.id.btn_dialog_no)
/*
taken from https://stackoverflow.com/questions/9467026/changing-position-of-the-dialog-on-screen-android
*/
val alert = dialogBuilder.create()
val dialogWindow = alert.window
val layoutParams = dialogWindow!!.attributes
layoutParams.gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
layoutParams.flags = layoutParams.flags and WindowManager.LayoutParams.FLAG_DIM_BEHIND.inv()
dialogWindow.attributes = layoutParams
dialogWindow.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
btnYes.setOnClickListener {
alert.dismiss()
}
btnNo.setOnClickListener {
alert.dismiss()
}
alert.show()
true
}
}
false
}
}
There are 2 problems:
The LinearLayout is displayed too high, aligned with the TitleBar. What I want is just a little bit on top of the BottomNavigationView, like 10dp or 20dp.
The screen is dimmed a bit. I don't want the brightness to be changed when those buttons appear.
How to fix these?

ScalaFX: how to wrap text in a TableCell

I want to show a list of key and values in a TreeTableView, and some of the values are a bit longer text which I want to wrap around and show completely.
I thought I use TextFieldTreeTableCell with wrapText and vgrow as follows:
val valCol = new TreeTableColumn[(String,String), String] {
text = "Header"
cellValueFactory = { p => StringProperty(p.value.value.value._2) }
cellFactory = { p => new TextFieldTreeTableCell[(String,String),String]() {
wrapText = true
vgrow = Priority.Always
} }
}
But the text is only shown in one line wiht ... at the end.
What am I missing?

How to add text on desired coordinates on new word file using openxml

I want to create .docx file using openxml and add text on desired coordinates(location) on each page of the file. Is there any way in openxml to adjust the text. I am using the following snippet:
WordprocessingDocument doc = WordprocessingDocument.Create("E:\\test11.docx", DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
{
MainDocumentPart mainPart = doc.AddMainDocumentPart();
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Paragraph para = body.AppendChild(new Paragraph());
ParagraphProperties oParagraphProperties = para.AppendChild(new ParagraphProperties());
Run run = para.AppendChild(new Run());
Text tt = new Text(str);
run.AppendChild(tt);
RunProperties runProp = new RunProperties(); // Create run properties.
RunFonts runFont = new RunFonts() { Ascii = "Cambria(Headings)", HighAnsi = "Cambria(Headings)" };
Bold bold = new Bold();
DocumentFormat.OpenXml.Wordprocessing.Color Color1 = new DocumentFormat.OpenXml.Wordprocessing.Color() { Val = "0EBFE9" };
Italic ita = new Italic();
runProp.Append(bold);
runProp.Append(Color1);
runProp.Append(ita);
FontSize size = new FontSize();
size.Val = new StringValue((fontSize * 2).ToString()); // 48 half-point font size
runProp.Append(runFont);
runProp.Append(size);
run.PrependChild<RunProperties>(runProp);
}
Using this I was able to add text on .docx file, but not on desired coordinate location. Can someone help with this?
Thanks.
I found a way to add text to a coordinate on the page of a Word file. I started with your generated Word file and using Word, I added a simple TextBox (Insert->Text->TextBox). I generated the code for the added TextBox using the Productivity Tool. (Note: as of this writing, the latest version of the SDK is now 2.5, which is recommended for this to work).
Add the following method to your class above:
private static void PlaceTextAtCoordinate(Paragraph para, string text, double xCoordinate, double uCoordinate)
{
var picRun = para.AppendChild(new Run());
Picture picture1 = picRun.AppendChild(new Picture());
Shapetype shapetype1 = new Shapetype() { Id = "_x0000_t202", CoordinateSize = "21600,21600", OptionalNumber = 202, EdgePath = "m,l,21600r21600,l21600,xe" };
Stroke stroke1 = new Stroke() { JoinStyle = StrokeJoinStyleValues.Miter };
Path path1 = new Path() { AllowGradientShape = true, ConnectionPointType = ConnectValues.Rectangle };
shapetype1.Append(stroke1);
shapetype1.Append(path1);
Shape shape1 = new Shape() { Id = "Text Box 2", Style = string.Format("position:absolute;margin-left:{0:F1}pt;margin-top:{1:F1}pt;width:187.1pt;height:29.7pt;z-index:251657216;visibility:visible;mso-wrap-style:square;mso-width-percent:400;mso-height-percent:200;mso-wrap-distance-left:9pt;mso-wrap-distance-top:3.6pt;mso-wrap-distance-right:9pt;mso-wrap-distance-bottom:3.6pt;mso-position-horizontal-relative:text;mso-position-vertical-relative:text;mso-width-percent:400;mso-height-percent:200;mso-width-relative:margin;mso-height-relative:margin;v-text-anchor:top", xCoordinate, uCoordinate), Stroked = false };
TextBox textBox1 = new TextBox() { Style = "mso-fit-shape-to-text:t" };
TextBoxContent textBoxContent1 = new TextBoxContent();
Paragraph paragraph2 = new Paragraph();
Run run2 = new Run();
Text text2 = new Text();
text2.Text = text;
run2.Append(text2);
paragraph2.Append(run2);
textBoxContent1.Append(paragraph2);
textBox1.Append(textBoxContent1);
TextWrap textWrap1 = new TextWrap() { Type = WrapValues.Square };
shape1.Append(textBox1);
shape1.Append(textWrap1);
picture1.Append(shapetype1);
picture1.Append(shape1);
}
The following usings were found in my class - your list may be different - but I wanted to detail them here just in case.
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Vml;
using DocumentFormat.OpenXml.Vml.Office;
using DocumentFormat.OpenXml.Vml.Wordprocessing;
using DocumentFormat.OpenXml.Wordprocessing;
Finally, add the following 2 calls to the very end of your method above:
PlaceTextAtCoordinate(para, "Text at 90.1,90.1", 90.1, 90.1);
PlaceTextAtCoordinate(para, "Text at 120.5,120.5", 120.1, 120.1);
and your Word Doc will look like the following:

syncfusion chart background line will be dotted line

I want my chart backgroud line will be dotted. Which property can i use for dotted in syncfusion? I tried but i coudn't do this. I don't know exactly which propertly will use for dotted line.
Here is my code:
control.AutoTempFileCleanUp = true;
control.OutputFormat = ImageProviderOutputFormat.DiskFile;
control.Model.Series.Clear();
ChartModel chartModel = new ChartModel();
ChartSeries chart = new ChartSeries(yAxisBar1LegendName, ChartSeriesType.Column);
chart.Text = yAxisBar1LegendName;
control.ChartArea.PrimaryXAxis.TickLabelsDrawingMode = ChartAxisTickLabelDrawingMode.UserMode;
// = string.Format("");
control.ChartArea.PrimaryXAxis.Labels.Add(new ChartAxisLabel("", Color.Black, new Font("Arial", 10), 0, "", ChartValueType.Custom));
int counter = 1;
DoubleRange dr = new DoubleRange(1, 100);
foreach (DataRow row in ds.Tables[0].Rows)
{
double bar1Value = Convert.ToDouble(row[yAxisValueColumn1]);
chart.Points.Add(counter, bar1Value);
control.ChartArea.PrimaryXAxis.Labels.Add(new ChartAxisLabel(row["ModuleCode"].ToString(), Color.Black, new Font("Arial", 10), counter, "", ChartValueType.Custom));
counter++;
}
chart.PrepareStyle += new ChartPrepareStyleInfoHandler(series_PrepareStyle);
control.ChartArea.PrimaryXAxis.DrawGrid = false;
control.PrimaryXAxis.GridLineType.ForeColor = Color.DarkGray;
control.PrimaryYAxis.GridLineType.ForeColor = Color.DarkGray;
control.PrimaryXAxis.LineType.ForeColor = Color.DarkGray;
control.PrimaryYAxis.LineType.ForeColor = Color.DarkGray;
control.Text = chartHeader;
control.ChartArea.PrimaryYAxis.Title = yAxisText;
control.ChartArea.PrimaryXAxis.Title = xAxisText;
control.ChartArea.PrimaryXAxis.TitleAlignment = StringAlignment.Center;
control.ChartArea.PrimaryXAxis.IsVisible = true;
control.ChartArea.PrimaryXAxis.LabelAlignment = StringAlignment.Center;
control.ChartArea.PrimaryXAxis.VisibleRange.Min = 0;
control.ChartArea.PrimaryXAxis.VisibleRange.Max = counter;
control.ChartArea.PrimaryXAxis.VisibleRange.Interval = 1;
control.ChartArea.PrimaryYAxis.EdgeLabelsDrawingMode = ChartAxisEdgeLabelsDrawingMode.Center;
control.ChartArea.PrimaryYAxis.GridDrawMode = ChartAxisGridDrawingMode.Default;
//control.PrimaryXAxis.EdgeLabelsDrawingMode = ChartAxisEdgeLabelsDrawingMode.Center;
control.PrimaryXAxis.Font = new Font("Arial", 10F);
control.PrimaryYAxis.Font = new Font("Arial", 10F);
counter = 0;
foreach (ChartSeries series in control.Series)
{
Color color;
if (counter == 0)
{
color = Color.Green;
else
{
color = Color.Red;
}
series.Style.Interior = new BrushInfo(color);
series.Style.Border.Color = Color.DarkGray;
series.Style.Font.Bold = true;
series.Style.TextColor = Color.Black;
series.Style.TextOrientation = ChartTextOrientation.Left;
series.Style.TextFormat = "{0}";
counter++;
}
control.Width = 650;
control.Series3D = false;
control.ShowLegend = false;
control.BorderStyle = BorderStyle.None;
control.BorderAppearance.SkinStyle = ChartBorderSkinStyle.None;
//control.Legend.Alignment = ChartAlignment.Far;
}
Here is my chart image:
Thanks for using syncfusion products.
We have analyzed your query. If you want to customize the grid lines in axis, then you can use the “DashStyle” property in GridLineType which property is used to change the line style. And you can also specify the grid line style as Dash, DashDot, DashDotDot, Dot, Solid in axis.
And please find the below code snippet
this.ChartWebControl1.PrimaryYAxis.GridLineType.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
And we have also prepared a sample for your reference in ASP.NET classic platform and attached in the below location.
Sample Link : http://www.syncfusion.com/downloads/support/directtrac/160606/ze/Sample1273790903
Please find the output of the sample below:
And also we wish to let you know that the above mentioned property is also applicable for chart control in windows forms, ASP.NET classic and ASP.NET MVC classic platforms.
Please contact us via syncfusion support, if you have any queries related to using syncfusion products.

Scala instantiation of a class with curly braces

I am starting with Scala and with ScalaFX, I understand most of the code but I don't understand this code using for the examples in ScalaFx;
where instantiate an anonymous class follow it by curly braces, How this works???
object ScalaFXHelloWorld extends JFXApp {
stage = new PrimaryStage {
title = "ScalaFX Hello World"
scene = new Scene {
fill = Black
content = new HBox {
padding = Insets(20)
children = Seq(
new Text {
text = "Hello"
style = "-fx-font-size: 48pt"
fill = new LinearGradient(
endX = 0,
stops = Stops(PaleGreen, SeaGreen)
)
},
new Text {
text = "World!!!"
style = "-fx-font-size: 48pt"
fill = new LinearGradient(
endX = 0,
stops = Stops(Cyan, DodgerBlue)
)
effect = new DropShadow {
color = DodgerBlue
radius = 25
spread = 0.25
}
}
)
}
}
}
}
the part I don't understand is why in the creation of an anonymous class is follow by curly braces (with some more declarations)(Scene is not a trail to be filling the abstract parts of that class) and even fill or content are functions not a variables and Black for fill for instant is a val meaning that this line
fill = Black
is doing calling a function fill and assigning a val to it(don't make sense for me ), this is fill definition
def fill: ObjectProperty[jfxsp.Paint] = delegate.fillProperty
and this is Black
val Black = new Color(jfxsp.Color.BLACK)
how works this instantiation of a new object with curly braces please help, want to understand.
This is because ScalaFx is wrapping JavaFx and something special is going on here?.
Thank you guys.
Update:
Well now I know that it is calling a setter via syntax sugar however I check that setter and I don't understand what is going on there
Check it out:
def fill: ObjectProperty[jfxsp.Paint] = delegate.fillProperty
def fill_=(v: Paint) {
fill() = v
}
how come the setter is calling the getter to update the value?
delegate.fillProperty
is a function that return a value
The syntax for anonymous classes in Scala is borrowed from Java; you can see it here, too:
class Coder {
protected String name;
public Coder(String name) {this.name = name;}
}
public static void main(String[] args) {
// Prints "Mr. Noble"
new Coder("Noble") {
private String prefix = "Mr.";
{
System.out.println(prefix + " " + name);
}
}
}
Because Scala lets you write your constructor code in the class body, all of your x = y statements are executed when you instantiate those anonymous classes. As #resueman points out, these are actually getters and setters in this format:
class Scene {
var _fill
def fill_=(color: Color) // Setter, has some hidden logic to set up the UI
def fill = _fill // Getter
}
And your statement fill = Black is desugared to fill_=(Black).