I am using JavaFx, and have Tabs with WebView objects on them. I am trying to have my tab title's text to read the web page's title like in most web browsers. When I use the "getTitle" method I get an empty title, Which I assume is because the page hasn't loaded yet. All the research I've done gives me an Android Solution and I'm looking for something that works with a desktop application. Here's what I have.
public class WebsiteTab extends Tab {
final static String DEFAULT_SITE = "https://google.com";
VBox browserBox;
WebView webView;
public WebsiteTab() {
super("Site One");
webView = new WebView();
webView.setPrefHeight(5000);
goToSite(DEFAULT_SITE);
browserBox = new VBox(10,webView);
VBox.setVgrow(browserBox, Priority.ALWAYS);
setContent(browserBox);
}
public void goToSite(final String site) {
webView.getEngine().load(site);
setText(webView.getEngine().getTitle());
}
}
Any help would be appreciated.
You can bind the tab's text property to the web engine's title property.
public class WebsiteTab extends Tab {
final static String DEFAULT_SITE = "https://google.com";
VBox browserBox;
WebView webView;
public WebsiteTab() {
super("Site One");
webView = new WebView();
webView.setPrefHeight(5000);
textProperty().bind(webView.getEngine().titleProperty()); // bind the properties
goToSite(DEFAULT_SITE);
browserBox = new VBox(10,webView);
VBox.setVgrow(browserBox, Priority.ALWAYS);
setContent(browserBox);
}
public void goToSite(final String site) {
webView.getEngine().load(site);
}
}
This will cause the text property to always have the same value as the title property. In other words, when the title property's value changes the text property will be automatically updated. Notice I bind the properties in the constructor as you only need to create the binding once. Also note that while bound you can no longer manually set the text property; attempting to do so will cause an exception to be thrown. For more information, see Using JavaFX Properties and Binding.
Related
enter image description hereI made a GUI on JavaFX that's for creating timetables. when I open the app I can add plans (Buttons) to day columns (VBox). ofc the changes aren't saved after I close the app: the next time I open it the table is empty.
my question is how can I make it save nodes that the user creates so the next time i open the app they're there?
this is the exact part where the nodes get added for what it's worth:
void ask_add_plan(ActionEvent event)
{
Button b = (Button) event.getSource();
VBox v = (VBox) b.getParent();
AnchorPane pop_up = new AnchorPane(); //this pop up is to specify things about the plan
//but i removed unnecessary code for simplicity
VBox pop_up_v = new VBox();
Button add = new Button("Add");
add.setOnAction(e->{
Button plan = new Button(what_to_do.getText());
v.getChildren().add(plan);
container.getChildren().remove(pop_up); //container is the anchor pane everything's in
});
pop_up_v.getChildren().add(add);
pop_up.getChildren().add(pop_up_v);
container.getChildren().add(pop_up); //container is the anchor pane everything's in
}
The JavaFX nodes are just the presentation of your data. They are not meant to be saved. Store the actual data itself in a private field in your class.
In your Application.stop method, write the data to a file.
In your Application.start method, read that file and use it to rebuild JavaFX nodes.
private static final Path PLANS_FILE =
Path.of(System.getProperty("user.home"), "plans.txt");
private final List<String> plans = new ArrayList<>();
void ask_add_plan(ActionEvent event) {
// ...
add.setOnAction(e -> {
String planText = what_to_do.getText();
plans.add(planText);
Button plan = new Button(planText);
v.getChildren().add(plan);
container.getChildren().remove(pop_up);
});
}
#Override
public void start(Stage primaryStage)
throws Exception {
// ...
if (Files.exists(PLANS_FILE)) {
plans.addAll(Files.readAllLines(PLANS_FILE));
// Add UI elements for each stored plan.
for (String planText : plans) {
Button planButton = new Button(planText);
v.getChildren().add(planButton);
container.getChildren().remove(pop_up);
}
}
}
#Override
public void stop()
throws IOException {
Files.write(PLANS_FILE, plans);
}
The above is just a simplified example. The file doesn’t have to store just strings.
I get the impression that the data created in the application is more complex than just plan strings. For complex data, XML may be more a suitable file format. Or you can use Java serialization. Or, you can invent your own file format.
You also don’t have to read from and write to a file. You can use a database, if you’re comfortable with database programming. Or you can use Preferences (though Preferences are not well suited to storing lists of complex data).
You should use MVP (model-view-presenter) pattern. Saving data in UI layer is not a good practice. Create a model with data and then serialize it.
I'm creating a custom content assist for an editor, this is how I'm creating the proposals:
#Override
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
String test = "Test";
ContextInformation contextInfo = new ContextInformation("Context display test", "information display test");
CompletionProposal proposal = new CompletionProposal(test,
offset,
0,
test.length(),
Activator.getImage("icons/sample.png"),
test,
contextInfo,
"Additional info");
return new ICompletionProposal[] {proposal};
}
This is the result:
Which is fine, but for example, in the content assist of the Java editor, they are using colors such as blue and gray:
I know there is a class called StyledText that could help but I can't find a good example to use it in combination with CompletionProposal.
The extension interface ICompletionProposalExtension6 supports styled display strings. Its sole method getStyledDisplayString() must return a StyledString that is used for display.
Instead of creating an instance of CompletionProposal you would have to implement your own ICompletionProposal that also implements the above mentioned extension. For example:
class StyledCompletionProposal
implements ICompletionProposal, ICompletionProposalExtension6
{
...
#Override
public StyledString getStyledDisplayString() {
return new StyledString("test").append(" [10%]", Styler.QUALIFIER_STYLER);
}
}
In addition, the content assistant must be configured to enable coloured labels. For editors, this is usually done in SourceViewerConfiguration::getContentAssistant:
ContentAssistant contentAssistant = new ContentAssistant();
contentAssistant.enableColoredLabels(true);
i would like to know if its possible to have a clickable link for a dynamic text.
I have tried by using the anchor tag with some wicket id and adding an onclick behavior to it, i could see the text with link on my screen but the onclick call of t he link was never triggered.
What could possibly be the issue?
i did something like this:
String someTextMessage = "Hey!!! <a wicket:id='printLink'>Click Here</a> now.";
Lable message = new Lable("messageLable", someTextMessage);
message.setEscapeModelStrings(true);
Link printLink = new Link("printLink") {
#Override
public void onClick() {
System.out.println("inside onClick");
}
};
this.add(printLink);
this.add(message);
i used this wicket id and added it to the page and attached an onclick behavior to this.
I have checked t he firebug console but there was no onclick call made for the link's click.
Thanks.
You want to use the Link.setAnchor(Component) method.
Don't forget to setOutputMarkupId to true for the component you want to jump to.
Label message = new Label("messageLable", "Anchor!");
message.setOutputMarkupId(true);
this.add(message);
Link printLink = new Link("printLink") {
#Override
public void onClick() {
System.out.println("inside onClick");
}
};
printLink.setAnchor(message);
this.add(printLink);
Don't try to add wicket components by appending html with "wicket:id" in some kind of component. It won't work.
I'm trying to update my data widget from a CellTable to DataGrid and I basically thought I online a change from #UiField CellTable<T> to #UiField DataGrid<T> but thats not it.
private void init() {
sortHandler = new ListHandler<GWTUser>(getUsers());
dataGrid.setWidth("100%");
dataGrid.setHeight("100%");
dataGrid.setAutoHeaderRefreshDisabled(true);
dataGrid.setEmptyTableWidget(emptyDb);
dataGrid.addColumnSortHandler(sortHandler);
dataGrid.setVisibleRangeAndClearData(dataGrid.getVisibleRange(), true);
dataGrid.setRowCount(1, true);
dataGrid.clearTableWidth();
dataGrid.redraw();
// Setup Cell Table.
initCellTable();
// Connect the table to the data provider.
dataProvider.addDataDisplay(dataGrid);
}
private void initCellTable() {
// userId Column
TextColumn<GWTUser> userIdColumn = new TextColumn<GWTUser>() {
#Override
public String getValue(GWTUser object) {
return object.getUserId();
}
};
dataGrid.addColumn(userIdColumn, Lang.LABEL_USER_USERID);
dataGrid.addColumnSortHandler(sortHandler);
dataGrid.getColumnSortList().push(userIdColumn);
dataGrid.getColumnSortList().push(userIdColumn);
}
#Override
public void setUserList(List<GWTUser> users) {
setUsers(users);
dataGrid.setRowCount(getUsers().size(), true);
dataGrid.setRowData(0, getUsers());
dataGrid.setPageSize(getUsers().size());
dataGrid.setVisibleRange(new Range(0,dataGrid.getRowCount()));
dataGrid.redraw();
sortHandler.setList(getUsers());
}
uiBinder:
<g:VerticalPanel>
<g:ScrollPanel ui:field="listScrollPanel">
<c:DataGrid styleName= ui:field='dataGrid' width="100%" height="98%"/>
</g:ScrollPanel>
<g:HorizontalPanel>
<g:Button ui:field="createButton">New</g:Button>
<g:Button ui:field="refreshButton">Refresh</g:Button>
<g:Button ui:field="removeSelectedButton">Delete Selection</g:Button>
</g:HorizontalPanel>
</g:VerticalPanel>
When I change the region where my DataGrid should be with the chrome dev tool, the data with the tables is there but not shown.
as basic information: init is called by the constructor and setUserList is called in my activitiy when I get the data from a rest service. thanks for any help.
The DataGrid requires an explicitly set height. This means that you can't use percentages (e.g. 100%), but rather have to use something like 500px.
Here is a related question:
GWT DataGrid automatic height
Trying to integrate a java applet in my website created using vaadin 7. I am trying to do it using embedded and adding it to the layout. This is what I have right now.
public class DeviceConfigure extends CustomComponent implements View {
#AutoGenerated
private AbsoluteLayout mainLayout;
#AutoGenerated
public DeviceConfigure() {
buildMainLayout();
setCompositionRoot(mainLayout);
Resource res = new ThemeResource("img/stars.jar");
Embedded jarFile = new Embedded("Jar File", res);
mainLayout.addComponent(jarFile);
}
private AbsoluteLayout buildMainLayout() {
// common part: create layout
mainLayout = new AbsoluteLayout();
mainLayout.setImmediate(false);
mainLayout.setWidth("860px");
mainLayout.setHeight("510px");
// top-level component properties
setWidth("860px");
setHeight("510px");
return mainLayout;
}
#Override
public void enter(ViewChangeEvent event) {
// TODO Auto-generated method stub
}
}
I've tried different things like setting the minetype, archive etc.. but can't get it to work. Whenever I navigate to the page the section where the applet should be is just blank. Is there something that I am missing that I'm just not seeing. Thanks to anyone who takes the time to read and reply to this.