0

ガラス ペインを使用して、JFrame 内にモーダル ダイアログを作成しました。私の表示方法は非常に単純です。アルファ背景を持つガラス ペインとして JPanel を作成し、JLabel と [OK] ボタンと [閉じる] ボタンを追加します。次に、ガラス ペインが設定され、 で表示されますframe.getGlassPane().setVisible(true);

すべて正常に動作します。メソッドを呼び出すと、ペインが表示され、[OK] または [キャンセル] をクリックするとガラス ペインが非表示になります。ただし、このメソッドはガラス ペインを表示した直後に戻ります。しかし、メソッドのように動作するようにしたいJOptionPane: ダイアログが閉じられるまでブロックします。

しかし、show メソッドの最後にビジー待機を挿入しようとするたびに、開くボタンをクリックすると GUI がフリーズします。私もメカニズムを取得しようとしましたJDialog#show()が、それは私にとって少し複雑です。

では、ガラス ペインが表示されている間に show メソッドをブロックするにはどうすればよいでしょうか。

簡単な例を次に示します。

public class GlassPaneSSCE extends JPanel {

    private JFrame parentFrame;

    public GlassPaneSSCE(JFrame parent) {
        parentFrame = parent;
        addKeyListener(new KeyAdapter() {});
        addMouseListener(new MouseAdapter() {});
        setBackground(new Color(0, 0, 0, 100));
        initGui();
    }

    @Override
    protected void paintComponent(Graphics g) {
        g.setColor(getBackground());
        g.fillRect(0, 0, getWidth(), getHeight());
        super.paintComponent(g);
    }

    private void initGui() {
        setLayout(new FlowLayout(FlowLayout.CENTER));
        setOpaque(false);

        final JPanel content = new JPanel(new BorderLayout(4, 4));
        content.setOpaque(true);
        content.setBorder(new EmptyBorder(8, 8, 8, 8));

        JLabel top = new JLabel("Title of this little modal dialog");
        content.add(top, BorderLayout.NORTH);

        JPanel inner = new JPanel(new BorderLayout());
        content.add(inner, BorderLayout.CENTER);

        inner.add(new JScrollPane(new JList(new String[] {
            "Item 1                                        ", 
            "Item 2", "Item 3"
        })));

        Box ctrlButtons = Box.createHorizontalBox();
        ctrlButtons.setBorder(new EmptyBorder(0, 4, 4, 4));
        ctrlButtons.add(Box.createHorizontalGlue());
        ctrlButtons.add(new JButton(new AbstractAction("OK") {

            @Override
            public void actionPerformed(ActionEvent e) {
                parentFrame.getGlassPane().setVisible(false);
                parentFrame.setGlassPane(new JPanel());
            }
        }));
        content.add(ctrlButtons, BorderLayout.SOUTH);

        add(content);
    }

    public void display() {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                parentFrame.setGlassPane(GlassPaneSSCE.this);
                parentFrame.getGlassPane().setVisible(true);

                // Set the focus on the glass pane
                requestFocus();
                setFocusCycleRoot(true);
            }
        });

        // The next line should be executed only if
        // the ok button is clicked and not before
        System.out.println("End of display()");
    }

    public static void main(String[] args) {
        final JFrame f = new JFrame();
        f.setLayout(new FlowLayout(FlowLayout.CENTER));
        JTextArea tp = new JTextArea(10, 10);

        for (int i = 0; i < 20; i++) {
            JButton b = new JButton("Open");
            b.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    GlassPaneSSCE gp  = new GlassPaneSSCE(f);
                    gp.display();
                }
            });
            f.add(b);

            tp.append("Item " + (i+1) + "\n");
        }
        f.add(new JScrollPane(tp));
        f.setSize(600, 600);
        f.setVisible(true);
    }

}
4

0 に答える 0