How disable JavaFX Text
Text t = new Text();
t.setText("This is a text sample");
t.setDisable(true); //it does not work
Solution
You can style Text visually, so that it looks disabled, if you wish. The solution below binds the opacity setting to the disabled setting of the text.
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class DisabledText extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Text enabledText = new Text("Enabled");
Text disabledText = new Text("Disabled");
disabledText.opacityProperty().bind(
Bindings.when(
disabledText.disabledProperty())
.then(0.4)
.otherwise(1)
);
disabledText.setDisable(true);
VBox layout = new VBox(10, enabledText, disabledText);
layout.setPadding(new Insets(10));
stage.setScene(new Scene(layout));
stage.show();
}
}
Notes
You might be able to accomplish this through CSS as well rather than a binding, I just didn't try that option.
In general, many times you are usually better off using a Label then Text for a lot of things as it includes more flexibility and functionality.
Background
Even though the user can't interact directly with text, so disabling text really has no effect, I guess what you are looking for is that the text look like other things when they are disabled.
Normally what happens when a control such as menu item or button is disabled, is that the CSS pseudo-class :disabled is set on the control. When this occurs, the default modena.css stylesheet for JavaFX 8 will modify the opacity for the control to -fx-opacity: 0.4;. This changes the visual look for the control so that it appears as though it is grayed out, as the low opacity makes the control looks faded.
Text is built to be a base drawing shape. Base drawing shapes in Java deliberately don't rely on CSS (though CSS can be used with them if needed - see the CSS reference guide for info on what default CSS rules apply to shapes). If your scene doesn't use any layout panes or controls, then the standard modena.css stylesheet will not be loaded and CSS processing will not be applied to the scene (for efficiency reasons so that, for instance, you could write a high performance game that did not use CSS processing). So CSS processing for Text is not necessarily required and, if used, is limited in its scope.
Two possible ways:
Add css style to the Text's instance.
Use Label instead.
I recommend using Label instead of Text.
Related
I'm building an Android and iOS app using Xamarin Forms.
What I'm simply trying to do is set a background drawable on my Android app for my ListView items. The root view of my ListView items are StackLayout's:
var listView = new ListView
{
ItemsSource = items,
ItemTemplate = new DataTemplate(() =>
{
return new ViewCell
{
View = new StackLayout(...)
};
}
};
I know I can access the native element by using a custom renderer:
public class MyEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.OldElement == null) {
var nativeEditText = (EditText)Control;
...
}
}
}
But I'm not sure how this would work for a StackLayout (or any other layout for that matter).
I first extended StackLayout:
public class ListViewItem : StackLayout
{
}
And I read somewhere that layouts use the VisualElementRenderer, so I tried the following:
public class ListViewItemRenderer : VisualElementRenderer<StackLayout>
{
protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
{
base.OnElementChanged(e);
// any way to access the native element?
}
}
But VisualElementRenderer does not seem to give me access to the native element.
So is there any way I can access the native elements of Layout elements? Or maybe there is a different way to simply set a background drawable on layouts within my Android app?
Even though I still don't know how to access the native element of a layout, the VisualElementRenderer has a method for setting the background drawable on Android (which was exactly what I needed). So I ended up with the following:
protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
{
base.OnElementChanged(e);
SetBackgroundDrawable(Resources.GetDrawable(Resource.Drawable.listViewItem));
}
I understand you want to hook into an existing Layout renderer and extending it to access the native element with extra capabilities like background image.
Eventually the support for background-image will be supported just like background-colour is, I imagine, across the Layout controls. It may be worth while waiting for this as I can't see why they wouldn't implement these in a later release.
In the mean time you would need something that would work and is quite easy to implement?
Creating the background drawable via inheriting the renderer from a Layout may not be the simplest of solutions therefore, although does have its advantages as you can then re-use easily with the extra functionality across all Layouts for an application.
In your code for ListViewItemRenderer, however, it is inheriting from a Xamarin.Forms control (you specified StackLayout) and have not specified a native, platform dependent, control to be the base for the layout control that would have to match the Xamarin.Forms platform dependent control used.
Each Renderer is tied to a native element. Layout controls will be no different than other custom native control renderers.
For a custom control, you will write a renderer something like the following (note I haven't specified a layout renderer as I haven't had a need to do this yet and am just going from past experience - but similar rules should apply to implementing a renderer for a layout as opposed to a custom control):-
// System.Windows.Controls.Grid in this case is the root native control for a WindowsPhone renderer of MyControl
public class MyControlRenderer : ViewRenderer<MyControlView, System.Windows.Controls.Grid>
There is a simpler approach, however to achieve what you want to do:-
The simpler approach would be instead of inheriting from the Stack Layout control, it would be better to inherit from Grid as the root of the control.
Then you can add an Image control to the Grid and also a Stack Layout for the same Grid Row and Column.
By doing the above you will be able to achieve a background-image across the entire listview item row.
I am confused with the possibilities of layouting components in Vaadin 7 - intuition tells to use just layout - however there are also Panels or Components which can be useful.
I need to create view which will have static left menu and top bar (constant size, visible on each page). The only thing that will change the content is middle component - which should be scrollable.
My design therefore is:
Custom component, which assembles everything. Is has absolute size for top and left menu.
Vertical layout for left menu and Horizontal layout for upper menu
Panel for middle component, since Panel is supposed to support scrolling.
Inside of panel I placed CssLayout with content that doesn't fit the page. Expected behaviour is that there would be a scroll bar (preferably on the browser, but i guess it'd be on the panel). But What actually happens is that just the part that fits the screen is visible and the rest is cut. CssLayout is sizeFull and panel default, but I tried also other combinations and nothing has helped.
How can I combine layouts to have middle panel scrollable (if needed) and top and left one with absolute size?
Thanks a lot,
In Vaadin 7 & 8, you generally use one of the Layout implementations to arrange widgets within a UI subclass. For example, VerticalLayout, HorizontalLayout, and GridLayout. For pixel-positioning, use AbsoluteLayout. Of course these can be nested one within another. But don't go crazy with the nesting as it may result in overly complex HTML/CSS at runtime.
The Panel class, as the doc says, is a special container. It contains only a single component, typically another container such as a Layout. The Panel presents itself with a border and a title bar displaying its caption property. This looks something like a sub-window.
As you mentioned, a Panel supports scrolling. But keep in mind that any web page defined with a Layout also supports scrolling, obviously.
Here is a complete example app showing a stack of TextField widgets in a VerticalLayout.
package com.basilbourque.example;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import javax.servlet.annotation.WebServlet;
import java.time.Instant;
/**
* This UI is the application entry point. A UI may either represent a browser window
* (or tab) or some part of an HTML page where a Vaadin application is embedded.
* <p>
* The UI is initialized using {#link #init(VaadinRequest)}. This method is intended to be
* overridden to add component to the user interface and initialize non-component functionality.
*/
#Theme ( "mytheme" )
public class MyUI extends UI {
#Override
protected void init ( VaadinRequest vaadinRequest ) {
final VerticalLayout layout = new VerticalLayout();
for ( int i = 1 ; i <= 100 ; i++ ) {
TextField textField = new TextField( String.format( "%3d" , i ) );
textField.setWidth( 17 , Unit.EM ); // Widen the field to fully display our contents.
textField.setValue( Instant.now().toString() );
layout.addComponents( textField );
}
setContent( layout );
}
#WebServlet ( urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true )
#VaadinServletConfiguration ( ui = MyUI.class, productionMode = false )
public static class MyUIServlet extends VaadinServlet {
}
}
As to your idea of nesting VerticalLayout and HorizontalLayout for nav panels, button/tool bars, and such…
Vaadin 7 & 8: Absolutely proper, and a good idea. Sometimes a GridLayout makes sense for that as well.
Vaadin 10: May also be a good idea. Or you may want to explore using new CSS3 features flexbox and Grid Layout.
As for your problem with CssLayout inside a Panel, I have rarely used either. I suspect the problem would lie in not properly defining a specific width & height of the CssLayout. You did not post details and code, so we can only speculate.
How can I specify a line height in a multi-line Text / Label?
It already seems it's not supported in css:
JavaFX CSS does not support comma-separated series of font family
names in the -fx-font-family property. The optional line height
parameter when specifying fonts is not supported. There is no
equivalent for the font-variant property.
Is there a reason for this?
Is there an alternative to set this in code? Or kinda emulate the functionality? I want to control vertical rhythm within my app.
Java 8+ implementation
RT-21683 Allow to change line-to-line spacing was implemented to add a line spacing feature to JavaFX Java 8.
The line spacibg API is defined on Text, TextFlow and Labeled nodes via a lineSpacing property and associated getters and setters. Spacing is defined in pixels, like the rest of JavaFX layout.
Java 2.2- implementation
If you cannot use Java 8+, you will need to implement line spacing yourself, e.g. By setting spacing on a VBox with separate Text nodes for each line.
Discussion of unit measurements in JavaFX
It seems that there is a corresponding (stylable) css property? If it's defined in pixels, how do I make it dpi aware
css properties work can work with em units if you use them. See for example the default modena.css stylesheet which measures almost all sizes in em units. This is why if you are just using default styles without additional pixel based layout, then if you change the root font size, everything in your layout scales automatically.
It's only the Java APIs and FXML which work with only pixel units. Even then, the JavaFX system is clever enough to know (at least on some machines), that it is running on a HiDPI display (e.g. OS X retina) so that, for example, pixel units are automatically doubled for the retina display (in Java 8).
If you are using FXML, you could use expression bindings as a way to define your own unit system.
Future versions of JavaFX may provide more support for RT-14020 Concept for a screen resolution independent definition of a GUI.
Sample Code
The sample below uses the Java 8 to demonstrate usage of the lineSpacing api and -fx-line-spacing css attribute.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
public class LineSpacing extends Application {
public static void main(String[] args) { launch(LineSpacing.class); }
#Override public void start(Stage stage) {
Label label = new Label(
"Power is my mistress.\n" +
"I have worked too hard at her conquest " +
"to allow anyone to take her away from me.\n" +
" - Napoleon Bonaparte");
label.setPadding(new Insets(20));
// as the default font spacing in JavaFX is 13 points,
// all of the following lines will provide the same results
// (double spacing the label text).
//
// label.setLineSpacing(13);
// label.setStyle("-fx-line-spacing: 13px;");
label.setStyle("-fx-line-spacing: 1em;");
stage.setScene(new Scene(label));
stage.show();
}
}
I want to create a JavaFX table that, in the cells of one column, allows the user to edit XHTML text. I only need very basic formatting capabilities like bold, italic, striketrough.
I have already managed to implement this by using my own subclass of TableCell and using a WebView for each cell (HTMLEditor would of course have been another choice, but my guess is that for my requirements, WebView should be sufficient).
However, to make editing comfortable for the user, I need the following features:
1. The cell height needs to resize if the user enters multi-line text.
2. A context menu (or, if not possible, some other menu or button) should allow formatting parts of the text in a cell as described above (bold, italic..)
Has anybody been successful in implementing something similar ? I have seen suggestions on the web, but they rarely included code samples.
I have succedded doing something similar.
I figured I can share some of the basic clues that allowed me to achieve it.
Resize the whole WebView. For that, the whole WebView must be an editable html page. You achive that by setting contenteditable to true:
<body contenteditable='true' id='content'></body>
You can have a context menu over a webview. But it is something tricky, as you must first disable the original context menu associated to it.
WebView editView;
...
EventDispatcher originalDispatcher = editView.getEventDispatcher();
editView.setEventDispatcher(new WebmenuEventDispatcher(originalDispatcher));
And this is the event dispatcher class:
public class WebmenuEventDispatcher implements EventDispatcher {
private EventDispatcher originalDispatcher;
public WebmenuEventDispatcher(EventDispatcher originalDispatcher) {
this.originalDispatcher = originalDispatcher;
}
#Override
public Event dispatchEvent(Event event, EventDispatchChain tail) {
if (event instanceof MouseEvent) {
MouseEvent mouseEvent = (MouseEvent) event;
if (MouseButton.SECONDARY == mouseEvent.getButton()) {
mouseEvent.consume();
// Show our own menu
cmEdit.show(editView.getScene().getWindow(), mouseEvent.getScreenX(), mouseEvent.getScreenY());
}
}
return originalDispatcher.dispatchEvent(event, tail);
}
}
Now, for setting the font from within that menu, you need a bidirectional Java<->javascript bridge and use some javascript in the webview side.
I am using javax.microedition.lcdui.Canvas for drawing my string on the screen. But I also need one dialog window for some purpose. So I am using lwuit package (com.sun.lwuit.Dialog) for showing dialog window when key pressing.
So in my program I just included that package and create the object of the Dialog box. While running my application, it is terminated unexpectedly.
I just included the following lines...
import javax.microedition.lcdui.Canvas;
import com.sun.lwuit.Dialog;
public class Mycanvas extends Canvas implements CommandListener
{
Dialog dialog = new Dialog();
//some other remaining codes for my canvas...
}
So, is it possible to show lwuit dialog window with lcdui canvas?
I would say it's possible but it will increase size of the app significantly. Whenever you need your dialog you can init LWUIT Display and use LWUIT Forms and Dialogs.
I would better to implement some really simple Dialog ourselves. It's not really much work. Or use another third party solution.
My Idea is create an user defined Item which extends from CustomItem for dialog.But it is difficult to code the complete implementation.Better u search for any third pary jar file which already implemented dialog box.