Some versions of Vaadin offered FontAwesome built-in. Later Vaadin came with its own collection of icons.
How can I use either of those in Vaadin 8?
With the new emphasis on Vaadin Flow (Vaadin 10+) and re-implementing with Web Components, I have not been able to find any documentation on how to use either of those Vaadin 8 compatible font sources.
How can I conveniently get some large icons displayed as widgets within my Vaadin 8 layout?
There is some 8.x documentation regarding font icons and VaadinIcons, as well as creating your own font icons.
Using them is as simple as new Button("Add", VaadinIcons.PLUS);, but you mentioned something about some large icons which you don't get out of the box AFAIK.
However, based on the above doc, the quick and dirty solution is using a label and some styles:
Theme:
.big-icon .v-icon{
font-size: 300px;
}
Code:
public class Icon extends VerticalLayout {
public Icon() {
Label image = new Label();
image.setContentMode(ContentMode.HTML);
image.setValue(VaadinIcons.EYE.getHtml());
image.addStyleName("big-icon");
addComponent(image);
}
}
Result:
Obviously you can proceed with the madness, and create a slightly more flexible label of your own that does not require modifying the styles, and can be updated at runtim. Something along the lines of:
public class Icon extends Label {
private static final String CONTENT = "<span class=\"v-icon v-icon-%s\" style=\"font-family: %s; color: %s; font-size: %spx;\">&#x%s;</span>";
private Color color;
private int size;
private VaadinIcons icon;
public Icon(VaadinIcons icon) {
this(icon, Color.BLACK, 16);
}
public Icon(VaadinIcons icon, Color color, int size) {
this.icon = icon;
this.color = color;
this.size = size;
setContentMode(ContentMode.HTML);
updateIcon();
}
public void setIcon(VaadinIcons icon) {
this.icon = icon;
updateIcon();
}
public void setSize(int size) {
this.size = size;
updateIcon();
}
private void updateIcon() {
setValue(String.format(CONTENT,
icon.name(),
icon.getFontFamily(),
color.name(),
size,
Integer.toHexString(icon.getCodepoint())));
}
public void setColor(Color color) {
this.color = color;
}
public enum Color {
BLACK, GREEN
}
}
Where myLayout.addComponents(new Icon(VaadinIcons.PLUS), new Icon(VaadinIcons.INFO, Icon.Color.GREEN, 200)); results in:
There could be more elegant solutions, but this is as far as I went brainstorming because I didn't have such a need so far. I always used regular sized icons with buttons and labels. Anyhow, hopefully this should get you started.
Related
I am using an JavaFX Alert with a text area on it.
The problem I have is that the text area does not use the full space of the Alert, as well as having white (borders).
My code:
TextArea area = new TextArea("");
area.setWrapText(true);
area.setEditable(false);
area.getStylesheets().add(getClass().getResource("/model/app.css").toExternalForm());
Alert alert = new Alert(AlertType.NONE);
alert.getDialogPane().setPrefWidth(750);
alert.getDialogPane().setPrefHeight(800);
alert.getDialogPane().setContent(area);
formatDialog(alert.getDialogPane());
alert.setTitle("Lizenz Info");
Window w = alert.getDialogPane().getScene().getWindow();
w.setOnCloseRequest(e -> {
alert.hide();
});
w.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.ESCAPE) {
w.hide();
}
}
});
alert.setResizable(true);
alert.showAndWait();
My corresponding css sheet:
.text-area .content {
-fx-background-color: #4c4c4c;
}
.text-area {
-fx-text-fill: #ff8800;
-fx-font-size: 15.0px;
}
.text-area .scroll-pane {
-fx-background-color: #4c4c4c;
}
.text-area .scroll-pane .viewport {
-fx-background-color: #4c4c4c;
}
.text-area .scroll-pane .content {
-fx-background-color: #4c4c4c;
}
.viewport and .content on .scrollpane did not have any effect whatsoever.
I want the white borders either to be gone, or have the same color as the background, also to use the full space of the dialog. Can someone help?
As #jewelsea suggested, I think Alert is not the right choice here. Your desired layout can be acheived by using Dialog (as in below code).
Dialog<String> dialog = new Dialog<>();
dialog.setTitle("Lizenz Info");
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK);
dialog.getDialogPane().setContent(area);
dialog.setResizable(true);
dialog.showAndWait();
Having said that, you can fix the existing issues as below:
Remove white space around text area: You can remove the white space by setting the padding of TextArea to 0. Include the below code in the css file.
.text-area{
-fx-padding:0px;
}
Changing the white space background : The .text-area and .content styleclasses are on same node. So instead of declaring with space between them
.text-area .content {
-fx-background-color: #4c4c4c;
}
you have to declare without the space between the styleclasses (in below code)
.text-area.content {
-fx-background-color: #4c4c4c;
}
Here is a similar example to Sai's but uses a standard stage.
It uses a UTILITY style, but you could use a different style if you prefer.
Basically, if you don't want the additional styling and functionality of the alerts and dialogs (and you don't seem to with at least the example you have given), then you can just use a standard stage to display your content rather than the dialog classes provided in the javafx.control package.
The alert.css file referenced in the example is the CSS from your question.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.*;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class TextAreaUtility extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage stage) {
Button showAlert = new Button("Show Alert");
showAlert.setOnAction(this::showAlert);
stage.setScene(new Scene(showAlert));
stage.show();
}
private void showAlert(ActionEvent e) {
TextArea textArea = new TextArea("");
textArea.setWrapText(true);
textArea.setEditable(false);
Scene scene = new Scene(textArea, 750, 800);
scene.getStylesheets().add(
TextAreaUtility.class.getResource(
"alert.css"
).toExternalForm()
);
Stage utility = new Stage(StageStyle.UTILITY);
utility.initOwner(((Button) e.getSource()).getScene().getWindow());
utility.initModality(Modality.APPLICATION_MODAL);
utility.setTitle("Alert Title");
utility.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (event.getCode() == KeyCode.ESCAPE) {
utility.hide();
}
});
utility.setResizable(true);
utility.setScene(scene);
utility.showAndWait();
}
}
Debugging nodes and styles info
If you want to see the nodes and style names in your scene graph and you aren't using a tool like ScenicView, a quick debug function is:
private void logChildren(Node n, int lvl) {
for (int i = 0; i < lvl; i++) {
System.out.print(" ");
}
System.out.println(n + ", " + n.getLayoutBounds());
if (n instanceof Parent) {
for (Node c: ((Parent) n).getChildrenUnmodifiable()) {
logChildren(c, lvl+1);
}
}
}
Which you can attach to run when the window is displayed:
w.setOnShown(se -> logChildren(alert.getDialogPane().getScene().getRoot(), 0));
When you run this on a standard dialog you will see quite a few nodes in the scene graph with attached styles that you can find defined in the modena.css file within the JavaFX SDK. You will also see that some of the bounding boxes for the layout that are not related to your text area have width and height.
Those dialog styles by default have padding attached to them, which is why you are seeing padding around your TextArea. The padding is not in the text area but the content regions containing it within the dialog. To get rid of it, you need to set the padding in your custom CSS to override the default. I don't have the CSS for that, it is difficult to create sometimes and overriding default padding is probably best avoided when possible.
(This is my first post, sorry if I do something wrong...)
I am writing a program in Vala with which one can design a classroom.
I have decided to use GTK for the GUI (Vala integrates well with this),
and Cairo to draw the classroom diagram (GTK comes with this by default).
I have created a 'classroom' class (a subclass of Gtk.DrawingArea),
which currently should just display a square:
public class Classroom : DrawingArea
{
private delegate void DrawMethod();
public Classroom()
{
this.draw.connect((widget, context) => {
return draw_class(widget, context, context.stroke);
});
}
bool draw_class(Widget widget, Context context, DrawMethod draw_method)
{
context.set_source_rgb(0, 0, 0);
context.set_line_width(8);
context.set_line_join (LineJoin.ROUND);
context.save();
context.new_path();
context.move_to(10, 10);
context.line_to(30, 10);
context.line_to(30, 30);
context.line_to(10, 30);
context.line_to(10, 10);
context.close_path();
draw_method(); // Actually draw the lines in the buffer to the widget
context.restore();
return true;
}
}
I have also created a class for my application:
public class SeatingPlanApp : Gtk.Application
{
protected override void activate ()
{
var root = new Gtk.ApplicationWindow(this);
root.title = "Seating Plan";
root.set_border_width(12);
root.destroy.connect(Gtk.main_quit);
var grid = new Gtk.Grid();
root.add(grid);
/* Make our classroom area */
var classroom = new Classroom();
grid.attach(classroom, 0, 0, 1, 1);
//root.add(classroom);
root.show_all();
}
public SeatingPlanApp()
{
Object(application_id : "com.github.albert-tomanek.SeatingPlan");
}
}
And this is my main function:
int main (string[] args)
{
return new SeatingPlanApp().run(args);
}
I put my classroom widget into a Gtk.Grid, my layout widget of choice.
When I compile my code and run it, I get a blank window:
However, if I do not use Gtk.Grid, and just add my classroom using root.add() (which I have commented out), the classroom widget is displayed correctly:
Why does my widget not show up when adding it using Gtk.Grid?
What can I do to fix this?
The problem is that the cell is sized 0x0 pixels, because the grid doesn't know how much space your drawing area actually needs.
A simple solution is to just request some fixed size, try this:
var classroom = new Classroom();
classroom.set_size_request (40, 40);
PS: I got this idea by looking at other similar questions on SO, particularly this one.
In an AS3 mobile App, I would like to have a menu of buttons or icons that slides up from the bottom. Using a SlideViewTransition, I can get part of what I want.
var transition:SlideViewTransition = new SlideViewTransition();
transition.direction = ViewTransitionDirection.UP;
transition.mode = SlideViewTransitionMode.COVER;
view.navigator.pushView(ShareView, null, null, transition);
This works, but it does not do two things that I need to do.
1) I want the new transition to only go up 1/2 of the screen so that the top part of the screen displays the view underneath.
2) I want the new view that covers to be partially transparent. By setting the alpha of the incoming view's contentGroup background alpha, the new view is transparent as it comes in. But, once it covers the view underneath the view becomes opaque.
this.contentGroup.setStyle('backgroundAlpha', 0.5);
Does anyone have any ideas of how I would have a view slide up 1/2 way and be transparent? I have no idea where to start, view skinning?, or subclass transition?, or use something in flash namespace instead of a spark view.
I decided it would be simplest to just use the lower level ActionScript and do the animation myself using methods that are normally applied to a Sprite, but in this case use a VGroup so that I could add spark elements to it. The following is the base class I wrote.
public class SlideUpDialog extends VGroup {
private var pctHeight:Number;
private var stopHeight:Number;
private var vertIncrement:Number;
public function SlideUpDialog(pctHeight:Number) {
super();
this.pctHeight = pctHeight;
if (stage) {
addedToStageHandler();
} else {
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
}
private function addedToStageHandler(event:Event=null) : void {
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
graphics.beginFill(0xEEEEEE, 0.8);
graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight * pctHeight);
graphics.endFill();
var bevel:BevelFilter = new BevelFilter(4, -45);
this.filters = [ bevel ];
x = 0;
y = stage.stageHeight;
stopHeight = y * (1 - pctHeight);
vertIncrement = y / 2 / 24 / 4;
}
public function open() : void {
addEventListener(Event.ENTER_FRAME, openFrameHandler);
}
private function openFrameHandler(event:Event) : void {
if (y > stopHeight) {
y -= vertIncrement;
} else {
removeEventListener(Event.ENTER_FRAME, openFrameHandler);
}
}
public function close() : void {
... the reverse of open
}
}
I have created a custom widget, basically an Image and a text label.
What must I do so that I can now set the position of the text ( top/left/bottom of the image for example ) using nothing only CSS? I mean what methods would my class need so that the CSS styling can be applied to it?
ie Can I have a css class like so
.ImageAndLabel
{
imagePosition: top;
}
Heres my gwt class
public class ImageAndLabel extends Composite
{
private Label label = new Label();
private Image img = new Image("/images/pinkBackground.png");
protected final FlexTable contentTable;
public ImageAndLabel()
{
contentTable = new FlexTable();
initWidget(contentTable);
label.getElement().getStyle().setFontSize(40, Unit.PX);
contentTable.setWidget(0,0,img);
img.setHeight("200px");
contentTable.setWidget(0,1,label);
label.getElement().getStyle().setLeft(0, Unit.PX);
img.getElement().setId("popupImg");
label.getElement().setId("popupLabel");
}
public void setText(String text)
{
label.setText(text);
}
}
I guess what I'm after is can I create my own Custom CSS codes?
You can use flextable method for alignment.
example :
flexTable.getFlexCellFormatter().setAlignment(0, 0,
HasHorizontalAlignment.ALIGN_CENTER, HasVerticalAlignment.ALIGN_MIDDLE);
I've just started playing about with skinning and am finding it harder than anything else I've come across in Flex 4 Mobile. It needs to be done in actionscript as I am trying to skin a flex mobile button. Here is what I have so far: (It does very little, only changes the background color)
package skins {
import flash.display.GradientType;
import flash.geom.Matrix;
import mx.utils.ColorUtil;
import spark.components.supportClasses.StyleableTextField;
import spark.skins.mobile.ButtonSkin;
import spark.skins.mobile.supportClasses.MobileSkin;
public class CustomButtonSkin extends ButtonSkin {
public function CustomButtonSkin() {
super();
layoutPaddingLeft = 10;
layoutPaddingRight = 10;
layoutPaddingTop = 2;
layoutPaddingBottom = 2;
layoutCornerEllipseSize = 1;
}
private static var colorMatrix:Matrix = new Matrix();
private static const CHROME_COLOR_ALPHAS:Array = [1, 1];
private static const CHROME_COLOR_RATIOS:Array = [0, 127.5];
override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void {
super.drawBackground(unscaledWidth, unscaledHeight);
var chromeColor:uint = getStyle("chromeColor");
if (currentState == "up") {
graphics.beginFill(0x1C1C1C);
}
else{
var colors:Array = [];
colorMatrix.createGradientBox(unscaledWidth, unscaledHeight, Math.PI / 2, 0, 0);
colors[0] = 0xFFFFFF;//ColorUtil.adjustBrightness2(chromeColor, 70);
colors[1] = 0xEEEEEE;//chromeColor;
graphics.beginGradientFill(GradientType.RADIAL, colors, CHROME_COLOR_ALPHAS, CHROME_COLOR_RATIOS, colorMatrix);
graphics.endFill();
}
}
}
}
There doesn't seem to be much in the way of documentation for skinning Flex mobile components purely in actionscript. How do we add a border for example? If anyone could post their custom flex mobile skins it would be hugely appreciated!
Specifically to draw a border, I would draw one manually using the graphics API.
this.graphics.lineStyle(1, color, alpha, true);
this.graphics.drawRect(0, 0, width, height);
I have a bunch of blog posts/podcasts about building mobile skins / itemRenderers that may help you:
https://www.flextras.com/blog/index.cfm/2011/6/17/Mobile-itemRenderers--6172011---Episode-103--Flextras-Friday-Lunch
https://www.flextras.com/blog/index.cfm/2011/6/23/Understanding-Mobile-itemRenderers
https://www.flextras.com/blog/index.cfm/2011/6/24/Building-a-Mobile-ItemRenderer-in-Flex
https://www.flextras.com/blog/index.cfm/2011/7/8/Implementing-States-in-a-Mobile-Skin---782011---Episode-105--Flextras-Friday-Lunch
https://www.flextras.com/blog/index.cfm/2011/7/13/Implementing-States-in-a-Mobile-Skin-or-Mobile-ItemRenderer
The ButtonSkin has the properties upBorderSkin and downBorderSkin, which you would set equal to fxg graphic resources in the constructor:
public function CustomButtonSkin()
{
super();
// your padding settings here
upBorderSkin = path.to.fxg.resource.upBorder;
downBorderSkin = path.to.fxg.resource.downBorder;
}
And you would override drawBackground with an empty body, not even super.drawBackground():
override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
{
}
This is so that your custom skin won't draw the default background.
You don't even have to detect a state change to draw something different. By specifying the border skin properties, you would be letting the ButtonSkin parent class to detect the state changes and draw the appropriate graphic.
See http://www.adobe.com/devnet/flex/articles/mobile-skinning-part1.html for more information, especially using fxg resources.