Swing window doesn't appear after getting input from Console - java

I have a simple swing window in order to load files.
This appear in the class analyzedLoad, in a function analyzedloads()
JFileChooser fc = new JFileChooser();
JFrame frame = new JFrame();
int returnVal = fc.showOpenDialog(frame);
frame.dispose();
if (returnVal == JFileChooser.APPROVE_OPTION) {
Where I apply the function without get an input from the user, all fine. But where I get an input from the user, in this way:
int al= 0;
Scanner in = new Scanner(System.in);
System.out.println("for choose file, press 1; for save, press 2");
al= in.nextInt();
if (al== 1){
analyzedLoad.analyzedloads(); // A static function which open the swing window
The window doesn't appear, and the process continue to run, without doing anything.
Thanks.

Becaue "a scanning operation may block waiting for input," I suspect you're blocking the event dispatch thread. Instead use a File Chooser to obtain a file reference.

Try adding a second mywindow.setVisible(true) after the console operation.

You might want to try to declaring the analyzeLoad variable as final and do something like so:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
analyzedLoad.analyzedloads();
}
}
or since the method is static:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
YourClass.analyzedloads();
}
}
That being said, without more code we can only speculate.

Related

Java: executing a showOptionDialog in another Thread and then exiting from it makes closing the entire application

I implemented the following code to run a dialogue event with swing in Java in another thread while my program does things.
public class othermain implements Runnable {
public void displayDialog() {
JPanel panel = new JPanel();
JLabel label = new JLabel("Insert text");
TextField text = new TextField(15);
panel.add(label);
panel.add(text);
String[] options = new String[]{"Cancel", "Ok"};
int option = JOptionPane.showOptionDialog(null, panel, "Ask",
JOptionPane.NO_OPTION, JOptionPane.NO_OPTION,
null, options, options[1]);
if (option == 1) {
System.out.println(text.getText());
}
}
#Override
public void run() {
this.displayDialog();
}
public static void main(String[] args) throws IOException, InterruptedException {
othermain a = new othermain();
//a.load();
Thread th = new Thread(a);
th.start();
while (true) {
System.out.println("I should never exit from the cycle");
Thread.sleep(3000);
}
}
}
This works but the problem is that on macOS once opened the dialog box, the icon of the program remains in the dock, so when I try to close it my entire application gets closed even if the dialogue has been executed in another thread. In other words, I expected that only the thread where the dialogue has executed should have closed after pressed ok button or cancel button.
How can I avoid the behaviour described and making the icon hidden, showing only the message box and not the icon of the program too so that it cannot be closed manually? Or if this cannot be avoided when quitting the app manually should be closed only the thread that is executing it and not the entire application.
Current Output:
I should never exit from the cycle
I should never exit from the cycle
I should never exit from the cycle
text
I should never exit from the cycle
Process finished with exit code 0 //When I quit the application from the dock
For those who are wondering about this problem, I solved with this trick.
System.setProperty("apple.awt.UIElement", "true");
java.awt.Toolkit.getDefaultToolkit();
Main updated:
//Code for messagebox is the same
public static void main(String[] args) throws IOException, InterruptedException {
System.setProperty("apple.awt.UIElement", "true");
java.awt.Toolkit.getDefaultToolkit();
othermain a = new othermain();
a.displayDialog();
//Thread th = new Thread(a); //You don't need to run in a separated thread now
//th.start();
while (true) {
System.out.println("I should never exit from the cycle");
Thread.sleep(3000);
}
}
Special thanks to the user who said me to "follow the Java conventions" without adding a single additional word about the problem. He helped me a lot, just like so many users who answer like him.

Netbeans Module: open JFrame on button click

I am coding a module for Netbeans where I have a button that when clicked will open a JFrame.
This is the action listener class of the button:
// ... (package and imports)
#ActionID(
category = "File",
id = "org.myorg.readabilitychecker.ReadabilityActionListener"
)
#ActionRegistration(
iconBase = "org/myorg/readabilitychecker/google.png",
displayName = "#CTL_ReadabilityActionListener"
)
#ActionReference(path = "Toolbars/File", position = 0)
#Messages("CTL_ReadabilityActionListener=Readability")
public final class ReadabilityActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JFrame readabilityFrame = new ReadabilityFrame();
readabilityFrame.setVisible(true);
}
}
In the JFrame I basically have:
public static void main(String args[]) {
* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ReadabilityFrame().setVisible(true);
}
});
}
It also has some other automatically generated code, but nothing important.
When I run the application, the button appears in the toolbar, but when I click it, the JFrame doesn't open.
I tried checking if a print inside the actionPerformed() method would show in the output terminal and it does, so I guess that I am missing something while calling the JFrame.
Can anyone give me a hint on where the problem is?
I think the issue is with the object creation of your frame. Try
ReadabilityFrame readabilityFrame = new ReadabilityFrame();
readabilityFrame.setVisible(true);
Hope it helps.
I found where was the problem.
The method initComponents() automatically generated had the line setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); and it was always throwing an exception.
I just changed EXIT_ON_CLOSE to DISPOSE_ON_CLOSE, defined the frame in a different way and now, the problem disappeared.

Disable non-SWT window while SWT dialog showing

I'm mixing SWT with a non-SWT window (formerly an AWT window but I'm now using a native GLFW window). When I call fileDialog.show(), I would like the file dialog to get the full application context, where it is drawn on top of the existing non-SWT window, and the non-SWT window cannot be clicked. i.e., the same behavior as when using AWT with an AWT FileDialog.
However, when I show the SWT FileDialog, it still allows me to click the other window and bring that window to front.
Here's how I set up my app. I'm using LWJGL 3 (via LibGDX), which in turn creates a native window through a GLFW binding. And this is part of the reason I'm using SWT...GLFW does not support AWT or Swing.
public static void main (String[] arg) {
//...
new Lwjgl3Application(app, config); //starts an OpenGL loop in a native GLFW window
prepareSWT();
}
static void prepareSWT (){
swtThread = new Thread(new Runnable (){
#Override
public void run() {
swtDisplay = new Display();
swtShell = new Shell(swtDisplay);
while (!swtDisplay.isDisposed()) {
if (!swtDisplay.readAndDispatch())
swtDisplay.sleep();
}
swtDisplay.dispose();
}
});
swtThread.start();
}
public static void showSWTFileChooserDialog (final FileChooserResult fileChooserResult){
swtDisplay.asyncExec(new Runnable() {
#Override
public void run() {
final org.eclipse.swt.widgets.FileDialog fileChooser =
new org.eclipse.swt.widgets.FileDialog(swtShell, SWT.OPEN);
fileChooser.open();
String filename = fileChooser.getFileName();
if (filename == null || filename.equals("")){
fileChooserResult.file = null;
} else {
fileChooserResult.file = new File(fileChooser.getFilterPath(), filename);
}
fileChooserResult.ready = true;
}
});
}
I'm at a loss for how to get the FileDialog to be forced on top of the non-SWT window.
Setting the SWT.SYSTEM_MODAL style on the Shell will block input to all applications' windows on the system.
http://help.eclipse.org/luna/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html#SYSTEM_MODAL

java garbage collecting in dialog

*I'm now encountering a very strange java GC problem when I trying to make a button in a JFrame, and when I click the button, it display a JDialog which need to deal with and show some images and need nearly 200M memory. But the problem is when I close the dialog and reopen it, sometimes it cause java.lang.OutOfMemoryError. (not every times)
Trying to solve the problem, I simplify this problem and make some experiment, which cause me more confused.
The Code I used in my " experiment " is showed below.
When I click a button in a frame, I allocate 160M memory for an integer array, and display a dialog, But If I close the dialog and reopen it, OutOfMemoryError appears. I adjusting the code and the result is:
If I don’t create the dialog and show it, no memory problem.
If I add a windowsCloseListener which invoke System.gc() to the dialog, no memory problem.
If I invoke System.gc() in the run() method, memory problem shows.
public class TestController {
int[] tmp;
class TDialog extends JDialog {
public TDialog() {
super();
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
// If I uncommment this code, OutOfMemoryError seems to dispear in this situation
// But I'm sure it not a acceptable solution
/*
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("windowsclose");
TDialog.this.dispose();
System.gc();
}
});
*/
}
}
TDialog dia;
public void run() {
// If I do System.gc() here, OutOfMemoryError still exist
// System.gc();
tmp = new int[40000000];
for (int i = 0; i < tmp.length; i += 10)
tmp[i] = new Random().nextInt();
dia = new TDialog();
dia.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
final JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(200, 200);
JButton button = new JButton("button");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
TestController controller = new TestController();
controller.run();
controller = null;
}
});
frame.add(button);
frame.setVisible(true);
}
});
}
}
I’ve read about a lot articles which describe how java’s GC work. I think if java trying to allocate some space in the heap and it do not have enough free space, java will do gc, and if a object can’t be accessed from the gc root through “GC graph”, in which a edge from u to v represent u have a reference to v, root is something in the a thread working stack, or native resources, It’s useless and qualified to be collected by java’s GC.
Now the problem is When I click the button and trying to create an Integer array, the Integer array I create last time is certainly qualified to be collected by java’s GC. So why it caused Error.
Apologize for Such A Long Description…I don’t have much tactics in asking problem, so just trying to make it clear.
Besides, The parameter I used to start jvm is “ java –Xmx256m”
You're allocating new int[40000000] before while tmp still holds the reference to the last int[40000000].
The order of operation in an expression like tmp = new int[40000] is:
new int[40000]
Assign the reference to the array to tmp
So in 1. tmp is still holding the reference to it's last value.
Try doing:
tmp = null;
tmp = new int[40000000];
Try this:
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
public class TestController {
private JFrame frame;
int[] tmp;
public TestController(JFrame frame) {
this.frame = frame;
}
public void finish() {
if (dia != null) {
dia.dispose();
}
tmp = null;
}
class TDialog extends JDialog {
public TDialog() {
super(frame, "Dialog", true);
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
}
}
TDialog dia;
public void run() {
tmp = new int[40000000];
for (int i = 0; i < tmp.length; i += 10)
tmp[i] = new Random().nextInt();
dia = new TDialog();
dia.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
final JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(200, 200);
JButton button = new JButton("button");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
TestController controller = new TestController(frame);
controller.run();
// controller = null;
System.out.println("here");
controller.finish();
}
});
frame.add(button);
frame.setVisible(true);
}
});
}
}
where you clean out both the dialog and its data in the finish() method. The dialog again should be modal for this to work, else you'll need a WindowListener.
You state in comment:
But would you tell me what's wrong in my code? and what's the meaning of "be modal". I've read the api of Dialog's setModal method in java doc. it means " whether dialog blocks input to other windows when shown", seems not the same thing as you referred.
A modal dialog is in fact one that blocks input from the calling window, and in fact freezes code flow from the calling code as soon as the dialog is visible. Code then resumes once the dialog is no longer visible.
There's no magical solution to your problem with the dialog being modal per se, but it allows us to know exactly when the dialog is no longer visible -- the code resumes from where the dialog was set visible, and thus allows us to call clean-up code at this point. Here I call the finish() method.
If you don't want the dialog to be modal, then you'd need a WindowListener and listen for the dialog being closed, and then do your finish method call there.
All my code does is make sure that the int array is available for GC'ing before you create a new int array.

Swing jfilechooser blocking other frames after passing null

I want my jfilechooser to display without blocking parent but i tried everything and still it is blocking parent. Any Solution....
public class main_class {
public static void main(String[] args) {
JFrame parent_frame = new JFrame("PARENT");
if (parent_frame != null) {
parent_frame.setBounds(50, 50, 500, 500);
parent_frame.setVisible(true);
parent_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = chooser.showDialog(null, "Ok");
}
}
}
By default, showDialog will use a modal dialog.
JFileChooser is simply based on a JComponent, so, so long as you don't mind that your code won't block, you could add the JFileChooser to a frame/dialog that you can yourself.

Categories