I have started to learn how to build JavaFX GUI app recently, and I have faced some problems with window scaling in JavaFX. When I set my Window scale to 125% my application seemed to be zoomed in even when I set the stage to show in fullscreen. However, when I set my Window scale back to 100%, the application is just show in the normal view. Please provide some solution on how can we make the application flexible to every DPI or screen scaling. Also, I have been using SceneBuilder and Intellij IDEA to create just only a Anchor Panel and a VBox with no important codes involed. I do not know much about JavaFX, and my English is far from perfect, so please ignor some stupid remarks that may have occured in this question.
100% Scaled Window
125% Scaled Window
Here is my code:
#Override
public void start(Stage stage) throws IOException{
Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("hello-view.fxml")));
Scene scene = new Scene(root);
Screen screen = Screen.getPrimary();
double dpi = screen.getDpi();
double scaleX = screen.getOutputScaleX();
double scaleY = screen.getOutputScaleY();
System.out.println("DPI: " + dpi + " - scaleX: " + scaleX + " - scaleY: " + scaleY);
stage.sizeToScene();
stage.setTitle("JavaFX_Practice");
stage.setScene(scene);
stage.setMaximized(true);
stage.show();
}
public static void main(String[] args) {
launch();
}
I faced that issue too. I have not found a solution in javafx directly, but I found a trick for my users who uses 125% window scale on Windows.
1. Right button click on desktop -> Display settings
2. Set scale to 100%
3. Do not close the settings window
4. Open javafx app
5. Go back to the settings window
6. Set your scale back
7. Close the settings window
This way a user of your app will be able to keep using his prefered scale, but your javafx app will be rendered on 100% scale until closed.
Related
I am making a view in SceneBuilder for my JavaFX application. I want my view to be maximized. How can I achieve this in SceneBuilder or the .fxml file?
You cannot do that using Scene Builder, since maximize or fullScreen are properties of the Stage and not the layouts set on the scene.
You can load and set the .fxml on the scene and later set the scene on the stage.
The following methods can be used on the stage :
setMaximized(boolean) - To maximize the stage and fill the screen.
setFullScreen(boolean) - To set stage as full-screen, undecorated window.
As you cannot maximize your view in fxml, you have to set the size of the stage to be maximized. There is no direct method for setting the size of the stage to be maximized in javafx 2 but there is another way you can do this. It is by manually setting the size of the stage. You can use this code:
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
primaryStage.setX(bounds.getMinX());
primaryStage.setY(bounds.getMinY());
primaryStage.setWidth(bounds.getWidth());
primaryStage.setHeight(bounds.getHeight());
This is the code that works for me
primaryStage.setMaximized(true);
it miximizes my window screen on the launch of the app.
I agree with Yemmy1000. primaryStage.setMaximized(true) works fine for me.
primaryStage.setScene(new Scene(root, 1800, 850));
primaryStage.setMaximized(true);
This code will go to width: 1800 and height:900 when restored down from maximum.
Two properties I found in stage which are useful.
First is setFullScreen(boolean) which will set your view to full screeb, but it will also hide all the taskbar and header of view.
Second is setMaximized(boolean) which will set you view to perfect like any other application view size.
I an using setMaximized(true) for my application.
I have a HTML editor in a Pane container 355px in width. The editor gets cut on the right side where the width overlaps the containing pane. How can I set the HTML Editor's width to a smaller width than that of the parent container?
Please note that I'm on JavaFx SceneBuilder 2 and dragging the width to something smaller than that of the Parent container just doesn't work.
While on Scene Builder 2.0 the HTML editor can't be resized, this just affects the preview (well, maybe it hiddens some other controls,...). If this is really a problem, instead of adding the HTML editor there, just place a container with a proper fx:id and later on the controller add the editor as a child of that container.
Assuming you have the editor added on your FXML, and the width of your scene is 355px, as you say, the first preview of the application will have the toolbars cut, and there won't be any overflow button until you resize the window. Only then, the toolbars will be resized and the overflows will appear.
To overcome this problems and let the editor be resized right after the application is launched, without the manual resize, the workaround is to find the toolbars of the editor, and resize them.
#FXML private HTMLEditor htmlEditor;
#Override
public void initialize(URL url, ResourceBundle rb) {
Platform.runLater(()->{
htmlEditor.lookupAll("ToolBar")
.forEach(node->((ToolBar)node).setPrefWidth(355));
});
}
Note the hardcoded width value, for the sake of simplicity.
My application on startup creates a sort-of "Splash Screen" with quick access buttons to Open, New, etc... This splash window is placed in the middle of the screen, and the application main window is placed behind it.
Here is the code to do it:
void MainWindowButtonDialog::showMe()
{
setModal(false);
setWindowFlags(
#ifdef Q_WS_WIN
Qt::SplashScreen |
#endif
Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
QDesktopWidget *d = QApplication::desktop();
QRect t = d->availableGeometry(this);
move(mapToGlobal(this->geometry().topLeft()).x() + t.center().x() - width() / 2,
t.center().y()- height() / 2);
show();
raise();
}
However I have some problems when the application runs on a two monitor setup. What happens is the following: the Splash screen regardless where the application starts, is created always on the first screen. So if the Window manager decided to open the application on the second screen the splash screen will be far far away on the middle of the first screen... Which is pretty ugly :(
Any idea how can this be fixed?
If you add the splash screen as a child to the MainWindow, it should have its initial coordinates set such that it displays right on top of its parent.
Try calling availableGeometry() not with a widget as parameter, but with a screen number. Something like
int screen = d->primaryScreen();
QRect t = d->availableGeometry(screen);
I am Using Qt 4.8
I am trying to bind mouse cursor to the center of my application.
If application is in fullscreen it works with following code
int middleX = QApplication::desktop()->width() >> 1;
int middleY = QApplication::desktop()->height() >> 1;
QPoint newMousePos;
newMousePos.setX(middleX);
newMousePos.setY(middleY);
QCursor::setPos(newMousePos);
and it works.
But how do I do this when application is not fullscreen mode?
I tried few codes from the web but I could not found them working. I understand that I need to get current geometry of window i.e. current window position w.r.t. monitor and width and height of window.
but what are the functions to be used for that?
Thanks in advance
All it takes is this:
QCursor::setPos(geometry().center());
This will put the cursor in the dead center of your application window main widget, agnostic of the size and position of the window on the screen.
I am a newbie to Qt and facing issue in my application. So here is what I am trying to do.
I have a class with QWidget as parent. This class has a grid layout on it. I set this widget as a central widget to main window. (this thing worked fine though this widget is not centered on Main Window.)
Now I wanted to rotate this widget in 90 degrees so that it can bee shown on device in landscape mode. So I created a graphics view and added this widget to it. (created a scene added widget to that and assigned scene to view.) then this graphics view was rotated and made central widget. this worked amazingly and it was very well centered, looked good on device as well.
But in final integration we want to have all QWidgets so Graphics View is not an option. To tackle this I created a Qwidget member inside my class. applied the layout to it. added this widget to graphicsView and my class was made parent to it.
This also works but has the similar issue I faced in first step, it sits in the top left corner of MainWindow and does not adjust to center. To make things even worse, when deployed on device it was not applied to entire screen. Widget was sitting in some part of top left area and had scroll bars to it! I even tried the set Window State to maximized but had no effect on it.
Here is what I tried
The widget is created inside my class and been added to Graphics View. this view has my class as parent and it will be rotated by using rotate api.
m_gridContainer = new QWidget();
m_gridContainer->setAutoFillBackground(true);
m_gridContainer->setPalette(blackPalette);
m_gridContainer->setLayout(m_grid);
m_gridContainer->setMinimumSize(480,265);
m_scene = new QGraphicsScene(0, 0, 480, 265);
m_window = new QGraphicsView(m_scene,this);
m_scene->setBackgroundBrush(brush);
m_window->setAlignment(Qt::AlignCenter);
m_scene->addWidget(m_gridContainer,Qt::Widget);
To use it from main Window
m_window = new CMyWidget(label, m_txtBox->text());
m_window->getRotatedWidget(90);
setCentralWidget(m_window);
I tried whatever I can but this widget is not being shown full screen (in just a small area) and still have scroll bars to it. I have no idea what exactly is happening there.
m_gridContainer being a graphics item part of a graphics scene, it doesn't receive the resize events of you main window.
You have to handle the resizeEvent() on your CMyWidget and adjust the size of your m_gridContainer accordingly, e.g.
void CMyWidget::resizeEvent ( QResizeEvent * event )
{
m_gridContainer->resize(event->size());
}
BTW, if you are handling the rotation for use on a mobile device, it is managed by Qt itself (by simply resizing your main window). You don't have to do it in your code (you'll actually end up with a widget looking like it has been rotated twice).