I'm currently developing a portlet, where I want to utilize vaadin with a self defined javascript component. In order to get an idea, how it works, I tried to code the following simple example http://www.rapidpm.org/2013/10/13/using-javascript-libraries-%28d3%29-in-vaa.html.
However, when I integrate my portlet onto liferay I get the following error:
Tue Dec 09 19:02:34 GMT+100 2014 com.vaadin.client.VConsole SEVERE: Could not determine ApplicationConnection for Overlay. Overlay will be attached directly to the root panel
http://localhost:8080/web/guest/testLine 0.
(source firebug)
Failed to load the widgetset:/asdg-0.0.1-SNAPSHOT/VAADIN/widgetsets/testd3.d3.AppWidgetSet/testd3.d3.AppWidgetSet.nocache.js?1418149425812
(chrome dev tool)
My code:
Diagram connector JS
window.testd323_asdg_Diagram = function() {
var diagramElement = this.getElement();
var diagramFrame = d3.select(diagramElement).append("svg:svg").attr("width", 500).attr("height", 500);
diagramFrame.append("svg:circle").attr("cx", 250).attr("cy", 250).attr("r", 20).attr("fill", "red");
this.onStateChange = function() {
var coords = this.getState().coords;
d3.selectAll("circle").transition().attr("cx", parseInt(coords[0]));
d3.selectAll("circle").transition().delay(500).attr("cy", parseInt(coords[1]));
}
}
Diagram.java
package testd323.asdg;
import java.util.List;
import com.vaadin.annotations.JavaScript;
import com.vaadin.ui.AbstractJavaScriptComponent;
#JavaScript({"d3.v3.min.js",
"diagram_connector.js"})
public class Diagram extends AbstractJavaScriptComponent {
public void setCoords(final List<Integer> coords) {
getState().setCoords(coords);
}
#Override
public DiagramState getState() {
return (DiagramState) super.getState();
}
}
DiagramState.java
package testd323.asdg;
import java.util.List;
import com.vaadin.shared.ui.JavaScriptComponentState;
public class DiagramState extends JavaScriptComponentState {
private List<Integer> coords;
public List<Integer> getCoords() {
return coords;
}
public void setCoords(final List<Integer> coords) {
this.coords = coords;
}
}
MyPortletUI.java
package testd323.asdg;
import java.util.ArrayList;
import java.util.List;
import javax.portlet.PortletContext;
import javax.portlet.PortletSession;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.Widgetset;
import com.vaadin.data.validator.IntegerRangeValidator;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.WrappedPortletSession;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
#Theme("mytheme")
#SuppressWarnings("serial")
#Widgetset("testd3.d3.AppWidgetSet")
public class MyPortletUI extends UI {
final VerticalLayout layout = new VerticalLayout();
final TextField xCoordField = new TextField("X");
final TextField yCoordField = new TextField("Y");
final Button button = new Button("move circle");
final Diagram diagram = new Diagram();
final List<Integer> coords = new ArrayList<Integer>();
#Override
protected void init(VaadinRequest request) {
configureIntegerField(xCoordField); //not interesting, just adding converter/validator to the textFields
configureIntegerField(yCoordField);
button.addClickListener(new Button.ClickListener() { //ATTENTION! Here we get the coordinates from the textfields and apply them to our Diagram via calling diagram.setCoords()
#Override
public void buttonClick(Button.ClickEvent event) {
if(xCoordField.isValid() && yCoordField.isValid()){
coords.clear();
coords.add(Integer.parseInt(xCoordField.getValue()));
coords.add(Integer.parseInt(yCoordField.getValue()));
diagram.setCoords(coords);
}
}
});
//now we build the layout.
layout.setSpacing(true);
layout.addComponent(xCoordField);
layout.addComponent(yCoordField);
layout.addComponent(button);
layout.addComponent(diagram); //add the diagram like any other vaadin component, cool!
setContent(layout);
}
private void configureIntegerField(final TextField integerField) {
integerField.setConverter(Integer.class);
integerField.addValidator(new IntegerRangeValidator("only integer, 0-500", 0,500));
integerField.setRequired(true);
integerField.setImmediate(true);
}
}
My setup is:
Maven 7.2.6 Vaadin-liferay-portlet Archertype
Liferay 6.2.1
d3.v3.min.js
Eclipse
I would be thrilled if someone could explain to me what I'm doing wrong. I don't have so much experience with the self contained approach and have some difficulties with it.
Thank you very much.
I have solved my issue a couple of weeks ago and I post my solution if someone has a similar problem.
In the main UI class you have to add an Anootation referring to your used Javascript libraries. For example in my case, I had to add my MyPorletUI.java:
#Theme("mytheme")
#SuppressWarnings("serial")
#Widgetset("CircleD3.circle.AppWidgetSet")
#com.vaadin.annotations.JavaScript( {"d3.v3.min.js",
"CircleD3_circle_Diagram.js"} )
public class MyPortletUI extends UI { (...)
Everything else works as described in the tutorial link, I was referring in my original question post.
Related
I'm following a guide on coding by Easy Tuto, currently on part 7 at the end where the recycler_note_item.xml would show up on the interface. In the video, he fixed the problem by adding the onStart, onStop, onResume commands and adding `noteAdapter.startListening' in between the lines as shown here: image In the video, it worked and showed the item however nothing showed up for me as can be seen here . I tried scouring the video trying to find what I did wrong. I'm pretty new to coding and I was using his video as a base to learn more about it. I added those lines myself but it diddn't work for me it seems. Can someone please help me? It would be greatly appreciated. Here is my code for MainActivity.Java:
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ImageButton;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.firestore.Query;
public class MainActivity extends AppCompatActivity {
FloatingActionButton addNoteBtn;
RecyclerView recyclerView;
ImageButton menuBtn;
NoteAdapter noteAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addNoteBtn = findViewById(R.id.add_note_btn);
recyclerView = findViewById(R.id.recyler_view);
menuBtn = findViewById(R.id.menu_btn);
addNoteBtn.setOnClickListener((v)-> startActivity(new Intent(MainActivity.this,NoteDetailsActivity.class)) );
menuBtn.setOnClickListener((v)->showMenu());
setupRecyclerView();
}
void showMenu(){
//TODO Display menu
}
void setupRecyclerView(){
Query query = Utility.getCollectionReferenceForNotes().orderBy("timestamp",Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Note> options = new FirestoreRecyclerOptions.Builder<Note>()
.setQuery(query,Note.class).build();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
noteAdapter = new NoteAdapter(options,this);
recyclerView.setAdapter(noteAdapter);
}
#Override
protected void onStart() {
super.onStart();
noteAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
noteAdapter.stopListening();
}
#Override
protected void onResume() {
super.onResume();
noteAdapter.notifyDataSetChanged();
}
}
I think the other relevant codes is my NoteAdapter which is this:
package com.example.myapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import io.grpc.okhttp.internal.Util;
public class NoteAdapter extends FirestoreRecyclerAdapter<Note, NoteAdapter.NoteViewHolder>{
Context context;
public NoteAdapter(#NonNull FirestoreRecyclerOptions<Note> options, Context context) {
super(options);
this.context = context;
}
#Override
protected void onBindViewHolder(#NonNull NoteViewHolder holder, int position, #NonNull Note note) {
holder.titleTextView.setText(note.title);
holder.contentTextView.setText(note.content);
holder.timestampTextView.setText(Utility.timestamptoString(note.timeStamp));
}
#NonNull
#Override
public NoteViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_note_item,parent,true);
return new NoteViewHolder(view);
}
class NoteViewHolder extends RecyclerView.ViewHolder{
TextView titleTextView,contentTextView,timestampTextView;
public NoteViewHolder(#NonNull View itemView) {
super(itemView);
titleTextView = itemView.findViewById(R.id.note_title_text_view);
contentTextView = itemView.findViewById(R.id.note_content_text_view);
timestampTextView = itemView.findViewById(R.id.note_timestamp_text_view);
}
}
}
Please tell me if there are any other relevant codes I can give to help give more context on my problem. Thanks for helping me out if anyone!
I got this (https://stackoverflow.com/a/42040344/3789572) solution, which code is below, but it isn't working. When I press the button, nothing is shown.
You can change the file paths and try it for yourself.
Can you help me?
Controller code:
package sample.principal;
import javafx.concurrent.Worker;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
import java.io.File;
import java.net.URL;
import java.util.Base64;
import java.util.ResourceBundle;
import org.apache.commons.io.FileUtils;
public class WebController implements Initializable {
#FXML
private WebView web;
#FXML
private Button btn;
public void initialize(URL location, ResourceBundle resources) {
WebEngine engine = web.getEngine();
String url = getClass().getResource("..\\resources\\web\\viewer.html").toExternalForm();
// connect CSS styles to customize pdf.js appearance
engine.setUserStyleSheetLocation(getClass().getResource("..\\resources\\web\\viewer.css").toExternalForm());
engine.setJavaScriptEnabled(true);
engine.load(url);
engine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
// to debug JS code by showing console.log() calls in IDE console
JSObject window = (JSObject) engine.executeScript("window");
window.setMember("java", new JSLogListener());
engine.executeScript("console.log = function(message){ java.log(message); };");
// this pdf file will be opened on application startup
if (newValue == Worker.State.SUCCEEDED) {
try {
// readFileToByteArray() comes from commons-io library
byte[] data = FileUtils.readFileToByteArray(new File("C:\\Users\\Felipe\\Documents\\" +
"Programação\\Java\\" +
"IdeaProjects\\PDFviewerStackOverFlow\\src\\sample\\principal\\teste.pdf"));
String base64 = Base64.getEncoder().encodeToString(data);
// call JS function from Java code
engine.executeScript("openFileFromBase64('" + base64 + "')");
} catch (Exception e) {
e.printStackTrace();
}
}
});
// this file will be opened on button click
btn.setOnAction(actionEvent -> {
try {
byte[] data = FileUtils.readFileToByteArray(new File("teste.pdf"));
String base64 = Base64.getEncoder().encodeToString(data);
engine.executeScript("openFileFromBase64('" + base64 + "')");
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
The Main code:
package sample.principal;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) {
Application.launch();
}
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("PDF test app");
primaryStage.setScene(new Scene(root, 1280, 576));
primaryStage.show();
}
}
and the other one:
package sample.principal;
public class JSLogListener {
public void log(String text) {
System.out.println(text);
}
}
I would be very grateful for your help.
Thanks.
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage stage) {
stage.setTitle("HTML");
stage.setWidth(500);
stage.setHeight(500);
Scene scene = new Scene(new Group());
VBox root = new VBox();
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(browser);
webEngine.loadContent("<b>asdf</b>");
root.getChildren().addAll(scrollPane);
scene.setRoot(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I am running React Native 0.56. When I start my app, it first shows a white screen for 1 second then goes to the app. My files are:
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
#Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
#Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new BlurViewPackage(),
new OrientationPackage(),
new ReactVideoPackage(),
new RNDeviceInfo(),
new LinearGradientPackage()
);
}
#Override
protected String getJSMainModuleName() {
return "index";
}
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
#Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
and
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
#Override
protected String getMainComponentName() {
return "CONtv";
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = new Intent("onConfigurationChanged");
intent.putExtra("newConfig", newConfig);
this.sendBroadcast(intent);
}
}
and index.js
import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
How do I make the white screen not appear? This is happening on Android.
As a solution for the white screen add a splash screen.
Check with this https://android.jlelse.eu/the-complete-android-splash-screen-guide-c7db82bce565
I know, this question may sound duplicate and I have tried everything found on stackover flow unable to resolve this problem, so please bear with me
To make you able to reproduce the error I am providing you the whole code thought this
Github Repo
Problem
I am getting the following error:
Provider parse errors:↵Cannot instantiate cyclic dependency!
InjectionToken_HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule
in ./AppModule#-1:-1
Information about the scenario (Notes)
Note 1
File: response-interceptor.service.ts
Path: ./src/app/shared/interceptors/response-interceptor/
I am intercepting the HTTPClient responses to check the 401 error and when the error comes I need to ask user to re-login.
To show the re-login prompt to user I have made a global-functions-services that has a function 'relogin'
Note 2
File: global-function.service.ts
Path: ./src/app/shared/services/helper-services/global-function/
Here is the place where this all started to happen...
As soon as I am injecting the PersonService
constructor(
public dialog: MatDialog,
private _personService: PersonService
) { }
I am getting this error and in PersonService I cannot find any import that can cause the issue.
PersonService:
./src/app/shared/services/api-services/person/person.service.ts
import { IRequest } from './../../../interfaces/I-request';
import { environment } from 'environments/environment';
import { Injectable } from '#angular/core';
// for service
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/toPromise';
// models
import { Person } from 'app/shared/models/person';
import { RequestFactoryService, REQUEST_TYPES } from 'app/shared/factories/request-factory/request-factory.service';
#Injectable()
export class PersonService {
private _requestService: IRequest;
constructor(
_requestFactoryService: RequestFactoryService
) {
this._requestService = _requestFactoryService.getStorage(REQUEST_TYPES.HTTP);
}
public signup(record): Promise<Person> {
let url = environment.api + 'person/public/signup';
return this._requestService.post(url, record) as Promise<Person>;;
}
public authenticate(code: string, password: string): Promise<Person> {
let url = environment.api + 'auth/signin';
let postData = {
code: code,
password: password
}
return this._requestService.post(url, postData) as Promise<Person>;
}
}
Request
Please suggest a solution for this, I have already wasted 2 days to figure out the issue but no luck.
Many thanks!! in advance
Cyclic dependency, means circling around endless, like planets orbiting sun..
Solution: Break the dependency chain, Re-factor code.
You have GlobalFunctionService -> PersonService -> so on... -> ResponseInterceptorService -> and back to -> GlobalFunctionService.
Cycle complete.
REMOVE the PersonService dependency from GlobalFunctionService. (its not used anyway, if you need it then find different way to get around.)
import { PersonService } from 'app/shared/services/api-services/person/person.service';
import { Injectable } from '#angular/core';
import { InputModalComponent } from 'app/shared/components/input-modal/input-modal.component';
import { MatDialog } from '#angular/material';
#Injectable()
export class GlobalFunctionService {
constructor(
public dialog: MatDialog
) { }
relogin(): void {
let dialogRef = this.dialog.open(InputModalComponent, {
width: '250px',
data: { title: "Please provide your password to re-login." }
});
dialogRef.afterClosed().subscribe(result => {
debugger
console.log('The dialog was closed');
let password = result;
});
}
}
Use setTimeout() function in constructor to assign service.
constructor(private injector: Injector) {
setTimeout(() => {
this.loginService = this.injector.get(LoginService);
})
}
Try this and revert back if you face any issue.
You have to modify your response-interceptor.service.ts
import { Injectable,Inject, Injector } from '#angular/core';
constructor( inj: Injector) {
this._globalFunctionService=inj.get(GlobalFunctionService)
}
You can get more info From this link
I Have D3 Intergrated in my Project.
Anytimes comes the Exception "could not initialize javascript connector because no javascript init function was found"
Here my Code
MainUI
package testd323.asdg;
import java.util.ArrayList;
import java.util.List;
import com.company.grafiktest5.ui.MainView;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.Widgetset;
import com.vaadin.data.validator.IntegerRangeValidator;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Button;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.xdev.ui.XdevUI;
import com.xdev.ui.navigation.XdevNavigator;
#Theme("mytheme")
#SuppressWarnings("serial")
#Widgetset("CircleD3.circle.AppWidgetSet")
#com.vaadin.annotations.JavaScript( {"d3.v3.min.js",
"CircleD3_circle_Diagram.js"} )
public class MainUI extends XdevUI {
final VerticalLayout layout = new VerticalLayout();
final TextField xCoordField = new TextField("X");
final TextField yCoordField = new TextField("Y");
final Button button = new Button("move circle");
final Diagram diagram = new Diagram();
final List<Integer> coords = new ArrayList<>();
#Override
protected void init(final VaadinRequest request) {
configureIntegerField(this.xCoordField); //not interesting, just adding converter/validator to the textFields
configureIntegerField(this.yCoordField);
this.button.addClickListener(new Button.ClickListener() { //ATTENTION! Here we get the coordinates from the textfields and apply them to our Diagram via calling diagram.setCoords()
#Override
public void buttonClick(final Button.ClickEvent event) {
if(MainUI.this.xCoordField.isValid() && MainUI.this.yCoordField.isValid()){
MainUI.this.coords.clear();
MainUI.this.coords.add(Integer.parseInt(MainUI.this.xCoordField.getValue()));
MainUI.this.coords.add(Integer.parseInt(MainUI.this.yCoordField.getValue()));
MainUI.this.diagram.setCoords(MainUI.this.coords);
}
}
});
//now we build the layout.
this.layout.setSpacing(true);
this.layout.addComponent(this.xCoordField);
this.layout.addComponent(this.yCoordField);
this.layout.addComponent(this.button);
this.layout.addComponent(this.diagram); //add the diagram like any other vaadin component, cool!
setContent(this.layout);
}
private void configureIntegerField(final TextField integerField) {
integerField.setConverter(Integer.class);
integerField.addValidator(new IntegerRangeValidator("only integer, 0-500", 0, 500));
integerField.setRequired(true);
integerField.setImmediate(true);
}
Diagramm.Java
package testd323.asdg;
import java.util.List;
import com.vaadin.annotations.JavaScript;
import com.vaadin.ui.AbstractJavaScriptComponent;
#JavaScript({"d3.v3.min.js",
"testd323.asdg.diagram_connector.js"})
public class Diagram extends AbstractJavaScriptComponent {
public void setCoords(final List<Integer> coords) {
getState().setCoords(coords);
}
#Override
public DiagramState getState() {
return (DiagramState) super.getState();
}
}
DiagramState.java
package testd323.asdg;
import java.util.List;
import com.vaadin.shared.ui.JavaScriptComponentState;
public class DiagramState extends JavaScriptComponentState {
private List<Integer> coords;
public List<Integer> getCoords() {
return this.coords;
}
public void setCoords(final List<Integer> coords) {
this.coords = coords;
}
}
diagram_connector.js
window.testd323_asdg_Diagram = function() {
var diagramElement = this.getElement();
var diagramFrame = d3.select(diagramElement).append("svg:svg").attr("width", 500).attr("height", 500);
diagramFrame.append("svg:circle").attr("cx", 250).attr("cy", 250).attr("r", 20).attr("fill", "red");
this.onStateChange = function() {
var coords = this.getState().coords;
d3.selectAll("circle").transition().attr("cx", parseInt(coords[0]));
d3.selectAll("circle").transition().delay(500).attr("cy", parseInt(coords[1]));
}
Hope that anyone can help me.
Thanks!
The JavaScript files need to be in resources/testd323/asdg in order to be found.