JFileChooser.showSaveDialog() not showing up - java

I'm using the Eclipse IDE, and I'm trying to call showSaveDialog(null) from another method which is in turn called from main, but nothing happens when I call it.
Main:
public static void main(String[] args) {
Main main = new Main();
main.pt = main.new PlayThread();
main.generateSound(getSamples(2), 500);
main.play(main.sound, 1);
if(new Scanner(System.in).nextLine().equals("save")){
System.out.println(main.save());
}
}
All the code before calling main.save() works fine, and main.save() starts like this:
public boolean save(){
System.out.println("Calling save");
try{
String saveName = getSaveTo("C:/");
System.out.println("I'm here now");
while getSaveTo() looks like:
public String getSaveTo(String def){
JFileChooser chooser = new JFileChooser();
System.out.println("Save called");
//chooser.setCurrentDirectory(new File(def));
int resp = chooser.showSaveDialog(null);
if(resp == JFileChooser.APPROVE_OPTION){
return chooser.getSelectedFile() + ".wav";
}else return null;
}
After it executes the first few functions in main, I type in 'save', and the console prints:
Calling save
Save called
But the dialog never opens, and it never says "I'm here now." Why's that? Also, when I typed
new JFileChooser().showSaveDialog(null)
That shows up fine, but in my save() method, it won't. Any ideas why?
EDIT:
Here's a condensed program which has the same problem:
package com.funguscow;
import java.util.Scanner;
import javax.swing.JFileChooser;
import com.funguscow.Main.PlayThread;
public class Test {
public static void main(String[] args) {
Test main = new Test();
Scanner scan = new Scanner(System.in);
boolean should = scan.nextLine().equals("save");
scan.close();
if(should){
System.out.println(main.save());
}
}
public String getSaveTo(String def){
JFileChooser chooser = new JFileChooser();
System.out.println("Save called");
//chooser.setCurrentDirectory(new File(def));
int resp = chooser.showSaveDialog(null);
System.out.println("Save called");
if(resp == JFileChooser.APPROVE_OPTION){
return chooser.getSelectedFile() + ".wav";
}else return null;
}
public boolean save(){
System.out.println("Calling save");
try{
String saveName = getSaveTo("C:/");
System.out.println("I'm here now");
if(saveName == null)return false;
}catch(Exception e){}
return false;
}
}
You can run this yourself if you'd like to examine it more.
This MCVE may be enough to reproduce the problem, and it seems that the Scanner that is initialized with System.in is interfering with the JFileChooser's ability to display an open file dialog, even when care is taken so that the file chooser is run on the Swing event thread:
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
public class Test3 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter something and press Enter: ");
scan.nextLine();
scan.close();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showOpenDialog(null);
}
});
// JFileChooser fileChooser = new JFileChooser();
// int result = fileChooser.showOpenDialog(null);
}
}

On Windows, Scanner interferes w/ JFileChooser -- why?
tl;dr strictly speaking, it's the user that interferes with JFileChooser by using a Scanner expecting input from system console (System.in). Either way, it's just about the windowing focus and Java's Dialog modality.
Explanation
The bug happens because the dialog appears in the background because requiring nextLine() on the Scanner on System.in essentially forces the user to switch the focus to the console. The application loses the focus, so the Dialog appears in the background. The code doesn't "hang" by itself, it just waits until the user selects a file or does any other dialog option - until he does, it does nothing. If there's some kind of OS issue blocking the background window from displaying/working properly (e.g. some "always in foreground" window obstructing it) - well, then your app is hanging around, waiting for input event that's not likely to happen due to the fact nobody can use the input dialog itself.
For anybody affected - the Dialog is there. I've tested this code on Java 8 on Windows XP, Java 8 on Windows 7 and some other configurations - in all of the cases the Dialog was created, possibly hidden in the background of the desktop due to focus loss. It's not shown in the taskbar, but it does show in the Alt+Tab list. Try running it outside of IDE, they tend to do strange things with app focus when console input is required (due to "real" console getting redirected to IDE output window etc). Feeding it data through the < pipe instead of using "real" console will propably prevent this behaviour from happening too.
As far as my imagination goes, workarounds would require either forcing the focus to the app's Frame or creating an on-the-fly always-on-top Frame to keep the focus where it should be (on the Dialog). Since the Dialog of JFileChooser (or any other similar Dialog to speak of) is itself a fire-and-forget object, it's kind of difficult to force it to foreground without specifying a parent. Therefore, I think that the easiest way to go, for parent-less Dialogs is to just use code like:
Exemplary solution
Scanner scan = new Scanner( System.in );
System.out.print( "Enter something and press Enter: " );
scan.nextLine();
scan.close();
SwingUtilities.invokeLater( new Runnable() {
public void run() {
JFrame jf = new JFrame( "Dialog" ); // added
jf.setAlwaysOnTop( true ); // added
JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showOpenDialog( jf ); // changed
//System.out.print( "result: " + result );
jf.dispose(); // added
}
} );
or, if you prefer to interfere with the Dialog itself, by subclassing it and applying the aforementioned setAlwaysOnTop(true) in the createDialog() call (note that createDialog() has protected access in JFileChooser, making it impossible to change the behaviour without extending the class, similarly to all the Dialog related stuff there), e.g.
int result = new JFileChooser() {
#Override
protected JDialog createDialog( Component parent ) throws HeadlessException {
JDialog jDialog = super.createDialog( parent );
jDialog.setAlwaysOnTop( true );
return jDialog;
}
}.showOpenDialog( null );
or even by creating a regular utility class extending JFileChooser doing just that.
NB switching to/fro EDT does nothing here, as this is not threading related by itself (though the multithreading of UI is the source of the problem, kind of).

I believe the answer by vaxquis to be quite correct in that the chooser is being shown, just behind the current window as it retains focus. It's all to do with Dialog modality and which windows take precedence over others on the various OS's (possibly in combination with some IDE's).
I have found the following workaround - keeping all your other code exactly the same, extend JFileChooser and then use MyFileChooser instead of JFileChooser in the getSaveTo() method. I've tested on my setup (Windows 8, Java 7). YMMV
class MyFileChooser extends JFileChooser {
protected JDialog createDialog(Component parent) throws HeadlessException {
JDialog dialog = super.createDialog(parent);
dialog.setAlwaysOnTop(true);
return dialog;
}
}
This allows you to use the original construction (.openSaveDialog(null)) and has the nice added advantage that you can set up other features of the dialog box in your overridden createDialog() method should you wish.
EDIT
I see vaxquis has appended this method to their answer now too, so that answer is, I would say, canonical.

Related

Java: How to wait for the listener to execute the next line?

I have a problem because I have the next code in my main class:
SelectCalculatorWindow selectCalculatorWindow = new SelectCalculatorWindow();
CalcWindow calcWindow;
if (selectCalculatorWindow.getOption() == SelectCalculatorWindow.BASIC_OPTION) {
calcWindow = new CalcWindow(0);
} else if (selectCalculatorWindow.getOption() == SelectCalculatorWindow.PSEUDOSCIENTIFIC_OPTION) {
calcWindow = new CalcWindow(1);
}
And, in other class (SelectCalculatorWindow), I have this:
public SelectCalculatorWindow() {
initComponents();
instantiateListener();
}
private void instantiateListener() {
acceptBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(basicCalculatorRbtn.isSelected()) {
setOption(BASIC_OPTION);
} else if (pseudoscientificCalculatorRbtn.isSelected()) {
setOption(PSEUDOSCIENTIFIC_OPTION);
}
setVisible(false);
}
});
}
So, I want that condition sentences that I wrote in the main class execute only if user click the button, and I don't know how to do it
You haven't posted a valid minimal reproducible example program yet, and so I can only guess, but having said that, my guess is that SelectCalculatorWindow creates and displays a JFrame which is a non-modal application window, which is not what you want. Instead you will want to display a modal child-window, or dialog, such as a modal JDialog. When you use this, it pauses application code flow in the calling code until the dialog has been dealt with, and so allows your program to pause waiting for the user to make their selection, and then resume the code once the selection has been made.
A JOptionPane is an example of a type of modal dialog, but using a JDialog, you can create windows as varied and flexible as a JFrame, but with the advantages noted above.

Calling JFileChooser twice in invokelater causes program not to exit

I am writing a program to collect information from two text files to add to tables in a database. In order to permit the user to select his own files I created a non-static method called chooseFile() that uses JFileChooser class to present a showOpenDialog (I've also tried it as a static method with the same results. If this sounds like I'm guessing, you're correct - I'm only so-so with programming).
My understanding is that calls to Swing classes in main() should be done using invokelater. This all worked fine (the JVM exits successfully) for one call to chooseFile(), but when I added a second call to chooseFile() the JVM keeps running indefinitely. However, the program exits normally with both calls to chooseFile() if I do so without using invokelater. Adding System.exit(0) after the second call in invokelater also allows the program to exit normally.
From what I have been able to gather, the program won't exit until all the (non-daemon) threads are closed. However, I thought that the purpose for using invokelater was to push all non-thread safe Swing related activities onto the EDT. Is using System.exit(0) the best practice here or is there something else I should know about?
Here is my SSCCE:
package ptMngr;
import java.io.IOException;
import java.nio.file.Path;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
public class ParticipantManager {
private Path chooseFile() throws IOException{
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("Text Files", "txt","csv");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: " +
chooser.getSelectedFile().getName());
}
Path path = chooser.getSelectedFile().toPath();
return path;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args){
// ParticipantManager pm = new ParticipantManager();
// try {
// pm.chooseFile();
// pm.chooseFile();
//
// } catch (IOException ex) {
// Logger.getLogger(ParticipantManager.class.getName()).log(Level.SEVERE, null, ex);
// }
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
ParticipantManager pm = new ParticipantManager();
try {
pm.chooseFile();
pm.chooseFile();
System.exit(0);
} catch (IOException ex) {
Logger.getLogger(ParticipantManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
}
In your call to showOpenDialog(null) you pass null as the parent component for the JFileChooser. It's been some time since I worked with JFileChooser, but I seem to remember, that a "magic" JFrame may be constructed, when null is passed in. It may be possible, that in this use case two "magic" JFrames are created and they prevent termination.
You may want to try to create a JFrame which serves as parent for both JFileChoosers so it does not create the automatic frames.
EDIT:
My first take would be this:
public static class ParticipantManager {
JFrame frame;
private JFrame getFrame() {
if (frame==null) {
frame = new JFrame();
frame.setSize(600, 400);
frame.setLocationRelativeTo(null);
// frame.setVisible(true); // <---- worked for me without this call too
}
return frame;
}
private void close() {
frame.dispose();
}
private Path chooseFile() throws IOException{
JFrame f = getFrame();
...
int returnVal = chooser.showOpenDialog(f);
...
...
pm.chooseFile();
pm.chooseFile();
pm.close(); // <----- close the frame
...

Program displays filenames in a JTextArea as it walks the directory tree but I don't know how to stop it via a keypress

There are two windows: a GUI for user input and Output window for list of filenames found. Execution must be user-stoppable via a keypress and must leave both windows open because the program processes subdirectories, so it can run a long time, possibly stepping thru 100_000 files, either producing tons of output or none at all, depending on how user's filename pattern matches files encountered in the selected starting node.
Here's my question:
How do I look for a keypress (e.g., ESC or CTRL-C) to allow user to terminate? (Clicking red X isn't an option since that closes windows; user needs to see what's been found before termination. Doing so does not close either window anyway since all buttons are disabled once tree walk begins.)
I've tried putting keyListeners in several places, but once the "Start" button is clicked, all the swing components are disabled.
This seems like such a common situation that I'm surprised I can't find any textbook, thread, or Google info that directly answers the question. So I'm afraid it's not gonna be at all easy. That would be no surprise. I may have found a clue here but I can't get it to compile and the link contained there doesn't lead to that code snippet.
The search begins when the Search button is clicked:
private void jbSearchActionPerformed(ActionEvent evt) {
SearchyGUI.doIt();
}
The doIt() method walks the directory tree by an extension of SimplefileVisitor:
public class OverriddenFileVisitor extends SimpleFileVisitor<Path> {
...
}
public static void doIt(){
try {
visitor = new OverriddenFileVisitor();
info.setVisible(true);
Files.walkFileTree(SearchyGUI.p , visitor);
}
catch (Exception e) { }
}
}
Output is written to jTextArea1 via the report() method:
public static void report(String s){
Output.jTextArea1.append(s + "\n");
}
This is done primarily in the visitFile() method of SimpleFileVisitor:
public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException {
report(foundkt + "--" + f.getFileName().toString());
return FileVisitResult.CONTINUE;
}
Here's the main class:
public class SearchyGUI {
static Output info;
static Path p ;
static FileVisitor visitor ;
static GUI gui
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
gui = new GUI();
gui.setVisible(true);
}
});
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
info = new Output();
}
});
}
The problem is you are hogging the GUI thread, so the GUI thread can't process any events originating from the user.
You need to create a new Thread and do the work in there. Then, to display output from that thread, you can use SwingUtilities.invokeLater or something like that.
The Key Bindings API is probably the best choice for monitoring key strokes.
I would also add a [Cancel] button to the UI, which shared the same action...
public class CancelAction extends AbstractAction {
public CancelAction() {
putValue(NAME, "Cancel");
}
public void actionPerformed(ActionEvent evt) {
// Perform the cancel operation...
}
}
Then some where else in your code...
CancelAction cancelAction = new CancelAction();
JButton cancelButton = new JButton(cancelAction);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "Cancel");
am.put("Cancel", am);
Now the other problem you're going to have is the fact that you look like you are running a long running task within the context of the Event Dispatching Thread. This is going to prevent your program from being able to update the UI or allow the user to interact with the UI.
If you need to make changes to the UI (ie, show the output of the file processing), you should try a SwingWorker.
The main reason being is that it allows you to execute the long running task in another thread, but provides the mechanism for re-syncing updates back to the EDT, where it is safe to make changes to the UI.
Take a look at Concurrency in Swing for more details.
Regardless of which direction you take, you're going to need to supply a reference to the object that is carrying out the task and provide some kind of "cancel" flag, which the "task" object will need to monitor
The way I had left this program last night was unsatisfactory since Exit resulted in user not being able to see the output so far displayed (it could be useful). So I established window listeners and used the close event to set a boolean aborted to true to prevent further output to the window, but the thread kept running, which led to intermittent problems if another search was started before the thread ended.
Here's how I fixed it.
The FileVisitor interface has 4 methods to implement to walk the tree--two for each file visited, two for each directory. Each returns a FileVisitResult which is normally FileVisitResult.CONTINUE. By changing the return value to FileVisitResult.TERMINATE in the file visitor thread, it terminates appropriately! That is, I set a flag that the thread could check and take appropriate action, which is exactly what #MadProgrammer suggested.
public static FileVisitResult disposition = FileVisitResult.CONTINUE;
...
private static void report(String s){
if (! aborted)
try{
Output.jTextArea1.append(s + "\n");
}
catch (Exception e){
aborted = true ;
disposition = FileVisitResult.TERMINATE;
}
}
...
#Override
public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException {
f1 = new File(f.getParent().toString() + "\\" + f.getFileName().toString());
long filesize = f1.length();
report(f.getFileName().toString() + "\t found in " + f.getParent().toString());
return disposition;
}
I am one happy camper! Thank you BOTH for your ideas and input.
Well, I made it stop. I guess if you wander the woods long enough you'll find a gnome. I read Robin's hint last week and sort of gave up. Then I read some more and more. And then more. But Robin assured me that gnomes DO exist in these here woods!
The code I used was a modification of some I found for a MatLab/Java app. (Why'd I even look at it?? Best apparent Google hint.)
I made the "file visitor" (directory tree walker component) startable as a thread as Robin advised:
public class OverriddenFileVisitor extends SimpleFileVisitor<Path> implements Runnable{
// ................................................................^^^^^^^^^^^^^^^^^^^
In doIt() I made a couple of changes, moving the lines that process the directory to the now-runnable class and started the file visitor as its own thread in doIt():
public static void doIt(){
try {
new OverriddenFileVisitor().startTh();
//^^^^^^^^^^
//(moved) Files.walkFileTree(SearchyGUI.p , visitor);
...
I added the new method in the previous line to OverriddenFileVisitor class: (This is the main part of the MatLab/Java code that made sense to me so I used and modified it.)
public void startTh() {
Thread t = new Thread(this);
t.start();
}
And I inserted the overridden run() method for the class:
public void run() {
try {
Files.walkFileTree(SearchyGUI.p , this); // Used to be in doIt().
}
catch (IOException ex) { }
}
It ran and gave correct results and stopped when I hit Exit button, which "became" enabled after revising the file visitor to run in its own thread, which is what #Robin Green was saying. I almost feel like I know what I've done.
P.S. Note that I already was able to get my output via invokeLater()--last several lines of original question.
It's not finished but it's much more satisfactory.

Creating a standalone gui console in java that extends prompt based application

I have several little applications which uses the standard console for retrieving user input and for showing messages troughtout System.in and System.out.
Now i would like to realize some Swing based class which called from these applications, it shows a frame with 2 text area, one for input (so associated to System.in) and another one (not editable) that shows the messages (hence associated to System.out). Actually i have implemented all, (actually creating a simple swing based gui and launching it from the event dispatcher thread is not so complex, the same for exporting all as a jar and including it as a library in the original project). The only problem I have so far, which took me here is about the swapping of the standard System.in and System.out to some custom ones which are associated with the 2 JTextArea. Actually checking some solutions online, I ended up with this few lines of code:
I use 2 PipedInputStream and a PrintWriter:
private final PipedInputStream inPipe = new PipedInputStream();
private final PipedInputStream outPipe = new PipedInputStream();
private PrintWriter inWriter;
then i swap the streams
System.setIn(inPipe);
System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));
inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);
for retrieving the data from the outPipe, I use a SwingWorker whose doInBackgroud method troughtout a Scanner reads the lines from the outPipe and publish them in order to append these string of lines in a not editable JTextArea.
Meanwhile a keyListener checks for VK_ENTER click in order to get the text from the JTextField used as prompt, once this happens, the text is displayed using the System.out itself, and it effectively appears in the previous JTextArea, hence the SwingWorker described above works, and then I wrote the same line of text in the inWriter (the PrintStream object associated to the pipe related to the System.in) so the line should be available to be read from Reader objects which are present in the original application.
Unfortunately this is the only part of the code which does not work. Indeed, once i launch the new gui console, then change the streams, the original application will show only the text it prints on System.out, but when it wants to read the text the user writes, for instance troughtout either a BufferedReader or a Scanner object, nothing happens, as if the the in stream was empty.
I think this is due to the Scanner in the SwingWorker doInBackground method since when it reads the next line on the outPipe, it cleans the stream itself too. Any idea to get rid of this problem? I know i could write new methods for handling input and output but i would like to keep this not-intrusive approach, so without editing the original code, a part the creation of the gui Console object in the original application main method. Thanks in advance.
Update 1
This is the Console class, all is done here
public class Console extends JFrame implements KeyListener
{
private JTextField prompt;
private JTextArea log;
private final PipedInputStream inPipe = new PipedInputStream();
private final PipedInputStream outPipe = new PipedInputStream();
private PrintWriter inWriter;
public Console(String title)
{
super(title);
System.setIn(inPipe);
try
{
System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));
inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);
}
catch(IOException e)
{
System.out.println("Error: " + e);
return;
}
JPanel p = new JPanel();
p.setLayout(null);
log = new JTextArea();
log.setEditable(false);
log.setBounds(10, 10, 345, 250);
p.add(log);
prompt = new JTextField();
prompt.setBounds(10, 270, 356, 80);
prompt.addKeyListener(this);
p.add(prompt);
getContentPane().add(p);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(392, 400);
setLocationRelativeTo(null);
(new SwingWorker<Void, String>()
{
protected Void doInBackground() throws Exception
{
Scanner s = new Scanner(outPipe);
while (s.hasNextLine())
{
String line = s.nextLine();
publish(line);
}
return null;
}
#Override
protected void process(java.util.List<String> chunks)
{
for (String line : chunks)
{
if (line.length() < 1)
continue;
log.append(line.trim() + "\n");
}
}
}).execute();
}
public void execute()
{
String text = prompt.getText();
prompt.setText("");
System.out.println(text);
inWriter.print(text.trim().replaceAll("\r\n", ""));
}
#Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
execute();
}
#Override
public void keyReleased(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
execute();
}
#Override
public void keyTyped(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
execute();
}
// this is the method called from the original application
public static void setConsole(final String title)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
new Console(title);
//System.out.println("somewhat");
}
});
}
}
I found out the solution by myself, actually all the code posted in the 1st post is almost correct, the problem is with the reading from the System.in the original program, since it was done with a Scanner object (but i tested it with a BufferedReader too) and it seems it's something related to the string termination because if i read by using a simple System.in.read() call, i got the right data, of course char by char. Since both Scanner methods and read one are I/O blocking, I think it's something related to the termination of the string. Because when i wrote it on the InputStream, i cleared the string from any LF and CF char, as you can see in the above code, so when println is invoked only a \r\n should be appended. But reading the result char by char I see \r\n\r\n at the end, so i guess it should be something related to the ending of the string, even if i couldnt figured out the right way to handle it. I will keep you informated by updates tought, but however if you have suggestions and/or feedbacks, they will be obviously welcome.

Modal dialogs in IE gets hidden behind IE if user clicks on IE pane

I have to write an applet that brings up a password dialog. The problem is that dialog is set to be always on top but when user clicks on IE window dialog gets hidden behind IE window nevertheless. And since dialog is modal and holds all IE threads IE pane does not refresh and dialog window is still painted on top of IE (but not refreshed). This behaviour confuses users (they see dialog on top of IE but it looks like it has hanged since it is not refreshe).
So I need a way to keep that dialog on top of everything. But any other solution to this problem would be nice.
Here's the code:
PassDialog dialog = new PassDialog(parent);
/* do some non gui related initialization */
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
Resolution: As #shemnon noted I should make a window instead of (null, Frame, Applet) parent of modal dialog. So good way to initlialize parent was:
parent = javax.swing.SwingUtilities.getWindowAncestor(theApplet);
What argument are you using for the parent?
You may have better luck if you use the parent of the Applet.
javax.swing.SwingUtilities.getWindowAncestor(theApplet)
Using the getWindowAncestor will skip the applet parents (getRoot(component) will return applets). In at least some versions of Java there was a Frame that was equivalent to the IE window. YMMV.
Make a background Thread that calls toFront on the Dialog every 2 seconds.
Code that we use (I hope I got everything):
class TestClass {
protected void toFrontTimer(JFrame frame) {
try {
bringToFrontTimer = new java.util.Timer();
bringToFrontTask = new BringToFrontTask(frame);
bringToFrontTimer.schedule( bringToFrontTask, 300, 300);
} catch (Throwable t) {
t.printStackTrace();
}
}
class BringToFrontTask extends TimerTask {
private Frame frame;
public BringToFrontTask(Frame frame) {
this.frame = frame;
}
public void run()
{
if(count < 2) {
frame.toFront();
} else {
cancel();
}
count ++;
}
private int count = 0;
}
public void cleanup() {
if(bringToFrontTask != null) {
bringToFrontTask.cancel();
bringToFrontTask = null;
}
if(bringToFrontTimer != null) {
bringToFrontTimer = null;
}
}
java.util.Timer bringToFrontTimer = null;
java.util.TimerTask bringToFrontTask = null;
}
This is a shot in the dark as I'm not familiar with applets, but you could take a look at IE's built-in window.showModalDialog method. It's fairly easy to use. Maybe a combination of this and Noah's suggestion?
You might try launching a modal from JavaScript using the JavaScript integration (see http://www.raditha.com/java/mayscript.php for an example).
The JavaScript you would need would be something like:
function getPassword() {
return prompt("Enter Password");
}
And the Java would be:
password = jso.call("getPassword", new String[0]);
Unfortunately that means giving up all hope of having a nice looking modal. Good luck!

Categories