JavaFX ScrollPane border and background - javafx-2

I'm having some problem regarding the default background and border of the ScrollPane.
Using this style made the problem clearer to see.
setStyle("-fx-background-color:blue; -fx-border-color:crimson;");
I've tried this style and got no luck only the red border gone and left me with the blue one.
setStyle("-fx-background-color:blue; -fx-background-insets:0; -fx-border-color:crimson; -fx-border-width:0; -fx-border-insets:0;");
I've looked at this old post JavaFX Hide ScrollPane gray border and http://docs.oracle.com/javafx/2/ui_controls/editor.htm
This line of code doesn't work neither
scrollPane.getStyleClass().add("noborder-scroll-pane");
Thanks

In the current version of JavaFX 8, you can use the edge-to-edge style class to remove the border entirely:
<ScrollPane styleClass="edge-to-edge"/>

I have found a solution and would liked to post it here so others won't need to waste their time find it again.
By looking at the default css of JavaFx (caspian.css) which has been extracted from the library using this command.
jar xf jfxrt.jar com/sun/javafx/scene/control/skin/caspian/caspian.css
I could see that the one I missed is
-fx-padding: 0;
So this is the css class I'm using.
.scroll-pane {
-fx-background-insets: 0;
-fx-padding: 0;
}
.scroll-pane:focused {
-fx-background-insets: 0;
}
.scroll-pane .corner {
-fx-background-insets: 0;
}

Try use this first
.scroll-pane > .viewport {
-fx-background-color: transparent;
}
Before setting the background color

There seems to be a simple solution, which is to use "-fx-background: rgb(80,80,80);", that is,
scrollPane.setStyle("-fx-background: rgb(80,80,80);");
At least this works perfectly for me, while "-fx-background-color: rgb(80,80,80);" or "-fx-control-inner-background: rgb(80,80,80);" do not work in javafx 8. "-fx-background-color: rgb(80,80,80);" did work in earlier versions of javafx.

You can use:
-fx-background-color: transparent;
-fx-control-inner-background: transparent;
If you set only -fx-background-color, you will see the color change is applied to only the ScrollPane's inner edges, and the color of the center area is still not changed.
The -fx-control-inner-background property will change the color of that center area.

Honestly, your question was not clear enough, but I am only providing this answer to help others if I can.
What is causing this problem is you have the ScrollPane and inside it something called viewport that is bound to the ScrollPane. The properties that you apply for the ScrollPane object does not apply for the viewport. If you want to apply the properties for both ONLY, not the children too, you have to use the stylesheet property, not the style property itself, which uses in-line css code. For example, if you want to make the ScrollPane transparent, you have to apply the property for both, assuming the name of file is "scrollPane.css", like so:
#mainScrollPane > .viewport {
-fx-background-color: transparent;
}
#mainScrollPane {
-fx-background-color: transparent;
}
However, you need to apply a special Id property for the ScrollPane object, so it does not apply for the children:
ScrollPane scrollPane = new ScrollPane(root);
scrollPane.setId("mainScrollPane");
scrollPane.getStyleSheets().add("scrollPane.css");

Rather than use FXML or CSS I prefer to consume the event, but this only works on the portion that has content. If your scrollPane is larger than its content you also have to fill the remaining space.
scrollPane.getContent().setOnMousePressed(Event::consume);
scrollPane.setFitToHeight(true);
scrollPane.setFitToWidth(true);

Related

change the background color of a cell in a QTableWidget element when the content is edited

I am designing a QTableWidget element in which I need to change the default behavior of a cell when it is edited.
What I need to achieve is that the background of the cell does not change to white, but rather that I can change that background to another color
This is my style sheet code
QTableWidget{
border:none;
border-left:1px solid #b0b9cf;
border-bottom: 1px solid #b0b9cf;
border-right:1px solid #b0b9cf;
selection-color:red;
selection-background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0, 0), stop:1 rgba(255, 255, 255, 0));
}
QHeaderView::section:horizontal{
background:#3d4454;
color:white;
border:0px;
border-bottom:2px solid #b0b9cf;
boder-left: 1px solid #b0b9cf;
border-right:1px solid #b0b9cf;
}
QTableWidget::item:selected{
border:1px solid blue;
}
QTableWidget::item:alternate{
background:red;
color:white;
}
The section indicated in the image represents the cell that is in text editing mode and changes its background color to white. The result that I expect to obtain is that the background and text color does not change when it enters editing mode
In other words, in this case, keep the red background and the white text color
Thank you and I hope you can help me
It's not possible to do it dynamically.
The problem is that QSS (Qt Style Sheets) completely override the underlying style and drawing of complex widgets and their sub-elements is completely done internally by the (private) QStyleSheetStyle.
Most importantly, the alternate row color is only intended as a visual aid, because it's scope is usability, not data based customization: the alternate color should always be related to the base color, because the text color should be the same and readable in both cases.
While QSS allow such customization, advanced usage is limited.
You could theoretically work around the background by using a custom delegate and set a transparent background for the editor, but this would show the current content of the cell also, so it's not a valid option.
There is no direct and easy way to know the actual background/text color of the cell if it's set by stylesheets. The only solution is to use hardcoded colors and set them for the editor:
class Delegate(QStyledItemDelegate):
def createEditor(self, parent, option, index):
editor = super().createEditor(parent, option, index)
if index.row() & 1:
editor.setStyleSheet('''
{} {{ background: red; color: white;}}
'''.format(editor.__class__.__name__))
return editor
# ...
tableWidget.setItemDelegate(Delegate(tableWidget))
Notes:
remember that QSS work very similar to CSS:
when even a single, main property of a complex widget is styled, you need to set all the other main properties of that widget;
properties are inherited if the QSS can be applied for the target, that's why it's always important to use proper selectors for containers and complex widgets, as I did above (if I used plain properties, the context menu would have used those colors too);
instead of using stylesheets for items, you could consider using a custom delegate that would alter the palette before calling the QStyle drawing within the delegate's paint() function; while this would still need hardcoded colors, they could be accessed dynamically more easily;
QSS are very powerful, but also quite "delicate"; there is no direct way to know every aspect they set, which limits the read access to their rules (see this related answer): most importantly, we can only indirectly access a few color properties for the "main" widget, but any sub-control/state is totally based on the parser and completely internal;
your QSS has a typo (boder-left should be border-left);

How do I get rid of the border around a split pane in JavaFX?

I'm using the JavaFX SceneBuilder, but I'll paste the FXML below since it's short. I have a very simple window with a split pane inside an anchor pane. Here is the FXML:
<?xml version="1.0" encoding="UTF-8"?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml">
<children>
<SplitPane id="main-split-pane" dividerPositions="0.25" focusTraversable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="-1.0" prefWidth="-1.0" style="" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" style="" />
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
</items>
</SplitPane>
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
<stylesheets>
<URL value="#main-view.css" />
</stylesheets>
</AnchorPane>
I'm using the following CSS:
#main-split-pane {
-fx-border-style: none;
-fx-border-color: blue;
-fx-border-width: 25;
}
It gives me a windows like this:
I've played around with the CSS settings shown here, but there are a few things I'm having trouble understanding:
Where is the border I've marked with the red arrow coming from?
Why does setting the -fx-border-style to none cause the -fx-border-color to be ignored while the -fx-border-width still has an effect (like padding) on how things look?
Solution - How to remove a border from a Split Pane
Override the -fx-box-border color definition if you don't want the border to show:
split.setStyle("-fx-box-border: transparent;");
Split Pane with Border Removed
Sample Code
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class SplitPaneBorderRemover extends Application {
public static void main(String[] args) throws Exception { launch(args); }
#Override public void start(final Stage stage) throws Exception {
StackPane r1 = new StackPane();
r1.setPrefSize(200, 150);
r1.setStyle("-fx-background-color: palegreen;");
StackPane r2 = new StackPane();
r2.setPrefSize(200, 150);
r2.setStyle("-fx-background-color: coral;");
SplitPane split = new SplitPane();
split.getItems().setAll(
r1, r2
);
split.setStyle("-fx-box-border: transparent;");
StackPane layout = new StackPane();
layout.getChildren().setAll(split);
layout.setStyle("-fx-padding: 20px; -fx-background-color: cornsilk");
stage.setScene(new Scene(layout));
stage.show();
}
}
Answers to Additional Question
Where is the border I've marked with the red arrow coming from?
It's a background style in the default css stylesheet (caspian.css for JavaFX 2.2 or modena.css for Java 8)).
Why does setting the -fx-border-style to none cause the -fx-border-color to be ignored while the -fx-border-width still has an effect (like padding) on how things look?
Because the border of split pane is displayed using a background definition rather than border definition. All default JavaFX control css styles work this way. They set multiple overlaid backgrounds to accomplish border techniques rather than by setting an explicit border attribute.
Understanding How the Answer Works
Although this answer is really just a simple one liner, I'll take some time to explain here why it works. Sorry if this explanation bloats the answer. Those who already know this information can ignore this part of the answer.
I'm still having trouble understanding the concept
Spend some time reading the JavaFX css reference guide, a bit dry I know, but essential reading if you want to understand JavaFX css styling.
There is also an official Oracle tutorial for css, but it's not going to teach you as much as reading the css reference and studying the default style sheets I linked earlier.
I extracted relevant statements from the css reference and quoted them here:
JavaFX has a rich set of extensions to CSS in support of features such as color derivation, property lookup, and multiple background colors and borders for a single node. These features add significant new power for developers and designers and are described in detail in this document.
The -fx-box-border which is set to transparent to remove the border, is not really a border at all, it is a looked up color that has been applied to one of multiple backgrounds for the split-pane.
With looked-up colors you can refer to any other color property that is set on the current node or any of its parents. This is a very powerful feature, as it allows a generic palette of colors to be specified on the scene then used thoughout the application. If you want to change one of those palette colors you can do so at any level in the scene tree and it will affect that node and all its decendents. Looked-up colors are not looked up until they are applied, so they are live and react to any style changes that might occur, such as replacing a palette color at runtime with the "style" property on a node.
In the following example, all background color of all buttons uses the looked up color "abc".
.root { abc: #f00 }
.button { -fx-background-color: abc }
The default definition for -fx-box-border for the Java 8 modena.css style is:
/* A little darker than -fx-color and used to draw boxes around objects such
* as progress bars, scroll bars, scroll panes, trees, tables, and lists.
*/
-fx-box-border: ladder(
-fx-color,
black 20%,
derive(-fx-color,-15%) 30%
);
The default styling for a split-pane is as a "Box Like Thing":
/* ==== BOX LIKE THINGS ================================================= */
.scroll-pane,
.split-pane,
.list-view,
.tree-view,
.table-view,
.tree-table-view,
.html-editor {
-fx-background-color: -fx-box-border, -fx-control-inner-background;
-fx-background-insets: 0, 1;
-fx-padding: 1;
}
. . .
/* ones with grey -fx-background not lighter -fx-control-inner-background */
.scroll-pane,
.split-pane {
-fx-background-color: -fx-box-border, -fx-background;
}
So, analyzing the css, you can see that, for an unfocused split-pane there are two backgrounds defined (as the latest or most specific definition of -fx-background-color for .split-pane wins css's weird application rules). The inner background is colored as -fx-background and is inset one pixel. The outer background is colored as -fx-box-border and is not inset. Padding for the split pane is set to one pixel. This prevents the split pane content from overwriting the one pixel border around it.
The solution in this answer works by overriding the look-up color definition in code specifically for a a given splitpane instance by using the setStyle method. By setting the -fx-box-border to transparent (though perhaps null could have been used equally as well and might be more efficient), the border is set to be not visible (even though it is still there and the padding for it remains in the css at 1 pixel).
Further modification of the css (by applying your own user stylesheet to override the default split-pane style class) could remove this one pixel padding if desired:
.split-pane {
-fx-background-color: -fx-control-inner-background;
-fx-background-insets: 0;
-fx-padding: 0;
}
Now all trace of the border is gone and your content is free to fill the entire area of the split pane including the 1 pixel area where the border used to be. I prefer the minimal change of just setting the -fx-box-border to transparent though because then your user style definitions are small and don't detail a lot from the default style.
For example, set -fx-box-border: red; and you'll get a 1px red border around the split pane.
Yep, that's because the default background area the -fx-box-border color is coloring is only 1 pixel wide and you have just explicitly set the pixel color to red.
I assume it's the box-border on the padding component.
No, as described above the reason is because the background the -fx-box-border an inset of 0 pixels from the edge of the region and the inner background -fx-background-color is inset 1 pixel from the edge of the region, leaving 1 pixel width colored with the -fx-box-border. All the -fx-padding is doing in this instance is ensuring that your split pane content does not draw over the 1 pixel outer background for the split-pane.
Then set -fx-padding: 5; on split. The red box-border disappears and another gray border shows up.
The "gray border" was always there - it's the second, inner background defined in the split-pane css style (the -fx-background one). And the default -fx-background color is gray. By setting -fx-padding to 5 you are saying to inset the content of the split pane 5 pixels from the outside edge of the splitpane region. This allows the default background to show through.
If your content had some transparent areas and did not fill the whole available region of the split-pane, then you would also have seen this gray -fx-background-color color show through in those transparent areas.
If what you wanted was to achieve a 5 pixel border around your content in -fx-box-border color then you would need to adjust both the padding and the border insets, for example:
.split-pane {
-fx-background-color: -fx-box-border, -fx-control-inner-background;
-fx-background-insets: 0, 5;
-fx-padding: 5;
}
If the manual analysis of the padding, background insets, css style derivation rules, etc for a large application seems like it would be daunting, know that there is tool support to help understand both the scene graph structure and css application. The tools to use are SceneBuilder's css analyzer for design time css analysis and ScenicView for runtime scenegraph and css analysis.
If you want to remove the border around the split pane, but keep the ones for dividers, do this:
.split-pane {
-fx-background-color: transparent, -fx-background;
}

Drupal autocomplete search UI bug

Hi in Drupal 7 I am using autocomplete search. In search input it displays part of ajax loader animation all the time even when the input is not focused. Bug is marked with red square .
Any suggestions please why there is this bug. (I am using boostrap theme)
Thank you for help.
It's not a twitter bootstrap error.
See your drupal installation's misc/throbber.gif file. You will see that it's actually a sprite and when the ajax request is in progress, it changes its position to show the animated throbber.
You will need to create a new one and adjust CSS accordingly to workaround this issue. Your text field has a relatively higher length than this sprite's
Add the following CSS to your theme's css file. These styles are defined already, so you will only need to override them. See inline comments.
html.js input.form-autocomplete {
background-image: url("/misc/throbber.gif"); // Enter a new thribber image here.
background-position: 100% 2px;
background-repeat: no-repeat;
}
html.js input.throbbing {
background-position: 100% -18px; // Adjust this -18px to the height of your new throbber.
}

How do I make a 100% width fixed div to leave some space on right?

I have a div which has position set to fixed. This div is meant to be site's header.
The problem is that it should take 100 % of the width except for leaving a small gap on the right edge, where we show a custom styled scroll-bar. The body of this page has been absolutely positioned and overflow set to scroll to present the custom scroll-bar.
I tried with 100% width, but then it takes 100% of the view-port instead of its parent. I also tried setting margin-right to scroll-bar width but it seems that is not honored. Is there a way to do this without using Javascript?
Let me just say this..
If your width is set to 100%, and you set margin-right: 20px;.. then the 20px is added to the original div.
Aside from that, I don't know what you're talking about without seeing it.
Instead of setting width to 100% I would use something like
#header {
height:30px; /* assumption */
top:0;
left:0;
right:10px; /* assumption */
}

Qt Stylesheets: How to apply style to menus? How to remove blue tinge around QTextEdit?

I am trying to make the menubar a gradient black colour and that works fine, except for the menu headings.
Here's the stylesheet i'm using:
QString styleSheet = "QMenuBar{background: qlineargradient(x1:0,x2:0,y1:0,y2:1,stop:0 #cccccc, stop:0.4 gray)} QStatusBar{background: qlineargradient(x1:0,x2:0,y1:0,y2:1,stop:0 #cccccc, stop:0.4 gray);color:white;} ";
this->setStyleSheet(styleSheet);
How do I apply the style to the meny headings too?
There is a blue tinge all around the QTextEdit which I can't get rid of. Is there a way to set it to black?
Thanks :)
I believe that the following website is a good resource for answering your question about the QT menubar issue you are having:
http://www.trinitydesktop.org/docs/qt4/stylesheet-examples.html#customizing-qmenubar
It gives a few code samples which should fully explain what you need to know. As for the blue tinge, I do not have a good idea on how to fix it - I haven't really seen that happen.
Best of luck.
This solved the problem for me:
QMenuBar::item {
background-color: transparent;
}
You can try using QMenuBar::item{}.
for aply color to the headings:
QMenuBar::item{
background-color: qlineargradient(x1:0,x2:0,y1:0,y2:1,stop:0 #cccccc, stop:0.4 gray)
}
For the blue tinge all around the QTextEdit:
QTextEdit{
border: 0
`

Resources