当前位置: 首页 > 面试题库 >

模态JDialog的最佳位置以避免卡死

孔俊捷
2023-03-14
问题内容

我的Swing应用程序必须向用户显示一个模式对话框。很抱歉没有发布SSCCE。

topContainer可能是JFrameJApplet

private class NewGameDialog extends JDialog {
     public NewGameDialog () {
         super(SwingUtilities.windowForComponent(topContainer), "NEW GAME", ModalityType.APPLICATION_MODAL);

         //add components here

         getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));

         //TODO:
         setSize(new Dimension(250, 200));
         setLocation(650, 300);
     }
}

我在网络事件中像这样启动对话框

SwingUtilities.invokeLater(new Runnable() {
     @Override
     public void run() {
         NewGameDialog dialog = new NewGameDialog();
         dialog.setVisible(true);
     }
});

问题是为我的对话框设置最佳位置。

1)如果将其设置为绝对值,并且我将应用程序框架移至第二个屏幕,则在第一个屏幕上显示对话框,这很奇怪。

2)如果为JFrame设置了相对值,则可能是用户将应用程序框架移到屏幕外部,并且相对位置的对话框对用户不可见。而且由于它是模态的,所以游戏会停滞不前。

考虑到上述两个问题,最佳解决方案是什么?


问题答案:

这让我想起了我最喜欢的帖子,在StackOverflow上使用Window.setLocationByPlatform(true)。

如何最佳定位Swing GUI

编辑1:

您可以添加FocusListener到您JDialogfocusGained(...)方法,你可以使用setLocationRelativeTo(null)两者的JFrameJDialog,让他们都来给屏幕的中心,无论他们在哪里了。

import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

/**
 * Created with IntelliJ IDEA.
 * User: Gagandeep Bali
 * Date: 1/14/13
 * Time: 7:34 PM
 * To change this template use File | Settings | File Templates.
 */
public class FrameFocus
{
    private JFrame mainwindow;
    private CustomDialog customDialog;

    private void displayGUI()
    {
        mainwindow = new JFrame("Frame Focus Window Example");
        customDialog = new CustomDialog(mainwindow, "Modal Dialog", true);
        mainwindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        JButton mainButton = new JButton(
                "Click me to open a MODAL Dialog");
        mainButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!customDialog.isShowing())
                    customDialog.setVisible(true);
            }
        });
        contentPane.add(mainButton);
        mainwindow.setContentPane(contentPane);
        mainwindow.pack();
        mainwindow.setLocationByPlatform(true);
        mainwindow.setVisible(true);
    }

    public static void main(String... args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new FrameFocus().displayGUI();
            }
        });
    }
}


class CustomDialog extends JDialog
{
    private JFrame mainWindow;
    public CustomDialog(JFrame owner, String title, boolean modal)
    {
        super(owner, title, modal);
        mainWindow = owner;
        JPanel contentPane = new JPanel();
        JLabel dialogLabel = new JLabel(
                "I am a Label on JDialog.", JLabel.CENTER);
        contentPane.add(dialogLabel);
        setContentPane(contentPane);
        pack();

        addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                mainWindow.setLocationRelativeTo(null);
                setLocationRelativeTo(null);
            }

            @Override
            public void focusLost(FocusEvent e) {
                /*
                 * Nothing written for this part yet
                 */
            }
        });
    }
}

编辑2:

我在这里到处搜索了一下,结果我认为,Monitor Screen您的应用程序首次出现的实际位置将确定它是GraphicsConfiguration。虽然在我漫游API时,对于上述问题只有一个getter方法,GraphicsConfiguration
而对于同一对象则没有setter方法(仍然可以通过任何顶级Window的构造函数(即JFrame(…)
/ JDialog(。
..)
)。

现在,您可以使用此代码来解决问题,该代码可用于确定要设置的适当位置,再次,focusGain()我认为您可能必须使用method来满足问题的条件2。看一下附带的代码,尽管无需创建new JFrame/JDialog,只需观察如何获取屏幕的坐标即可(您可以在该focusGain()方法中添加该坐标以确定整个Application的位置。)

GraphicsEnvironment ge = GraphicsEnvironment.
    getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for (int j = 0; j < gs.length; j++) {
    GraphicsDevice gd = gs[j];
    GraphicsConfiguration[] gc =
            gd.getConfigurations();
    for (int i=0; i < gc.length; i++) {
        JFrame f = new
        JFrame(gs[j].getDefaultConfiguration());
        Canvas c = new Canvas(gc[i]);
        Rectangle gcBounds = gc[i].getBounds();
        int xoffs = gcBounds.x;
        int yoffs = gcBounds.y;
        f.getContentPane().add(c);
        f.setLocation((i*50)+xoffs, (i*60)+yoffs);
        f.show();
    }
}

编辑3:

尝试更改此:

int x = loc.getX() + (mainWindow.getWidth() - getWidth()) / 2;
int y = loc.getY() + (mainWindow.getHeight() - getHeight()) / 2;
setLocation(x, y);

只是:

setLocationRelativeTo(mainWindow);

为了测试上述FrameFocus内容,尽管已将您的更改添加到我的CustomDialog方法中,但仍按原样使用Class
,如修改后的CustomDialogClass中所示。

class CustomDialog extends JDialog
{
    private JFrame mainWindow;
    public CustomDialog(JFrame owner, String title, boolean modal)
    {
        super(owner, title, modal);
        mainWindow = owner;
        JPanel contentPane = new JPanel();
        JLabel dialogLabel = new JLabel(
                "I am a Label on JDialog.", JLabel.CENTER);
        contentPane.add(dialogLabel);
        setContentPane(contentPane);
        pack();

        addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                //mainWindow.setLocationRelativeTo(null);
                //setLocationRelativeTo(null);
                GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                GraphicsDevice[] gs = ge.getScreenDevices();
                for (int j = 0; j < gs.length; j++) {
                    GraphicsDevice gd = gs[j];
                    GraphicsConfiguration[] gc = gd.getConfigurations();
                    for (int i=0; i < gc.length; i++) {
                        Rectangle gcBounds = gc[i].getBounds();

                        Point loc = mainWindow.getLocationOnScreen();
                        if (gcBounds.contains(loc)) {
                            System.out.println("at " + j + " screen");

                            int x = gcBounds.x + (gcBounds.width - mainWindow.getWidth()) / 2;
                            int y = gcBounds.y + (gcBounds.height - mainWindow.getHeight()) / 2;
                            mainWindow.setLocation(x, y);

                            //x = (int) (loc.getX() + (mainWindow.getWidth() - CustomDialog.this.getWidth()) / 2);
                            //y = (int) (loc.getY() + (mainWindow.getHeight() - CustomDialog.this.getHeight()) / 2);
                            //CustomDialog.this.setLocation(x, y);
                            CustomDialog.this.setLocationRelativeTo(mainWindow);

                            break;
                        }
                    }
                }
            }

            @Override
            public void focusLost(FocusEvent e) {
                /*
                 * Nothing written for this part yet
                 */
            }
        });
    }
}


 类似资料:
  • 问题内容: 我认为这个问题经常出现在Web应用程序开发中。但是,我将尝试详细解释我的问题。 我想知道如何纠正这种行为,例如,当我有如下代码块时: 提交表单后,数据将插入数据库中,并产生消息 “完成操作” 。然后,如果刷新页面,则数据将再次插入数据库。 如何避免这个问题?任何建议将不胜感激:) 问题答案: 创建动作后不要显示响应;操作完成后重定向到另一个页面。如果有人刷新,则他们刷新的是您重定向到的

  • 让我们看一下使用两种不同的方式去计算单词的个数,第一种方式使用 reduceByKey 另外一种方式使用 groupByKey: val words = Array("one", "two", "two", "three", "three", "three") val wordPairsRDD = sc.parallelize(words).map(word => (word, 1)) val

  • 问题内容: 我找到了几个node.js模块,用于使用ip地址查找有关客户端位置和网络的信息。 要求: 位置-国家,城市,州,纬度,经度等 网络-Internet服务提供商,Internet连接类型和Internet速度等。 数据准确性-最大可能性。 注意: 寻找服务器端解决方案。 上面提到的模块使用maxmind数据。而且我还阅读了有关maxmind数据准确性的信息。 我很少选择上面的node.j

  • 我在将JDialog设置为非模态时遇到问题。我需要在不阻止应用程序其余部分的情况下显示弹出窗口。我尝试使用SwingUtilities.invoke稍后(),但顾名思义,它是在主线程工作完成后很久才调用的。为了简化,这是我的代码: 对话框会显示出来,但它是空的。如果我将其用作模式,它会显示得很好。我尝试在某些变体中使用它,例如: 但是正如我所说,对话框对我来说调用得太晚了。(我也尝试了调用和等待,

  • 问题内容: 我的网站最近遭到了一个无辜的代码的攻击: 那里没有SQL调用,因此我不担心SQL注入。但是,显然,SQL并不是唯一的注入方式。 该网站提供了解释以及避免代码注入的一些示例:http : //www.theserverpages.com/articles/webmasters/php/security/Code_Injection_Vulnerabilities_Explained.ht

  • 你们可能都遇到过以下场景: } 简而言之,如何在Objective-C的氛围中有效地简化上述场景? 有什么建议/想法/解决方案吗?干杯:) 编辑:供参考,从这里拍摄的场景。我希望这个问题可以节省哪怕一秒钟需要的开发人员。