0

Java で MDI フォームを使用するプロジェクトに取り組んでいます。フレームを作成し、それにデスクトップ ペインを追加しました。私のプロジェクトは多くの内部フレームを使用しています。また、これらの内部フレームには、自分で作成したカスタム ダイアログを表示する必要があります。明確にするために、1つのjdialogには、ユーザーに1つの行を選択するように求めるテーブルがあります。しかし、問題は、内部フレームから jdialog を呼び出すと (modality=true で)、ダイアログが内部フレームの上部だけでなく、メイン フレームの上部に表示されることです。これにより、jdialog が表示されているときにウィンドウを最小化できなくなります。

私の見解では、2 つの解決策が考えられます (不可能かもしれません!!).. jdialog をデスクトップ ペイン内に表示するか、jdialog の代わりに内部フレームを作成して、親の内部フレームに対してモーダルであるように見せる必要があります。 . つまり、ダイアログを表示したいときは、内部フレームを無効にしてフォームをフォーカスできないように設定し、この内部フレームの上に新しい内部フレームを表示することができます。何週間もフォーラムを検索してきましたが、答えが見つかりませんでした。解決策があることを願っています。よろしくお願いします。

4

3 に答える 3

2

java 6で非常にうまく機能するjavaプロジェクトで作業しているときにも同じ問題が発生しましたが、java7に変更すると同じ問題が発生しました。

私は解決策を見つけました。dialog.setVisible(false)続いて。を追加しまし たdialog.setVisible(true)。次に、ダイアログはキーボードに応答しています。

于 2013-02-07T09:15:14.717 に答える
1

また、カスタム ダイアログを表示する多くの内部フレームを使用する MDI アプリにも取り組んでいます。ダイアログを非モーダルにして、ダイアログを表示したまま、内部フレームをアイコン化したり、デスクトップ ペイン全体を最小化したりできるようにします。

モーダルな動作が絶対に必要な場合 (つまり、ユーザーが他の操作を行う前にダイアログと対話する必要がある場合) は、おそらくダイアログをモードレスのままにして、コードをデファクト モダリティにすることができます。

また、 setModalityType(java.awt.Dialog.ModalityType.DOCUMENT_MODAL); の動作を見ましたか?

?

于 2012-07-07T20:30:27.190 に答える
0

わお!!私はwebbytから答えを得ました...内部フレームの使用を避けてください..クラスModalityInternalFrame(JinternalFrameのサブクラス)を使用してみてください..すべて正常に動作します..クラスは次のとおりです

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

/**
 * An extended
 * <code>JInternalFrame</code> that provides modality in a child/parent
 * hierarchy
 *
 * @author webbyit
 */
public class ModalityInternalFrame extends JInternalFrame {

    protected JDesktopPane desktopPane;
    protected JComponent parent;
    protected ModalityInternalFrame childFrame;
    protected JComponent focusOwner;
    private boolean wasCloseable;

    public ModalityInternalFrame() {
        init(); // here to allow netbeans to use class in gui builder
    }

    public ModalityInternalFrame(JComponent parent) {
        this(parent, null);
    }

    public ModalityInternalFrame(JComponent parent, String title) {
        this(parent, title, false);
    }

    public ModalityInternalFrame(JComponent parent, String title, boolean resizable) {
        this(parent, title, resizable, false);
    }

    public ModalityInternalFrame(JComponent parent, String title, boolean resizable, boolean closeable) {
        this(parent, title, resizable, closeable, false);
    }

    public ModalityInternalFrame(JComponent parent, String title, boolean resizable, boolean closeable,
            boolean maximizable) {
        this(parent, title, resizable, closeable, maximizable, false);
    }

    public ModalityInternalFrame(JComponent parent, String title, boolean resizable, boolean closeable,
            boolean maximizable,
            boolean iconifiable) {
        super(title, resizable, closeable, maximizable, iconifiable);
        setParentFrame(parent);
        //setFocusTraversalKeysEnabled(false);
        if (parent != null && parent instanceof ModalityInternalFrame) {
            ((ModalityInternalFrame) parent).setChildFrame(ModalityInternalFrame.this);

            /*
             * set focus to the new frame and show the frame Code added by Jasir
             */
            try {
                ((ModalityInternalFrame) parent).setSelected(false);
                setSelected(true);
                setVisible(true);
            } catch (PropertyVetoException ex) {
                Logger.getLogger(ModalityInternalFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        // Add glass pane
        ModalityInternalGlassPane glassPane = new ModalityInternalGlassPane(this);
        setGlassPane(glassPane);


        // Add frame listeners
        addFrameListener();

        // Add frame veto listenr
        addFrameVetoListener();

        init();


        // calculate size and position


    }

    private void setParentFrame(JComponent parent) {
        desktopPane = JOptionPane.getDesktopPaneForComponent(parent);
        this.parent = parent == null ? JOptionPane.getDesktopPaneForComponent(parent) : parent; // default to desktop if no parent given
    }

    public JComponent getParentFrame() {
        return parent;
    }

    public void setChildFrame(ModalityInternalFrame childFrame) {
        this.childFrame = childFrame;
    }

    public ModalityInternalFrame getChildFrame() {
        return childFrame;
    }

    public boolean hasChildFrame() {
        return (childFrame != null);
    }

    protected void addFrameVetoListener() {
        addVetoableChangeListener(new VetoableChangeListener() {

            public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
                if (evt.getPropertyName().equals(JInternalFrame.IS_SELECTED_PROPERTY)
                        && evt.getNewValue().equals(Boolean.TRUE)) {
                    if (hasChildFrame()) {
                        //childFrame.setSelected(true);
                        if (childFrame.isIcon()) {
                            childFrame.setIcon(false);
                        }
                        throw new PropertyVetoException("no!", evt);
                    }
                }
            }
        });
    }

    /**
     * Method to control the display of the glass pane, dependant on the frame
     * being active or not
     */
    protected synchronized void addFrameListener() {
        addInternalFrameListener(new InternalFrameAdapter() {

            @Override
            public void internalFrameActivated(InternalFrameEvent e) {
                if (hasChildFrame() == true) {
                    getGlassPane().setVisible(true);
                    grabFocus();
                } else {
                    getGlassPane().setVisible(false);
                }
            }

            @Override
            public void internalFrameOpened(InternalFrameEvent e) {
                getGlassPane().setVisible(false);
                try {
                    setSelected(true);
                } catch (PropertyVetoException ex) {
                    Logger.getLogger(ModalityInternalFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            @Override
            public void internalFrameClosing(InternalFrameEvent e) {
                if (parent != null && parent instanceof ModalityInternalFrame) {
                    ((ModalityInternalFrame) parent).childClosing();
                }
            }
        });
    }

    /**
     * Method to handle child frame closing and make this frame available for
     * user input again with no glass pane visible
     */
    protected void childClosing() {
        setClosable(wasCloseable);
        getGlassPane().setVisible(false);
        if (focusOwner != null) {
            java.awt.EventQueue.invokeLater(new Runnable() {

                @Override
                public void run() {
                    try {
                        moveToFront();
                        setSelected(true);
                        focusOwner.grabFocus();
                    } catch (PropertyVetoException ex) {
                    }
                }
            });
            focusOwner.grabFocus();
        }
        getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        setChildFrame(null);
        getDesktopPane().setSelectedFrame(this);
        System.out.println(getDesktopPane().getSelectedFrame());
    }

    /*
     * Method to handle child opening and becoming visible.
     */
    protected void childOpening() {
        // record the present focused component
        wasCloseable = isClosable();
        setClosable(false);
        focusOwner = (JComponent) getMostRecentFocusOwner();
        grabFocus();
        getGlassPane().setVisible(true);
        getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    }

    @Override
    public void show() {
        if (parent != null && parent instanceof ModalityInternalFrame) {
            // Need to inform parent its about to lose its focus due
            // to child opening
            ((ModalityInternalFrame) parent).childOpening();
        }
        calculateBounds();
        super.show();
    }

    protected void init() {
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 394, Short.MAX_VALUE));
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 274, Short.MAX_VALUE));

        pack();
    }

    public void calculateBounds() {
        Dimension frameSize = getPreferredSize();
        Dimension parentSize = new Dimension();
        Dimension rootSize = new Dimension(); // size of desktop
        Point frameCoord = new Point();

        if (desktopPane != null) {
            rootSize = desktopPane.getSize(); // size of desktop
            frameCoord = SwingUtilities.convertPoint(parent, 0, 0, desktopPane);
            parentSize = parent.getSize();
        }

        //setBounds((rootSize.width - frameSize.width) / 2, (rootSize.height - frameSize.height) / 2, frameSize.width, frameSize.height);

        // We want dialog centered relative to its parent component
        int x = (parentSize.width - frameSize.width) / 2 + frameCoord.x;
        int y = (parentSize.height - frameSize.height) / 2 + frameCoord.y;

        // If possible, dialog should be fully visible
        int ovrx = x + frameSize.width - rootSize.width;
        int ovry = y + frameSize.height - rootSize.height;
        x = Math.max((ovrx > 0 ? x - ovrx : x), 0);
        y = Math.max((ovry > 0 ? y - ovry : y), 0);
        setBounds(x, y, frameSize.width, frameSize.height);
    }

    /**
     * Glass pane to overlay. Listens for mouse clicks and sets selected on
     * associated modal frame. Also if modal frame has no children make class
     * pane invisible
     */
    class ModalityInternalGlassPane extends JComponent {

        private ModalityInternalFrame modalFrame;

        public ModalityInternalGlassPane(ModalityInternalFrame frame) {
            modalFrame = frame;
            addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (modalFrame.isSelected() == false) {
                        try {
                            modalFrame.setSelected(true);
                            if (modalFrame.hasChildFrame() == false) {
                                setVisible(false);
                            }
                        } catch (PropertyVetoException e1) {
                            //e1.printStackTrace();
                        }
                    }
                }
            });
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.setColor(new Color(255, 255, 255, 100));
            g.fillRect(0, 0, getWidth(), getHeight());
        }
    }
}

しかし、まだフォーカスと他の何かにいくつかの問題があります..

于 2012-07-11T01:52:39.980 に答える