Getting an error in in JavaFX - javafx

I am trying to test this code but I am encountering problems. I have netbeans with default JavaFX platform.
This example is from this web site: http://onjava.com/pub/a/onjava/2007/07/27/introduction-to-javafx-script.html?page=4
package captureexample1;
import java.io.*;
import javafx.ui.*;
import javafx.ui.canvas.*;
import javafx.ui.filter.*;
import java.awt.Robot;
import java.awt.Rectangle;
import java.awt.image.RenderedImage;
import javax.imageio.ImageIO;
import java.lang.System;
class CaptureExample extends CompositeNode{
attribute lx: Integer;
attribute ly: Integer;
operation CaptureExample();
}
attribute CaptureExample.lx = 0;
attribute CaptureExample.ly = 0;
operation saveCapture(lx_copy:Integer, ly_copy:Integer) {
var robot = new Robot();
var rect = new Rectangle (lx_copy, ly_copy, 50, 50);
var BI=robot.createScreenCapture(rect);
var file = new File(".//capture.jpg");
ImageIO.write((RenderedImage)BI, "jpg", file);
}
function CaptureExample.composeNode() =
Group{
transform: []
content:[ImageView {
transform: []
image: Image { url: ".//app//Sunset.gif" }
cursor: DEFAULT
onMouseClicked: operation(e:CanvasMouseEvent) {
saveCapture(e.source.XOnScreen,e.source.YOnScreen);
}
onMouseMoved: operation(e:CanvasMouseEvent) {
lx = e.x;
ly = e.y;
}
},
Rect{
x: bind lx
y: bind ly
width: 50
height:50
strokeWidth: 1
stroke: black
}]
};
Frame {
centerOnScreen: true
visible: true
height: 230
width: 300
title: "Capture the screen..."
onClose: operation() {System.exit(0);}
content: ScrollPane {
background: white
view: Canvas {
background: black
cursor: DEFAULT
content: CaptureExample
}
}
}

It seems you are mixing JavaFX script and JavaFX2.
JavaFX script (aka JavaFX 1.3) is obsolete, not supported and old.
modern JavaFX 2 uses Java as language instead of FX script. You can see examples here: http://docs.oracle.com/javafx/2/get_started/jfxpub-get_started.htm
If you really want to use JavaFX 1.3:
get older NetBeans, like 6.1
rename you .java file to .fx
But if you just trying to learn JavaFX I really advise you to try JavaFX 2.

Related

Can't import css houdini paint js file

I have a React/Electron app, where I'm trying to use the new CSS Houdini paint() function (as demonstrated in this page). In my project's index.html file I have added a script tag with the paintWorklet addModule() function as shown:
<script>
CSS.paintWorklet.addModule('../src/ResultDisplay/DefaultResultDisplay/testPaint.js');
</script>
Then in that testPaint.js file I have essentially a copy of what's shown in that blog post:
registerPaint(
"testPaint",
class {
paint(ctx, geom) {
console.log("painting!!!");
const circleSize = 10;
const bodyWidth = geom.width;
const bodyHeight = geom.height;
const maxX = Math.floor(bodyWidth / circleSize);
const maxY = Math.floor(bodyHeight / circleSize);
for (let y = 0; y < maxY; y++) {
for (let x = 0; x < maxX; x++) {
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.arc(
x * circleSize * 2 + circleSize,
y * circleSize * 2 + circleSize,
circleSize,
0,
2 * Math.PI,
true
);
ctx.closePath();
ctx.fill();
}
}
}
}
);
And finally my css file:
.container {
background-image: paint(testPaint);
display: flex;
margin: 4px;
border-radius: 12px;
height: 75px;
}
I should point out I am using CSS Modules, so this file is defaultResultStyles.module.scss; not sure if that affects anything. When I bring up the component that's meant to have these styles in my app, it has no styles, though inspecting it, it does display background-image: paint(testPaint). The console.log that I added to the testPaint.js` file is never shown.
I have tried multiple variations of the filepath for addModule; I've tried just testPaint.js, starting it with ./src and src both, but nothing seems to work; is this possible in an Electron/React app?
The addModule function will not work through webpack or other bundlers, it instead works through the native module system of browsers. You have to put the testPaint.js file in the public directory, otherwise it would get bundled with everything else.
Here's what I added to the index.html to get it to run from the public directory on a local Create React App project:
<script>
CSS.paintWorklet.addModule('%PUBLIC_URL%/testPaint.js');
</script>
I didn't actuallly set up any of the markup and just added the container class to test it out:
If you want to use this without going through the public folder (at all, because normally you'd have to add the paint module in the index.html which is changing the public directory), then I'd suggest using React Helmet to set up the script tags. As a note with this, the hot-reload features of CRA seems to prevent the scripts from updating, so every time you change the script tags, you'll need to refresh the page manually.
import React from 'react';
import { render } from 'react-dom';
import { Helmet } from 'react-helmet';
import styled from 'styled-components';
// Render these styled components like normal react components.
// They will pass on all props and work
// like normal react components – except they're styled!
const Demo = styled.div`
background: #1108a0;
padding: 50px 0;
`;
const Test = styled.div`
--color: cyan;
--multiplier: 0.24;
--pad: 30;
--slant: 20;
background: paint(background-canvas);
transition: --multiplier 0.4s;
font: bold 6em sans-serif;
color: yellow;
text-shadow: 0 3px 1px cyan;
line-height: 1.5em;
width: max-content;
padding-left: 30px;
padding-right: 50px;
isolation: isolate;
&:hover {
--multiplier: 1;
}
& span {
mix-blend-mode: exclusion;
}
`;
export const App = () => (
<Demo>
<Test className="el" right={'right'}>
<span>JS-in-CSS</span>
</Test>
</Demo>
);
export const Helm = () => (
<Helmet>
<script language="javascript+paint">{`
registerPaint('background-canvas', class {
static get inputProperties() {
return ['--multiplier', '--color', '--pad', '--slant'];
}
paint(ctx, geom, properties) {
let multiplier = +properties.get('--multiplier').toString();
let c = properties.get('--color').toString();
let pad = +properties.get('--pad').toString();
let slant = +properties.get('--slant').toString();
ctx.moveTo(0, 0);
ctx.lineTo(pad + (geom.width - slant - pad) * multiplier, 0);
ctx.lineTo(pad + (geom.width - slant - pad) * multiplier + slant, geom.height);
ctx.lineTo(0, geom.height);
ctx.fillStyle = c;
ctx.fill();
}
})
`}</script>
<script>{`
if ("paintWorklet" in CSS) {
const src = document.querySelector('script[language$="paint"]').innerHTML;
const blob = new Blob([src], {
type: 'text/javascript'
});
CSS.paintWorklet.addModule(URL.createObjectURL(blob));
}
`}</script>
</Helmet>
);
render(
<div>
<Helm />
<App />
</div>,
document.getElementById('root')
);
If you're looking to avoid using /public, you can use a monorepo manager like Yarn Workspaces to keep your worklet in a dedicated package. Then, you can import it into your client app like you would any other package dependency.
Step by step (using Yarn Workspaces):
create dedicated packages for your app (package.json name is #packages/myapp) and worklet (#packages/myworklet)
add your worklet as a dependency to your app -- from #packages/myapp run yarn add #packages/myworklet
import your worklet from #packages/myworklet and add it -- see https://houdini.how/usage/

QT Quick Test KeyClicks

I am trying to implement a keyClick with a shift modifier but it doesn't work. Below is a basic setup of what I am trying to do. The first test_case1 can perform what I am doing but I'd like the second test_case2 to work as well but with using the Qt.ShiftModifier.
../MyTextBox.qml
Page {
id: page1
objectName: "page1"
TextField {
id: lastNameField
objectName: "lastNameField"
text: qsTr("")
}
}
tst_page.qml
import "../"
Item {
width: 800
height: 600
MyTextBox {
id: page1
}
TestCase {
id: "txtBox"
when: windowShown
function test_case1 () {
//var qmlObj = findChild(page1, "lastNameField")
var qmlObj = page1.lastNameField
// Bring to focus
mouseClick(qmlObj, Qt.LeftButton, Qt.NoModifier)
// Keypress
keyPress("Y")
keyPress("e")
keyPress("s")
tryCompare(qmlObj, "text", "Yes") // pass
}
function test_case2 () {
var qmlObj = page1.lastNameField
// Bring to focus
mouseClick(qmlObj, Qt.LeftButton, Qt.NoModifier)
// Keypress
keyClick(QT.Key_Y, Qt.ShiftModifier)
keyClick(QT.Key_E)
keyClick(QT.Key_S)
tryCompare(qmlObj, "text", "Yes") // fail
}
}
}
test output
PASS : test_case1()
FAIL! : test_case2()
Actual (): yes
Expected (): Yes
Edit: Added a simple project to github for testing.

Is this right way to code for JavaFx application?

I am new to JavaFX. SO i would like to know is the code provided below is the good way to caode in for JavaFX application by declaring .fx files.
or
We should code using.java files.
Help is needed on this regard.
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.scene.text.Text;
import javafx.ext.swing.SwingLabel;
import javafx.ext.swing.SwingTextField;
import javafx.ext.swing.SwingButton;
var login = false;
var userName = "";
var systemUser = "test";
Stage {
title : "Login App"
scene: Scene {
width: 300
height: 300
content: bind if(not login) Group{
content: [
SwingLabel{
text: "User Name:"
},
SwingTextField {
text : bind userName with inverse;
columns : 10;
editable : true;
},
SwingButton{
translateX: 50
translateY: 50
text: "Submit"
action: function(){
if((userName != systemUser)) {
println("Invalid UserName");
}
login = (userName == systemUser);
}
}
]
}
else Group{
content: [
Text {
x: 10 y: 30
content: "You have successfully logged in."
},
SwingButton{
translateX: 10
translateY: 50
text: "Log out"
action: function(){
userName = "";
login = false;
}
}
]
}
}
}
The JavaFX script code (with .fx files) in your question is from the obsolete JavaFX 1.x branch. I strongly advise you not to use the JavaFX 1.x branch. Oracle will drop all support for it this month.
The script code in your question also integrates Swing controls inside JavaFX, which is not supported in current JavaFX 2.x releases.
Instead, use JavaFX 2+ and write your JavaFX code in Java (with .java files) using only JavaFX controls and no Swing controls.
There are some excellent tutorials to get you started:
Oracle's Ensemble Sample
edu.maker.ch JavaFX Tutorial
Oracle's JavaFX HelloWorld App
JavaFX Documentation Home
StackOverflow JavaFX Community Wiki Resource List
Oracle's Java tutorials (if you need to learn the Java language)

CSSBuilder can be used without Griffon?

I have a standalone Swing application and I'm using Groovy as programing language.
Trying to apply styles using CSS and searching for some tool for this purpose, I've found CSSBuilder.
The problem is that CSSBuilder comes integrated with Griffon framework, so I cannot use all of its features isolated from Griffon, such as 'cssClass' selector.
Therefore my question is simply: has anyone managed to do something like this?
Just wrote a quick test, and this seems to work:
#GrabResolver( name='codehaus', root='http://repository.codehaus.org' )
#Grab( 'org.codehaus.griffon:cssbuilder:0.4' )
import griffon.builder.css.*
import groovy.swing.SwingBuilder
import java.awt.BorderLayout as BL
def style = '''* {
background-color: red;
}
jbutton {
background-color: blue;
}
.active {
color: green ;
font-size: 50%;
}
jlabel {
color: pink ;
font-size: 200% ;
}'''
Class klass = javax.swing.JComponent
if( !AbstractSyntheticMetaMethods.hasBeenEnhanced(klass) ) {
AbstractSyntheticMetaMethods.enhance(klass,[
"getCssClass": {-> delegate.getClientProperty(ClarityConstants.CLIENT_PROPERTY_CLASS_KEY) },
"setCssClass": { String cssClass -> delegate.putClientProperty(ClarityConstants.CLIENT_PROPERTY_CLASS_KEY, cssClass) }
])
}
new SwingBuilder().edt {
int count = 0
def frame = frame( title:'CSS Test', size:[ 300, 300 ], show: true ) {
borderLayout()
textlabel = label(text:"Click the button!", constraints: BL.NORTH)
button(text:'Click Me',
cssClass: 'active',
actionPerformed: {count++; textlabel.text = "Clicked ${count} time(s)."; println "clicked"},
constraints:BL.SOUTH)
}
CSSDecorator.applyStyle( style, frame )
}
The meta-class enhancing code I took from the source of CSSBuilder

Javafx - Clipview to a Group?

Can I apply clipview to a vertical expanding Group? Time to time I'm appending text to a group and want to use scrollbar to navigate in that group. The scrollbar part is working when I assign it to the group itself but want to limit the size of the group by using clipview.
Anyone having experience in this?
The clipview basically just creates a view portal into its content. Here is a simple example. (You would need to handle the clipY properly when clip.maxY is < scene.height).
var group = VBox { };
var ndx:Integer = 0;
def cv : ClipView = ClipView {
pannable: false
node: group
width: bind scene.width - sb.layoutBounds.width
height: bind scene.height
};
var scene: Scene;
var sb: ScrollBar;
Stage {
title: "ClipView Test"
scene: scene = Scene {
width: 250
height: 80
content: [
cv,
Rectangle {
layoutX: bind scene.width - sb.layoutBounds.width - 50
width: 50
height: 50
fill: Color.RED
onMouseClicked: function(e) {
insert Text { content: "Text - {ndx++}" } into group.content;
if(cv.maxClipY > scene.height) {
cv.clipY = cv.maxClipY;
}
}
}
sb = ScrollBar {
vertical: true
layoutX: bind scene.width - sb.layoutBounds.width
height: bind scene.height
min: 0
max: bind cv.maxClipY
value: bind cv.clipY with inverse
}
]
}
}

Resources