Setting CSS to use when printing from JavaFX - java

I am writing a program which needs to print notes about deliveries made. Currently using the JavaFX 8 printing methods I've been able to create a basic delivery note however the default style for displaying a TableView contains a lot of greyscale which makes a physical printed copy look strange and difficult to read.
I have used CSS to style the TableView to be solid black and white however when printing it seems to ignore the CSS that I have set.
Here's what I have currently:
private void printDeliveryNote(){
PrinterJob job = PrinterJob.createPrinterJob();
PageLayout pageLayout = Printer.getDefaultPrinter().createPageLayout(Paper.A4, PageOrientation.PORTRAIT, Printer.MarginType.HARDWARE_MINIMUM);
Group pane = new Group();
pane.getChildren().addAll(getNodeToPrint());
pane.getStylesheets().add("css/main.css");
if (job != null && job.showPrintDialog(new Stage())){
boolean success = job.printPage(pageLayout, pane);
if (success){
job.endJob();
}
}
}
private Node getNodeToPrint() {
Group group = new Group();
Label prntDeliveryId = new Label("Delivery Id: " + txtDeliveryId.getText());
prntDeliveryId.setLayoutX(txtDeliveryId.getLayoutX());
prntDeliveryId.setLayoutY(txtDeliveryId.getLayoutY());
Label prntDate = new Label("Date: " + txtDate.getText());
prntDate.setLayoutX(txtDate.getLayoutX() - 20);
prntDate.setLayoutY(txtDate.getLayoutY());
Label prntTitle = new Label(lblTitle.getText());
prntTitle.setLayoutX(lblTitle.getLayoutX());
prntTitle.setLayoutY(lblTitle.getLayoutY());
prntTitle.setFont(lblTitle.getFont());
ImageView imgBarcode = new ImageView(SwingFXUtils.toFXImage(handleBarcode(txtDeliveryId.getText()), null));
imgBarcode.setLayoutX(txtDeliveryId.getLayoutX());
imgBarcode.setLayoutY(txtDeliveryId.getLayoutY());
TableView<InstrumentContainer> prntInstrumentList = new TableView<InstrumentContainer>();
setupInstrumentList(prntInstrumentList);
prntInstrumentList.setLayoutY(lstInstruments.getLayoutY() + 40);
prntInstrumentList.setPrefWidth(lstInstruments.getPrefWidth());
System.out.println(prntInstrumentList.getHeight());
prntInstrumentList.setLayoutX(lstInstruments.getLayoutX());
group.getChildren().addAll(
prntDeliveryId,
prntDate,
prntInstrumentList,
prntTitle,
imgBarcode
);
return group;
}
The CSS file looks like this (which works when displaying on a form rather than when printed):
.table-row-cell{
-fx-table-cell-border-color: #424242;
}
.column-header{
-fx-border-color: #424242;
-fx-background-color: #ffffff;
}
The TableView with the style applied to it on the form looks like this:
But when printed it still has the default style:
Any ideas of how to style a node which is being printed?

This is probably a precedence issue. JavaFX includes its own default stylesheet modena.css* which can, and often does, use higher specificity rules than any custom ones you may have added.
One way to get around this would be to add !important to each of the declarations:
.table-row-cell {
-fx-table-cell-border-color: #424242 !important;
}
.column-header {
-fx-border-color: #424242 !important;
-fx-background-color: #ffffff !important;
}
If you have a lot of properties to override this might become a bit tedious. You could look at the default styles in the default stylesheet (linked above) and use a specificity calculator to work out how to make your selector more specific than the default one.
* Older versions may use different default stylesheets.

Related

How to set the cell color dynamically in grid header by it's value

I am trying to dynamically change the color of header cells
The columns with header in grid are generated dynamically too:
for (Employee emp : employees) {
Grid.Column<Employee> empColumn = grid.addColumn(...).setHeader(emp.getNameWithEmpRelationship());
}
But I only know how to change the color of whole header row, not only for cell
My custom .css file:
:host(.header-change) [part~="header-cell"] {
background-color: #ececec;
color: black;
}
Then I added it into the grid
grid.addClassName("header-change");
And result looks like:
But I need to do something like this:
for (Employee emp : employees) {
Grid.Column<Employee> empColumn = grid.addColumn(...).setHeader(emp.getNameWithEmpRelationship());
if(emp.getNameWithEmpRelationship().name().equals("CONTRACT") {
empColumn.addClassName("orange-cell");
}
if(emp.getNameWithEmpRelationship().name().equals("PART_TIME") {
empColumn.addClassName("green-cell");
}
if(emp.getNameWithEmpRelationship().name().equals("FULL_TIME") {
empColumn.addClassName("blue-cell");
}
}
.css should looks like:
.orange-cell {
background-color: orange;
color: black;
}
.blue-cell {
background-color: blue;
color: black;
}
.green-cell {
background-color: green;
color: black;
}
And the result should looks like (I achieved the sample result by manually adjusting the value of the element through the browser):
How can I do this? Because my example is not working.
I'm afraid the short answer is that you can't. While you can apply css classnames, and thus styling, to body cells, using ClassNameGenerator, that does not work for header cells.
What you can do is use a component for the header cells' contents, using Column.setHeader(Component c); Then you can of course apply styling whichever way you like to that component.
However, that component is not going to cover the entire space. While it's technically possible to make that happen with css, it's complicated, error prone, and not really supported.
There's a feature request ticket for this here: https://github.com/vaadin/web-components/issues/1434. You can vote for the feature by adding a thumbs-up reaction.

Dinamically changing the font size and its style in the TextArea causes padding bugs

I am creating a small text editor with JavaFX.
For this purpose I use TextArea and ComboBox'es to dynamically style it: e.g. changing the font, it's size, making it bold, italic and so on. It kind of works, however there is a disturbing visual bug that I can't put up with.
I tried to narrow the problem and here is a simpler code that has the same behavior and a couple of pics to understand what I'm talking about:
(to reproduce the bug set the size to 70 then choose bold and you will see how the text steps away from the edge.)
public class Main extends Application {
public void start(Stage stage) {
textArea = new TextArea("TEST 112123");
textArea.setPrefWidth(800);
textArea.setPrefHeight(400);
textArea.setLayoutY(40);
CheckBox bold = new CheckBox("BOLD");
bold.setLayoutX(20);
bold.setOnAction(e -> {
Font currentFont = textArea.getFont();
if (bold.isSelected()) {
textArea.setFont(
new Font("System Bold", currentFont.getSize()));
//I set new Font each time to save all of it's past properties and
//change only one of them, this is the only way that I found to do
//this as there are no setters in the Font class, only constructors
} else {
textArea.setFont(
new Font("System", currentFont.getSize()));
}
});
ComboBox sizeBox = new ComboBox();
//I removed the list of options and the input validity check
sizeBox.setLayoutX(80);
sizeBox.setEditable(true);
sizeBox.setOnAction(e -> {
textArea.setFont(new Font(textArea.getFont().getName(),
Double.valueOf((String)sizeBox.getValue())));
});
stage.setScene(new Scene(new Group(textArea, bold, sizeBox), 800, 500));
stage.show();
}
}
images: https://imgur.com/a/Cg53nAL
You can add the following stylesheet.
.text-area .content {
-fx-padding: 3 7 3 7;
}
It overrides the padding from modena.css:
.text-area .content {
/*the is 1px less top and bottom than TextInput because of scrollpane border */
-fx-padding: 0.25em 0.583em 0.25em 0.583em; /* 3 7 3 7 */
-fx-cursor: text;
-fx-background-color:
linear-gradient(from 0px 0px to 0px 4px, derive(-fx-control-inner-background, -8%), -fx-control-inner-background);
-fx-background-radius: 2;
}

JavaFX - Set Different Backgrounds for contents of Different TextArea

I'm a newbie in JavaFX. How to set different background colors for the contents of different TextAreas. As far as I know , using CSS, I can set background color like
.text-area {
-fx-background-color: transparent;
-fx-text-box-border: gray;
}
.text-area .scroll-pane .content{
-fx-background-color: transparent;
}
But it is affecting both TextAreas.
Also what is the background color of the disabled TextArea in JavaFX and how can I modify it?
TextArea textarea = new TextArea();
TextArea textarea1 = new TextArea();
These are the attributes I have applied
textarea1.setMaxHeight(180);
textarea1.setMaxWidth(500);
textarea.setEditable(false);
textarea.setPrefRowCount(15);
textarea.setWrapText(true);
textarea.setStyle("-fx-background-color: transparent");
textarea1.setStyle("-fx-background-color: tomato");
You can introduce a custom variable in CSS to determine the color.
When a TextArea is disabled, the opacity of the TextArea and children is set to 0.4 (=40%). You can undo this by overwriting the property in your stylesheet, if you wish.
.text-area {
/* use variable as inner background */
-fx-control-inner-background: content-background;
}
/* keep element fully opaque, when disabled */
.text-area:disabled,
.text-area *:disabled {
-fx-opacity: 1;
}
/* replace inner background with darker color, when disabled */
.text-area:disabled {
-fx-control-inner-background: derive(content-background, -40%);
}
// set content-background from inline style
textarea.setStyle("content-background: transparent;");
textarea1.setStyle("content-background: tomato;");
In case you do not need the color to determine the -fx-control-inner-background based on your chosen color (the derive part), you could also simply assign the property from inline style. In this case you do not need the CSS rules for the background in your stylesheet.
textarea.setStyle("-fx-control-inner-background: transparent;");
textarea1.setStyle("-fx-control-inner-background: tomato;");
So what you need to do is put this line inside your css page:
.text-area .content {
-fx-background-color: text-area-background ;
}
So now whatever you set your text-area background to it will set the content back grounf to that. So you should be able to do this below and it will work:
TextArea one = new TextArea();
TextArea two = new TextArea();
TextArea three = new TextArea();
one.setStyle("-fx-background-color: transparent");
two.setStyle("-fx-background-color: tomato");
three.setStyle("-fx-background-color: steelblue");

Menu Style CSS Java

Am hoping someone can advise what is need to be changed to remove the hideous border (?) from this menu (see image).
Have extracted modena from the java jar to see how they do it but to no avail. Sure it's very very simple just drawing a blank at the moment.
The css at the moment is very simple just not sure which element need to be changed / added.
.menu-bar {
-fx-background-color:#237a72;
/*-fx-border-width:2;*/
}
.menu-bar .label {
-fx-text-fill:#ffffff;
}
.menu-bar .label:hover {
-fx-text-fill:yellow;
}
.menu-item {
-fx-background-color:#237a72;
-fx-border-color: #237a72;
}
Many Thanks.
The white border is the background color of the context-menu.
So if you want to get rid of it, you could remove the padding:
.context-menu {
-fx-padding: 0;
}

Fill buttons in grid with FontAwesome icons and add tooltips to them

Is there any way to use FontAwesome for buttons in Grid? I tried to make it as an html - but buttos dont parse html but I can only see it as text.
I also tried to make a custom renderer (from https://vaadin.com/forum#!/thread/9418390/9765924) but it does not work - no errors, it just wont change text no matter how i do it.
I would like to have 3 buttons with FontAwesome icons and tooltips in every row. Is there some simple way to do that?
I guess what you want is clickable icons that don't necessarily need to be buttons.
So instead of using ButtonRenderer to add buttons, for which you can only provide a caption, a simple solution is to use HtmlRenderer to add the FontAwesome icon (1 column for each icon), then use an ItemClickListener. Use ItemClickEvent#getPropertyId() to detect which column was clicked.
I've a simple workaround for the FontIcon issue.
I've used a normal ButtonRenderer and I've overridden the getValue() method of PropertyValueGenerator object to return the icon codepoint.
wrapperContainer.addGeneratedProperty("delete", new PropertyValueGenerator<String>() {
#Override
public String getValue(Item item, Object itemId, Object propertyId) {
return "\uF014"; //FontAwesome.TRASH_O
}
#Override
public Class<String> getType() {
return String.class;
}
});
I've put in scss the right font-family for button element:
button {
border: 0;
background-color: transparent;
background-size: 25px;
color: $v-blue-color;
font-family: FontAwesome;
height: 25px;
width: 25px;
}
Pure-Java solution for Vaadin 8:
final ButtonRenderer<Person> renderer = new ButtonRenderer<>(event -> onPersonClicked(event.getItem()));
renderer.setHtmlContentAllowed(true);
grid.addColumn(person -> VaadinIcons.EXTERNAL_BROWSER.getHtml(), renderer).setWidth(60);
There is lots of alternative
Like add with HtmlRenderer or CellStyleGenerator and anothers
But HtmlRenderer uploading for every row like this data
25=<span class="v-icon v-icon-caret_square_up_o" style="font-family: Vaadin-Icons;"></span>
This is big problem for network traffic
So I like to use
Grid.Column gridColumn = grid.addColumn(a -> (char) FontAwesome.BTC.getCodepoint());
gridColumn.setStyleGenerator(item -> "cssStyleName");
With this network usage is better as you see
27= //unshowing character is icon character code
but don't forget to add "cssStyleName" to css / for example
.cssStyleName {font-family: FontAwesome; }
And listen clicks with
grid.addItemClickListener(event -> {
if (!event.getMouseEventDetails().isDoubleClick()) {
//To Do
}
}
This is compatible with Vaadin 8
A button with just an icon and a tooltip can be created like this:
Button button = new Button(FontAwesome.ANDROID);
button.setDescription("Any tooltip");
To generate buttons for each row, just use any fitting loop (for or while).

Categories

Resources