For some reason when I print my laptop's resolution width using Screen.getPrimary().getVisualBounds().getWidth()); I get the right result of 1920. But if I print the resolution width, change the resolution to 1680x1050 in Windows Settings, ask the thread to wait a minute, and print the resolution width again using the same code, I get 1920 instead of 1680! However, if I stop the project, set the resolution to 1680x1050, then compile and run the project, it does print 1680. In other words it seems that the project doesn't update the resolution if I change it while the project is running.
Below is some JavaFX code to illustrate what I mean. If I run the code below, watch it print 1920, change the resolution real quick, wait until the thread is done sleeping, then as described before it will still print 1920 instead of the new resolution width.
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
System.out.println(Screen.getPrimary().getVisualBounds().getWidth());
Thread.sleep(60000);
System.out.println(Screen.getPrimary().getVisualBounds().getWidth());
}
public static void main(String[] args) { launch(args); }
}
The problem has to do with polling the screen resolution on the same thread. If a new thread is created, told to sleep while the user changes the screen resolution in Windows Settings, and then told to print the screen resolution the screen, the resolution will reflect the updated resolution.
If the user ran the following and changed the resolution while the thread is asleep then the correct updated resolution would print to screen, unlike the code in the original question.
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
System.out.println(Screen.getPrimary().getVisualBounds().getWidth());
new Thread(){
public void run() {
try{
this.sleep(30000);
} catch (InterruptedException e) {
// ignore
}
System.out.println(Screen.getPrimary().getVisualBounds().getWidth());
}
}.start();
}
public static void main(String[] args) { launch(args); }
}
Another solution that also reflects an updated screen resolution is to use AWT. The following would print the correct updated resolution,
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
System.out.println(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
Thread.sleep(30000);
System.out.println(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
}
public static void main(String[] args) { launch(args); }
}
Related
This question already has answers here:
Create threads in java to run in background
(4 answers)
Closed 5 years ago.
This is my main method where I start my application. The JFrame loads successfully. When I add the WHILE-Loop part to do some background work where I work with some data to show on my JFrame my JFrame doesn't load correctly (see image below).
public static void main(String[] args) throws IOException {
if (Config.checkIfConfigExists() == true) {
/*
* Starten der Anwendung
*/
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main window = new Main();
window.frmServicenowHelper.invalidate();
window.frmServicenowHelper.validate();
window.frmServicenowHelper.repaint();
window.frmServicenowHelper.setVisible(true);
while (true) {
// the part that makes it error
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
} else {
Notifications.alertMSGConfig("Config not found. Create one?");
}
}
As you can see the JFrame freezes and shows its background.
I found out it has something to do with Threads and correct processing (I think I am using something at the wrong point) but I am unable to fix it myself.
Background knowledge:
I want to get a JSON-String from a URL (the methods for that are working - I want to call & show the results on the frame) every 5 minutes (therefore the while-loop).
EDIT:
I tried this which loads the frame correctly but makes the loop (which I need) useless:
while (true) {
Main window = new Main();
window.frmServicenowHelper.invalidate();
window.frmServicenowHelper.validate();
window.frmServicenowHelper.repaint();
window.frmServicenowHelper.setVisible(true);
break;
}
I found the solution:
I simply created a new Thread (background processing) using:
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
runYourBackgroundTaskHere();
}
};
new Thread(r).start();
//this line will execute immediately, not waiting for your task to complete
}
Source: Create threads in java to run in background
I changed my IDE from Eclipse to IntelliJ IDEA. The new one started complaining about my code.
public class Controller {
private OknoGlowne frame;
private MenuListener menuListen = new MenuListener(this);
private TabListener tabListener = new TabListener(this);
public OknoGlowne getFrame() {
return frame;
}
public Controller(){
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new OknoGlowne();
frame.setVisible(true); //error
frame.addMenuListener(menuListen);
frame.addTabListener(tabListener);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
So I commented this line. And add new line to constructor of UI frame.
public OknoGlowne() {
jPanel.setVisible(true);
}
App start but UI doesn't show any more. IDEA create frame in different way than Eclispe. I have to switch.
Main
public class Runner {
public static void main(String[] args) {
new Controller();
}
}
This doesn't really have anything to do with your IDEs. I bet if you ran it 100 times in eclipse, or from the command line, you'd get different results depending on how busy your system is.
The reason you aren't seeing the JFrame pop up is because you're using invokeLater() instead of invokeAndWait().
The invokeLater() method immediately returns, at which point you're in a race condition: will the event thread display the EDT first, or will the main thread exit first? If the main thread exits first, then your program will exit before any windows are shown.
To prevent this, you have to use invokeAndWait() instead of invokeLater().
I want to draw some graphs of statistics gathered during a simulation I coded in Java. I decided to try JavaFX, as it has some great graphing abilities. However, as I've never used it before, I'm not sure if it's even possible to add JavaFX capabilities to a project that wasn't set up to do this initially.
I've added the javafx library to my project, and copy pasted the JavaFX tutorial on line graphs at http://docs.oracle.com/javafx/2/charts/line-chart.htm (without the main function) to test if the graphs display properly.
They don't, however. I call the graph in my runsimulation function (which is called from a SwingWorker thread) with
LineChartSample.launch(new String());
and after running the program and not seeing any graph, I added a println after the call and noticed that the program doesn't ever reach it; i.e. it terminates on the call to LineChartSample.
Am I doing something wrong? Is what I'm trying even possible?
EDIT: A quick summary of what that part of the code looks like:
A JButton in class InputGUI calls
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
new AnswerWorker().execute();
}
public class AnswerWorker extends SwingWorker<Void, Integer> {
protected Void doInBackground() throws Exception
{
AMEC.runsimulation();
return null;
}
protected void done()
{
try {
JOptionPane.showMessageDialog(InputGUI.this, AMEC.unsuccesfulpercentage + "% of iterations had trucks that had to sleep over");
AMEC.unsuccesfulpercentage = 0;
}
catch (Exception e)
{
e.printStackTrace();
}
}
And AMEC.runsimulation calls
public static void runsimulation() throws IOException, InterruptedException {
...
LineChartSample.launch(new String());
}
I get the JDialogBox that AnswerWorker throws when it's done, but no graph, and whenever I test for a println after my LineChartSample.launch call, it never gets reached.
try
public static void runsimulation() throws IOException, InterruptedException {
...
LineChartSample.launch(LineChartSample.class, "");
}
for more information:
http://docs.oracle.com/javafx/2/api/javafx/application/Application.html#launch%28java.lang.String...%29
be aware that you shouldn't actually do it like this, because you can't call this code more than once in your applications lifetime. Instead, you should extract the code from the LineChartSample that builds the scene graph and use a JFXPanel to embed the scene graph into your swing application.
I'm using JavaApplicationBundle to set icon for my jar file, and now I am trying to remove my program from Dock.
I've set LSUIElement to 1, but that didn't worked until I added StartOnMainThread directive in Java section of Info.plist.
But - then problem appeared - GUI was locked up - just like the program is executing infinite loop or something. I've changed main() to be like this:
public static void main(String[] args) {
Thread queryThread = new Thread() {
public void run() {
new MainWindow();
}
};
queryThread.start();
}
but I can't see the JDialog - it won't appear even if the JavaApplicationBundle process is running (as this is background application now - could there be some step that I am missing to bring up the dialog?)
What can cause this problem? Does anybody have simple app bundle where java program is running without sitting in Dock - I've searched internet, but nothing appeared in my search results?
Thanks
Edit
After reading comments, I've tried what I already tried, but I forgot about it:
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run() {
new MainWindow();
}
});
}
In this case, application is running - but no GUI is shown. When I check Console Messages I see few of these:
*** -[NSConditionLock unlock]: lock (<NSCOnditionLock: 0x1347a0> '(null)') unlocked when not locked
*** Break on _NSLockError() to debug.
In JGame, the method setBGImage() is supposed to change the background image. This works when I'm setting the background image for the first time at the start of the initialization. However, when I call the same method later to change the background image, it seems to do nothing. What am I doing wrong?
Here's some example code to show you what I mean:
import jgame.*;
import jgame.platform.*;
public class Test extends JGEngine{
public static void main(String[] args) {
new Test();
}
public Test(){
super();
initEngine(640,480);
}
public void initCanvas(){
setCanvasSettings(10,6,64,80,null,JGColor.white,null);
}
public void initGame(){
setFrameRate(35,2);
defineMedia("media.tbl");
doTestBackground();
}
/* Demonstrates the bug */
void doTestBackground(){
new Thread(new Runnable(){
public void run(){
setBGImage("bg1");
/* If it's put here, then it works perfectly:
setBGImage("bg2"); */
try{
Thread.sleep(2000);
}
catch(Exception e){}
/* If it's put here it doesn't work!
The background SHOULD change here but it doesn't */
setBGImage("bg2");
}
}).start();
}
}
If you still want some answer. Here it is:
http://installsteps.blogspot.com/2010/10/jgame-java-game-engine.html
FYI, this setBGImage behaviour is a bug that was fixed in version 3.4. Since 3.4, setBGImage correctly updates the screen.
Perhaps you are running into problems with using the wrong thread? Generally, the AWT thread is used to change components (in the Swing framework).
Try using SwingUtilities.invokeLater(new Runnable() { public void run() { setBGImage("things");} } );