Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
358 views
in Technique[技术] by (71.8m points)

java - How can I set the location of a JOptionPane?

I have a splash window that pops up while the program loads. This splash window uses the method setAlwaysOnTop(true), which is something I would prefer to keep.

The issue comes when a separate part of the program pops up a JOptionPane to notify the user they need to update the software. On Linux this appears in front of the Splash window, but on Windows it appears behind, barely visible to the user who then might sit for 30mins - hour before finding out why it's not loaded yet.

A fix I'd like to implement is to either

  • Force the JOptionPane to popup somewhere else on the screen
    or
  • Change the location that the JOptionPane appears at, so it is positioned to the top, or bottom of the splash screen.

The only function I can see that would do this is the setLocationRelativeTo(Component myComponent) method. But this is no good as there is nothing better for it to be relative to (and nothing present!).

Is this sort of thing possible? If so how do I go about doing it?

Here is my SSCCE (based off of SeniorJD's code in their answer) :

public class Main {
    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                final Splash splash =new Splash();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                final Frame frame = new Frame("Frame");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
                splash.dispose();
            }
        });
    }
}

@SuppressWarnings("serial")
public class Frame extends JFrame implements ActionListener{
    Frame(String title){
        super(title);
        JButton button = new JButton("Button");
        add(button);

        setAlwaysOnTop(true);
        setSize(500, 500);
        setLocationRelativeTo(getParent());
        setAlwaysOnTop(true);
        button.addActionListener(this);
        actionPerformed(null);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JOptionPane optionPane = new JOptionPane("Option Pane");
        optionPane.showMessageDialog(this, "Message: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas tristique gravida congue."); 
    }
}
    @SuppressWarnings("serial")
public class Splash extends JFrame {
    public Splash() throws HeadlessException {
        setAlwaysOnTop(true);
        setUndecorated(true);
        setVisible(true);
        setSize(600, 450);
        setLocationRelativeTo(getParent());
    }
}

This more ore less emulates the behaviour my users are seeing. How do I move the JOptionPane out of the way of the splash screen?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should set the frame as a parent of JOptionPane:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;


public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                final JFrame frame = new JFrame("Frame");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JButton button = new JButton("Button");
                frame.add(button);

                frame.setAlwaysOnTop(true);
                frame.setSize(500, 500);
                frame.setLocation(500, 500);

                button.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane optionPane = new JOptionPane("Option Pane");
                        optionPane.showMessageDialog(frame, "Message!"); // if you put null instead of frame, the option pane will be behind the frame
                    }
                });

                frame.setVisible(true);
            }
        });
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...