Implementing the Ace Code Editor in JavaFX - java

I am trying to make a code editor using JavaFX and want to use Ace. I saw an earlier post that used WebView to achieve this but I am a little lost on how to set up my project structure beforehand.

The following is a very minimal implementation with JavaFX's WebView and the Ace editor.
To get started, I'll just use a few required js files from the Ace repository:
editor.html, this is the main entry. Download from here, and add it to the resources folder, like: src/main/resources/ace/editor.html.
mode-java.js, download from here, and add it to resources: src/main/resources/ace/js/mode-java.js.
theme-eclipse.js, download from here, and add it to resources: src/main/resources/ace/js/theme-eclipse.js.
Note that the above project structure corresponds with the use of Maven or Gradle build tools. To get started, I used this project as a reference.
Now edit the editor.html file, and replace the existing scripts with:
<script src="js/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
var editor = ace.edit("editor");
editor.setTheme("ace/theme/eclipse");
editor.session.setMode("ace/mode/java");
</script>
Optionally, replace the javascript function with some java code, like:
<pre id="editor">package com.ace.editor;
import java.util.ArrayList;
public class AceEditor {
/*
* This is a demo
*/
public static void main(String[] args) {
System.out.println("Hello World");
}
}</pre>
Finally, in your JavaFX code, add a WebView control, and load the editor:
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.load(getClass().getResource("/ace/editor.html").toExternalForm());
Scene scene = new Scene(webView, 600, 400);
...
Note that you will need to add the javafx.web module. This is using Gradle, but the same could be done with Maven.
javafx {
version = "13"
modules = [ 'javafx.web' ]
}
Build and run the project, and you should get the code editor:
More functionality can be added by modifying the editor.html file, and adding more js files, to extend the editor options. For instance, this shows you can add a statusbar.
EDIT
This is my project structure:
(It uses FXML as well, but doesn't change anything of the above).

Related

Vaadin 8. Resource cannot be resolved

I tried to add an overlay plugin. https://vaadin.com/directory/component/overlays
I have a problem with image overlay. Im getting that error:
The type com.vaadin.terminal.Resource cannot be resolved.
It is indirectly referenced from required .class file
problem is with this line:
io.setImage(res);
how can I fix it? I put icon-new.png to the class package folder and added into maven overlays plugin
My code:
final ImageOverlay io = new ImageOverlay(button);
Resource res = new ClassResource(this.getClass(), "../icon-new.png");
io.setImage(res);
io.setComponentAnchor(Alignment.TOP_LEFT); // Top left of the button
io.setOverlayAnchor(Alignment.MIDDLE_CENTER); // Center of the image
io.setClickListener(new OverlayClickListener() {
public void overlayClicked(CustomClickableOverlay overlay) {
Notification.show("ImageOverlay Clicked!");
}
});
layout.addComponent(io);
io.setEnabled(true);
I need to achive that on the button will show up an overlay. If the user clicked on this button and added a new content something like taht show up on the button
That's because it's compatible with Vaadin 6 only as it's indicated in the add-on page:
If you scroll to the comments section, someone is suggesting a fork of the add-on compatible with Vaadin 7, but I could not see anything related to 8:
HI ALL! You can find version 1.1.3 for Vaadin 7.6 here: https://github.com/Haulmont/vaadin-overlays/releases
YURIY ARTAMONOV
Add-ons that are compatible with multiple Vaadin versions, indicate this explicitly, and usually (but not necessarily... dev's choice) have different version numbering, eg: 1.x for Vaadin 6, 2.x For Vaadin 7, 3.x for Vaadin 8, etc:
Either way, clicking on the link for a specific Vaadin version, will select the latest add-on release compatible with it. Or, if you select an add-on release from the drop-down, the Vaadin version compatible with it will be updated accordingly.
Edit after update
You can use a regular button + the predefined BUTTON_ICON_ALIGN_RIGHT Valo style. From the javadoc:
/**
* Align the icon to the right side of the button caption. Can be combined
* with any other Button style.
*/
public static final String BUTTON_ICON_ALIGN_RIGHT = "icon-align-right";
Please note that for the best UI result, I've used 24x24 icons, but depending on your requirements you can tweak your theme for the size you need. Also if you don't have icons and don't want to spend money or time buying or creating your own icons, you can use the existing Vaadin Font Icons (list of icons and matching java enum)
public class ButtonWithIconOnTheRightComponent extends VerticalLayout {
public ButtonWithIconOnTheRightComponent() {
// text filed to specify icon URL
TextField urlField = new TextField("Icon URL", "http://files.softicons.com/download/toolbar-icons/status-icons-set-by-iconleak/png/16x16/30.png");
// button which updates its icon using the URL specified in the text field above
Button button = new Button("Update icon", event -> event.getButton().setIcon(new ExternalResource(urlField.getValue())));
// use valo style to align icon to the right
button.addStyleName(ValoTheme.BUTTON_ICON_ALIGN_RIGHT);
// add components to the UI
addComponents(urlField, button);
setSpacing(true);
}
}

JavaFX - Cannot Load Image Inside Project Directory

I am using netbeans. I have a project directory like this:
HTMLEdit/
src/
htmledit/
- pic.png
- MyClass.java
I tried to get the image, but it return null. I had trying both of these but still cannot get it to work:
System.out.println(getClass().getResourceAsStream("/pic.png"));
and
System.out.println(getClass().getResourceAsStream("pic.png"));
What's causing this weird behavior?
EDIT :
It looks like it's because I choosed JAVAFX Project when created the project. I recreate the project by choosing Java Project and it works fine. May be this is Netbeans bug.
getClass().getResourceAsStream() is used for files embedded inside your java jar file. You should use FileInputStream if you need to read a file from your file system as a stream of bytes. Here's the documentation: https://docs.oracle.com/javase/8/docs/api/java/io/FileInputStream.html
When you do getClass().getResourceAsStream("/pic.png")then the url that will be looked to access the file will be an absolute url. The absolute URL is indicated by the slash which is at the front of the resource location.
If you do getClass().getResourceAsStream("pic.png"), then a resource relative to the package where the class resides will be used.
Because you said that both of the getResourceAsStream() statements did not work in Netbeans, I checked the below JavaFX code in Netbeans and it worked perfectly.
public class MyClass extends Application{
#Override
public void start(Stage primaryStage) {
Pane root = new Pane();
Image images = new Image(getClass().getResourceAsStream("pic.png"));
ImageView image = new javafx.scene.image.ImageView(images);
root.getChildren().add(image);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Here is the structure and the output of the program.
In case if you want to know the Netbeans version, I am using then it is Netbeans 8.0.2.
Also, read the following post.
Different ways of loading a file as an InputStream

How can I make React Component Structure in Idea Intellij 15?

I'm new to IntelliJ Idea and working with IntelliJ Idea 15. I'm working on a react project. I want something which can generate a react component by the direct click in that folder. e.g.
Now there should be an option for making a new React Component. Upon clicking that a pop-up should open which should ask what files I want to add in the Component's Directory. e.g. the structure should be :
e.g.
Component
Component.js
index.js
component.scss
test Directory
Component.test.js
These should be configured according to the need of user. I don't know java and anything about IntelliJ plugins development. How can I do it?
Go to the template settings:
Windows and Linux: File | Settings | Editor | File and Code Templates
macOS: IntelliJ IDEA | Preferences | Editor | File and Code Templates
Click on the plus button and add a new template:
Name: React Component
Extension: js
This template works well for me:
import React, { PropTypes, Component } from 'react';
class ${NAME} extends Component {
render() {
const { } = this.props;
return (
<div>
</div>
);
}
}
${NAME}.propTypes = {
};
export default ${NAME};
You can also PureComponent or add some default props if you like.
I don't think so that you need such a structure of the component. React components are pretty much straight forward. You just create a JavaScript file and write like that.
import React, {Component} from 'react';
class YourComponent extends Component {
render() {
return(
<h1>Hello React</h1>
)
}
}
export default YourComponent;

JavaFX 2 WebView URL Listener

When using a JavaFX (2.2) WebView, is there a way to listen to and handle url's within java code?
For example: I'm loading a local HTML file to my WebView with webEngine.loadContent(html). The HTML contains resources like
<script src="local:my-script.js"></script>
<img src="cms:1234.png"/>
which is also a local file and should be provided from the java application. So I want to register a listener that could handle requests from the page.
Edit: The resource data that is loaded within the HTML page comes from a content-managemant-system so using relative paths is not working.
Create your own URL protocol handler and install it using:
URL.setURLStreamHandlerFactory(new HandlerFactory());
A New Era for Java URL Protocol Handlers article provides detailed instructions for creating the handler.
WebView can make use of your custom protocol to load your content.
The easiest way for you would be substituting local: resource with runtime value in html right before loading it. E.g.:
public class WebViewLocal extends Application {
#Override
public void start(Stage primaryStage) {
String st = "<html><head><title>X</title>"
+ "</head><body><img src='local:1.jpg'/>"
+ "</body></html>";
System.out.println(st);
primaryStage.setScene(new Scene(loadHtml(st), 400, 400));
primaryStage.show();
}
public WebView loadHtml(String html) {
html = html.replace("local:", getClass().getResource(".").toString());
WebView view = new WebView();
view.getEngine().loadContent(html);
return view;
}
public static void main(String[] args) { launch(); }
}
N.B.: This is working sample, just put 1.jpg image at the same place as this file.
If you really want to work with java class from javascript you can use "JavaFX to JavaScript bridge" feature. Take a look at tutorial here: https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx
If you load your html-file locally, you can simply use relative paths:
This is an example, which load html, with relative scripts.
http://code.google.com/p/jfx-gap/source/browse/src/main/java/com/googlecode/jfxgap/JFXGap.java
The trick schould be the relative path inside the html.

Render and Export FusionCharts on the Server

I am trying to render and export FusionCharts completely on the server. I am aware of solutions such as FCimg and FusionCharts .NET Solution. I have also implemented a Java solution that uses the Process class to run wkhtmltoimage.
However, I am trying to find a pure Java solution of doing this. I have an html file that includes FusionCharts JS Libraries and code to generate the fusion chart. I found JxBrowser that properly renders the chart but it requires X-Server for it to work on Linux. I also have tried Cobra/Lobo Browser but it does not fully support JavaScript. Are there any other ways to render and export fusion charts on the server or atleast render an html file that includes JavaScript completely in Java (and that does not require xserver)?
Thanks in advance for all the help!
Update: Solution that does not require xserver: WebRenderer. The Swing Edition is the only edition that supports HTML5 as of July 9th, 2012. You can use the swing edition to capture the image without a GUI.
I found a way that uses Eclipse's SWT Browser. However this cannot be run in an headless mode. You will have to use xserver to implement this. See this question.
Since this requires xserver and cannot be run in an headless mode, I would suggest using JxBrowser. It is a lot simpler and all you need is to generate an html file with all the fusion charts scripts. See #1, #2, #3
You have to create a template.html file that contains the header
(<html><head>), jquery.min.js, FusionCharts.js,
FusionCharts.HC.js, FusionCharts.HC.Charts.js. Make sure each of
these scripts are in their own script tags (<script type="text/javascript"> [js code] </script>)
Now add another JavaScript function with its own script tags containing the steps to render the chart. For example:
function load() { FusionCharts.setCurrentRenderer('javascript'); var chart = new FusionCharts("swf", 'chart0', "width", "height", "0", "1"); chart.setXMLData("XML DATA HERE"); chart.render("divNAMEHere"); }
Now you need to call the load() function onload, create a div to render the chart in, and end the html file. For example:
`
test
`
Create a new class that imports the eclipse swt browser libraries. Instantiate Display, Shell, and Browser (use this as a guideline to help understand what is happening: http://www.roseindia.net/tutorials/swt/swt-browser.shtml).
Set the text of the browser (browser.setText("htmlcode")) to the html code from template.html. The best way to do this would be to read the file using BufferedReader.
Lastly, the image takes some time to render. Now there is probably a better way to do this but if you want to just get it working, I set up a count and it captures the image after a certain number. This is what you need to add to the end:
int i = 0;
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
i++;
// System.out.println(i);
if(i==100)
{
GC source = new GC (shell);
Image image = new Image(display, browser.getClientArea());
source.copyArea(image, 0, 0);
ImageLoader io = new ImageLoader ();
io.data = new ImageData[] { image.getImageData() };
File f = new File (currentDir+"/workpng.png");
io.save (f.getAbsolutePath(), SWT.IMAGE_PNG);
}
}
}

Categories