Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将JDialog显示为工作表不工作_Java_Macos_Swing_Jdialog - Fatal编程技术网

Java 将JDialog显示为工作表不工作

Java 将JDialog显示为工作表不工作,java,macos,swing,jdialog,Java,Macos,Swing,Jdialog,我目前正在使用这段代码创建JDialog package com.kamuara.reposync.window; import java.awt.Dialog; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JDialog; import javax.sw

我目前正在使用这段代码创建JDialog

package com.kamuara.reposync.window;

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

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;

public class SheetDialog {

    private JFrame _windowFrame;

    public static void main(String[] args) {
        System.setProperty("apple.awt.documentModalSheet", "true");
        System.setProperty("apple.awt.brushMetalLook", "true");

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            new SheetDialog();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public SheetDialog() {
        _windowFrame = new JFrame();
        _windowFrame.setResizable(false);
        _windowFrame.setBounds(100, 100, 451, 320);
        _windowFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        _windowFrame.getContentPane().setLayout(null);
        _windowFrame.setVisible(true);

        JButton showDialogButton = new JButton("Show Dialog");
        showDialogButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showSheetDialog(_windowFrame, "Test", "This should be a sheet dialog", "Oke");
            }
        });
        showDialogButton.setBounds(328, 263, 117, 29);
        _windowFrame.getContentPane().add(showDialogButton);
    }

    public void showSheetDialog(JFrame owner, String title, String message, String button) {
        final JDialog messageDialog = new JDialog(owner, title, Dialog.ModalityType.DOCUMENT_MODAL);
        messageDialog.setBounds(30, 0, owner.getWidth() - 60, 130);

        // TODO: only when os is osx
        messageDialog.getRootPane().putClientProperty("apple.awt.documentModalSheet", "true");
        messageDialog.setLayout(null);

        int offsetX = 25;

        JLabel titleLabel = new JLabel(title);
        titleLabel.setFont(new Font("Lucida Grande", Font.BOLD, 13));
        titleLabel.setBounds(offsetX, 10, 100, 25);
        messageDialog.getContentPane().add(titleLabel);

        JLabel messageLabel = new JLabel(message);
        messageLabel.setVerticalTextPosition(JLabel.TOP);
        messageLabel.setHorizontalTextPosition(JLabel.LEFT);
        messageLabel.setFont(new Font("Lucida Grande", Font.PLAIN, 11));
        messageLabel.setBounds(offsetX, 10, messageDialog.getWidth() - 10, messageDialog.getHeight() - 60);
        messageDialog.getContentPane().add(messageLabel);

        JButton okButton = new JButton(button);
        okButton.setBounds(messageDialog.getWidth() - 105, messageDialog.getHeight() - 35, 100, 25);
        okButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                messageDialog.dispose();
            }
        });
        messageDialog.getContentPane().add(okButton);

        messageDialog.setVisible(true);
    }
}
我以前使用Java 6编译应用程序,并设置clientProperty
apple.awt.documentModalSheet
可以完美地在OSX上将对话框显示为“工作表”,但现在我开始使用Java 7(更新25),对话框不再显示为工作表。我似乎找不到任何关于这个的更新文档。他们对此有什么改变吗?我怎样才能解决这个问题?当前的界面设计使用工作表比使用对话框看起来更好

更新

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.LineBorder;

public class SheetableJFrame extends JFrame implements ActionListener {

    public static final int INCOMING = 1;
    public static final int OUTGOING = -1;
    public static final float ANIMATION_DURATION = 1000f;
    public static final int ANIMATION_SLEEP = 50;

    JComponent sheet;
    JPanel glass;
    Sheet animatingSheet;
    boolean animating;
    int animationDirection;
    Timer animationTimer;
    long animationStart;
    BufferedImage offscreenImage;

    public SheetableJFrame() {
        super();
        glass = (JPanel) getGlassPane();
        glass.setLayout(new GridBagLayout());
        animatingSheet = new Sheet();
        animatingSheet.setBorder(new LineBorder(Color.black, 1));
    }

    public JComponent showJDialogAsSheet(JDialog dialog) {
        sheet = (JComponent) dialog.getContentPane();
        sheet.setBorder(new LineBorder(Color.black, 1));
        glass.removeAll();
        animationDirection = INCOMING;
        startAnimation();
        return sheet;
    }

    public void hideSheet() {
        animationDirection = OUTGOING;
        startAnimation();
    }

    private void startAnimation() {
        glass.repaint();
        // clear glasspane and set up animatingSheet
        animatingSheet.setSource(sheet);
        glass.removeAll();
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.NORTH;
        glass.add(animatingSheet, gbc);
        gbc.gridy = 1;
        gbc.weighty = Integer.MAX_VALUE;
        glass.add(Box.createGlue(), gbc);
        glass.setVisible(true);

        // start animation timer
        animationStart = System.currentTimeMillis();
        if (animationTimer == null) animationTimer = new Timer(ANIMATION_SLEEP, this);
        animating = true;
        animationTimer.start();
    }

    private void stopAnimation() {
        animationTimer.stop();
        animating = false;
    }

    // used by the Timer
    public void actionPerformed(ActionEvent e) {
        if (animating) {
            // calculate height to show
            float animationPercent = (System.currentTimeMillis() - animationStart) / ANIMATION_DURATION;
            animationPercent = Math.min(1.0f, animationPercent);
            int animatingHeight = 0;

            if (animationDirection == INCOMING) {
                animatingHeight = (int) (animationPercent * sheet.getHeight());
            } else {
                animatingHeight = (int) ((1.0f - animationPercent) * sheet.getHeight());
            }
            // clip off that much from sheet and put it into animatingSheet
            animatingSheet.setAnimatingHeight(animatingHeight);
            animatingSheet.repaint();

            if (animationPercent >= 1.0f) {
                stopAnimation();
                if (animationDirection == INCOMING) {
                    finishShowingSheet();
                } else {
                    glass.removeAll();
                    glass.setVisible(false);
                    glass.setLayout(new GridBagLayout());
                    animatingSheet = new Sheet();
                }
            }
        }
    }

    private void finishShowingSheet() {
        glass.removeAll();
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.NORTH;
        glass.add(sheet, gbc);
        gbc.gridy = 1;
        gbc.weighty = Integer.MAX_VALUE;
        glass.add(Box.createGlue(), gbc);
        glass.revalidate();
        glass.repaint();
    }

    class Sheet extends JPanel {
        Dimension animatingSize = new Dimension(0, 1);
        JComponent source;
        BufferedImage offscreenImage;

        public Sheet() {
            super();
            setOpaque(true);
        }

        public void setSource(JComponent source) {
            this.source = source;
            animatingSize.width = source.getWidth();
            makeOffscreenImage(source);
        }

        public void setAnimatingHeight(int height) {
            animatingSize.height = height;
            setSize(animatingSize);
        }

        private void makeOffscreenImage(JComponent source) {
            GraphicsConfiguration gfxConfig = GraphicsEnvironment.getLocalGraphicsEnvironment()
                    .getDefaultScreenDevice().getDefaultConfiguration();
            offscreenImage = gfxConfig.createCompatibleImage(source.getWidth(), source.getHeight());
            Graphics2D offscreenGraphics = (Graphics2D) offscreenImage.getGraphics();
            source.paint(offscreenGraphics);
        }

        public Dimension getPreferredSize() {
            return animatingSize;
        }

        public Dimension getMinimumSize() {
            return animatingSize;
        }

        public Dimension getMaximumSize() {
            return animatingSize;
        }

        public void paint(Graphics g) {
            // get the bottom-most n pixels of source and paint them into g, where n is height
            BufferedImage fragment = offscreenImage.getSubimage(0, offscreenImage.getHeight() - animatingSize.height,
                    source.getWidth(), animatingSize.height);
            g.drawImage(fragment, 0, 0, this);
        }
    }
}
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JDialog;
import javax.swing.JOptionPane;

public class SheetTest extends Object implements PropertyChangeListener {

    JOptionPane optionPane;
    SheetableJFrame frame;

    public static void main(String[] args) {
        new SheetTest();
    }

    public SheetTest() {
        frame = new SheetableJFrame();
        // build JOptionPane dialog and hold onto it
        optionPane = new JOptionPane("Do you want to close?", JOptionPane.QUESTION_MESSAGE, JOptionPane.CANCEL_OPTION);
        frame.setSize(640, 480);
        frame.setVisible(true);
        optionPane.addPropertyChangeListener(this);

        JDialog dialog = optionPane.createDialog(frame, "irrelevant");
        frame.showJDialogAsSheet(dialog);
    }

    public void propertyChange(PropertyChangeEvent pce) {
        if (pce.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) {
            System.out.println("Selected option " + pce.getNewValue());
            frame.hideSheet();
        }
    }
}
我发现下面的Bug报告似乎与我遇到的问题相同

有人知道如何解决这个问题吗?我研究过类似的库,但我不想使用任何库,因为我只想要工作表功能

更新2

我尝试了QuaQua,但该库目前在使用Java7编译时存在完全相同的问题。有解决办法吗

更新3

将代码替换为工作示例()

更新4


发现SWT的Shell类有一个名为SWT.SHEET的样式,这个样式在Java7中仍然可以使用,我不喜欢使用像SWT这样的库,但它似乎是唯一的解决方案。

据我所知,苹果没有正式发布他们的JDK 7版本。苹果为其OS X优化的最新版本JDK仍然是JDK 6。这也是为什么Java的更新会通过AppStore更新选项卡进行。这些更新并非直接来自Oracle

如果您直接从Oracle下载JDK 7,那么这是一个更通用、无需调整的版本

所以,我认为你只需要等待苹果发布他们的OSX优化JDK7

从Oracle下载时,我体验到许多OS X功能无法正常工作:

  • 触控板手势
  • 即使尝试通过UIManager手动设置,原生Aqua外观也不起作用
  • 使用JOptionPane时应用程序图标不工作
  • JMenu将粘贴到JFrame本身,而不是移动到屏幕顶部
看来在JDK修复bug之前,您必须自己实现工作表

重点是:

  • 使用窗框的玻璃窗格来保存“图纸”对话框
  • 使用GridBagLayout(带北锚)将对话框放置在窗格的顶部|中心
  • 通过反复绘制对话框(每次绘制对话框的更多/更少部分),在显示/消失时设置图纸动画
  • 以下是示例代码

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GraphicsConfiguration;
    import java.awt.GraphicsEnvironment;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    
    import javax.swing.Box;
    import javax.swing.JComponent;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.border.LineBorder;
    
    public class SheetableJFrame extends JFrame implements ActionListener {
    
        public static final int INCOMING = 1;
        public static final int OUTGOING = -1;
        public static final float ANIMATION_DURATION = 1000f;
        public static final int ANIMATION_SLEEP = 50;
    
        JComponent sheet;
        JPanel glass;
        Sheet animatingSheet;
        boolean animating;
        int animationDirection;
        Timer animationTimer;
        long animationStart;
        BufferedImage offscreenImage;
    
        public SheetableJFrame() {
            super();
            glass = (JPanel) getGlassPane();
            glass.setLayout(new GridBagLayout());
            animatingSheet = new Sheet();
            animatingSheet.setBorder(new LineBorder(Color.black, 1));
        }
    
        public JComponent showJDialogAsSheet(JDialog dialog) {
            sheet = (JComponent) dialog.getContentPane();
            sheet.setBorder(new LineBorder(Color.black, 1));
            glass.removeAll();
            animationDirection = INCOMING;
            startAnimation();
            return sheet;
        }
    
        public void hideSheet() {
            animationDirection = OUTGOING;
            startAnimation();
        }
    
        private void startAnimation() {
            glass.repaint();
            // clear glasspane and set up animatingSheet
            animatingSheet.setSource(sheet);
            glass.removeAll();
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.NORTH;
            glass.add(animatingSheet, gbc);
            gbc.gridy = 1;
            gbc.weighty = Integer.MAX_VALUE;
            glass.add(Box.createGlue(), gbc);
            glass.setVisible(true);
    
            // start animation timer
            animationStart = System.currentTimeMillis();
            if (animationTimer == null) animationTimer = new Timer(ANIMATION_SLEEP, this);
            animating = true;
            animationTimer.start();
        }
    
        private void stopAnimation() {
            animationTimer.stop();
            animating = false;
        }
    
        // used by the Timer
        public void actionPerformed(ActionEvent e) {
            if (animating) {
                // calculate height to show
                float animationPercent = (System.currentTimeMillis() - animationStart) / ANIMATION_DURATION;
                animationPercent = Math.min(1.0f, animationPercent);
                int animatingHeight = 0;
    
                if (animationDirection == INCOMING) {
                    animatingHeight = (int) (animationPercent * sheet.getHeight());
                } else {
                    animatingHeight = (int) ((1.0f - animationPercent) * sheet.getHeight());
                }
                // clip off that much from sheet and put it into animatingSheet
                animatingSheet.setAnimatingHeight(animatingHeight);
                animatingSheet.repaint();
    
                if (animationPercent >= 1.0f) {
                    stopAnimation();
                    if (animationDirection == INCOMING) {
                        finishShowingSheet();
                    } else {
                        glass.removeAll();
                        glass.setVisible(false);
                        glass.setLayout(new GridBagLayout());
                        animatingSheet = new Sheet();
                    }
                }
            }
        }
    
        private void finishShowingSheet() {
            glass.removeAll();
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.NORTH;
            glass.add(sheet, gbc);
            gbc.gridy = 1;
            gbc.weighty = Integer.MAX_VALUE;
            glass.add(Box.createGlue(), gbc);
            glass.revalidate();
            glass.repaint();
        }
    
        class Sheet extends JPanel {
            Dimension animatingSize = new Dimension(0, 1);
            JComponent source;
            BufferedImage offscreenImage;
    
            public Sheet() {
                super();
                setOpaque(true);
            }
    
            public void setSource(JComponent source) {
                this.source = source;
                animatingSize.width = source.getWidth();
                makeOffscreenImage(source);
            }
    
            public void setAnimatingHeight(int height) {
                animatingSize.height = height;
                setSize(animatingSize);
            }
    
            private void makeOffscreenImage(JComponent source) {
                GraphicsConfiguration gfxConfig = GraphicsEnvironment.getLocalGraphicsEnvironment()
                        .getDefaultScreenDevice().getDefaultConfiguration();
                offscreenImage = gfxConfig.createCompatibleImage(source.getWidth(), source.getHeight());
                Graphics2D offscreenGraphics = (Graphics2D) offscreenImage.getGraphics();
                source.paint(offscreenGraphics);
            }
    
            public Dimension getPreferredSize() {
                return animatingSize;
            }
    
            public Dimension getMinimumSize() {
                return animatingSize;
            }
    
            public Dimension getMaximumSize() {
                return animatingSize;
            }
    
            public void paint(Graphics g) {
                // get the bottom-most n pixels of source and paint them into g, where n is height
                BufferedImage fragment = offscreenImage.getSubimage(0, offscreenImage.getHeight() - animatingSize.height,
                        source.getWidth(), animatingSize.height);
                g.drawImage(fragment, 0, 0, this);
            }
        }
    }
    
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    
    import javax.swing.JDialog;
    import javax.swing.JOptionPane;
    
    public class SheetTest extends Object implements PropertyChangeListener {
    
        JOptionPane optionPane;
        SheetableJFrame frame;
    
        public static void main(String[] args) {
            new SheetTest();
        }
    
        public SheetTest() {
            frame = new SheetableJFrame();
            // build JOptionPane dialog and hold onto it
            optionPane = new JOptionPane("Do you want to close?", JOptionPane.QUESTION_MESSAGE, JOptionPane.CANCEL_OPTION);
            frame.setSize(640, 480);
            frame.setVisible(true);
            optionPane.addPropertyChangeListener(this);
    
            JDialog dialog = optionPane.createDialog(frame, "irrelevant");
            frame.showJDialogAsSheet(dialog);
        }
    
        public void propertyChange(PropertyChangeEvent pce) {
            if (pce.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) {
                System.out.println("Selected option " + pce.getNewValue());
                frame.hideSheet();
            }
        }
    }
    
    测试代码

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GraphicsConfiguration;
    import java.awt.GraphicsEnvironment;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    
    import javax.swing.Box;
    import javax.swing.JComponent;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.border.LineBorder;
    
    public class SheetableJFrame extends JFrame implements ActionListener {
    
        public static final int INCOMING = 1;
        public static final int OUTGOING = -1;
        public static final float ANIMATION_DURATION = 1000f;
        public static final int ANIMATION_SLEEP = 50;
    
        JComponent sheet;
        JPanel glass;
        Sheet animatingSheet;
        boolean animating;
        int animationDirection;
        Timer animationTimer;
        long animationStart;
        BufferedImage offscreenImage;
    
        public SheetableJFrame() {
            super();
            glass = (JPanel) getGlassPane();
            glass.setLayout(new GridBagLayout());
            animatingSheet = new Sheet();
            animatingSheet.setBorder(new LineBorder(Color.black, 1));
        }
    
        public JComponent showJDialogAsSheet(JDialog dialog) {
            sheet = (JComponent) dialog.getContentPane();
            sheet.setBorder(new LineBorder(Color.black, 1));
            glass.removeAll();
            animationDirection = INCOMING;
            startAnimation();
            return sheet;
        }
    
        public void hideSheet() {
            animationDirection = OUTGOING;
            startAnimation();
        }
    
        private void startAnimation() {
            glass.repaint();
            // clear glasspane and set up animatingSheet
            animatingSheet.setSource(sheet);
            glass.removeAll();
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.NORTH;
            glass.add(animatingSheet, gbc);
            gbc.gridy = 1;
            gbc.weighty = Integer.MAX_VALUE;
            glass.add(Box.createGlue(), gbc);
            glass.setVisible(true);
    
            // start animation timer
            animationStart = System.currentTimeMillis();
            if (animationTimer == null) animationTimer = new Timer(ANIMATION_SLEEP, this);
            animating = true;
            animationTimer.start();
        }
    
        private void stopAnimation() {
            animationTimer.stop();
            animating = false;
        }
    
        // used by the Timer
        public void actionPerformed(ActionEvent e) {
            if (animating) {
                // calculate height to show
                float animationPercent = (System.currentTimeMillis() - animationStart) / ANIMATION_DURATION;
                animationPercent = Math.min(1.0f, animationPercent);
                int animatingHeight = 0;
    
                if (animationDirection == INCOMING) {
                    animatingHeight = (int) (animationPercent * sheet.getHeight());
                } else {
                    animatingHeight = (int) ((1.0f - animationPercent) * sheet.getHeight());
                }
                // clip off that much from sheet and put it into animatingSheet
                animatingSheet.setAnimatingHeight(animatingHeight);
                animatingSheet.repaint();
    
                if (animationPercent >= 1.0f) {
                    stopAnimation();
                    if (animationDirection == INCOMING) {
                        finishShowingSheet();
                    } else {
                        glass.removeAll();
                        glass.setVisible(false);
                        glass.setLayout(new GridBagLayout());
                        animatingSheet = new Sheet();
                    }
                }
            }
        }
    
        private void finishShowingSheet() {
            glass.removeAll();
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.NORTH;
            glass.add(sheet, gbc);
            gbc.gridy = 1;
            gbc.weighty = Integer.MAX_VALUE;
            glass.add(Box.createGlue(), gbc);
            glass.revalidate();
            glass.repaint();
        }
    
        class Sheet extends JPanel {
            Dimension animatingSize = new Dimension(0, 1);
            JComponent source;
            BufferedImage offscreenImage;
    
            public Sheet() {
                super();
                setOpaque(true);
            }
    
            public void setSource(JComponent source) {
                this.source = source;
                animatingSize.width = source.getWidth();
                makeOffscreenImage(source);
            }
    
            public void setAnimatingHeight(int height) {
                animatingSize.height = height;
                setSize(animatingSize);
            }
    
            private void makeOffscreenImage(JComponent source) {
                GraphicsConfiguration gfxConfig = GraphicsEnvironment.getLocalGraphicsEnvironment()
                        .getDefaultScreenDevice().getDefaultConfiguration();
                offscreenImage = gfxConfig.createCompatibleImage(source.getWidth(), source.getHeight());
                Graphics2D offscreenGraphics = (Graphics2D) offscreenImage.getGraphics();
                source.paint(offscreenGraphics);
            }
    
            public Dimension getPreferredSize() {
                return animatingSize;
            }
    
            public Dimension getMinimumSize() {
                return animatingSize;
            }
    
            public Dimension getMaximumSize() {
                return animatingSize;
            }
    
            public void paint(Graphics g) {
                // get the bottom-most n pixels of source and paint them into g, where n is height
                BufferedImage fragment = offscreenImage.getSubimage(0, offscreenImage.getHeight() - animatingSize.height,
                        source.getWidth(), animatingSize.height);
                g.drawImage(fragment, 0, 0, this);
            }
        }
    }
    
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    
    import javax.swing.JDialog;
    import javax.swing.JOptionPane;
    
    public class SheetTest extends Object implements PropertyChangeListener {
    
        JOptionPane optionPane;
        SheetableJFrame frame;
    
        public static void main(String[] args) {
            new SheetTest();
        }
    
        public SheetTest() {
            frame = new SheetableJFrame();
            // build JOptionPane dialog and hold onto it
            optionPane = new JOptionPane("Do you want to close?", JOptionPane.QUESTION_MESSAGE, JOptionPane.CANCEL_OPTION);
            frame.setSize(640, 480);
            frame.setVisible(true);
            optionPane.addPropertyChangeListener(this);
    
            JDialog dialog = optionPane.createDialog(frame, "irrelevant");
            frame.showJDialogAsSheet(dialog);
        }
    
        public void propertyChange(PropertyChangeEvent pce) {
            if (pce.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) {
                System.out.println("Selected option " + pce.getNewValue());
                frame.hideSheet();
            }
        }
    }
    
    参考文献


    我想出了一个非常狡猾的方法,设置了JDK现在似乎忘记设置的标志,并手动将窗口定位在正确的位置。但仍有一个阴影缺失,因此我想知道是否有人能改进它。;)

    这会弄乱内部类和私有字段,所以它可能会在任何给定的JDK新版本中出现,但它仍然可以在8u5上工作。也许它会让我们了解这些内部AWT类是如何构造的

    public static void makeSheet(Dialog dialog) {
        dialog.addNotify();
        ComponentPeer peer = dialog.getPeer();
    
        // File dialogs are CFileDialog instead. Unfortunately this means this hack
        // can't work for those. :(
        if (peer instanceof LWWindowPeer) {
            LWWindowPeer windowPeer = (LWWindowPeer) dialog.getPeer();
            //XXX: Should check this before casting too.
            CPlatformWindow platformWindow = (CPlatformWindow) windowPeer.getPlatformWindow();
            try {
                Method method = CPlatformWindow.class.getDeclaredMethod(
                    "setStyleBits", int.class, boolean.class);
                method.setAccessible(true);
                method.invoke(platformWindow, 64 /* CPlatformWindow.SHEET */, true);
    
                Window parent = dialog.getOwner();
                dialog.setLocation(dialog.getLocation().x,
                                   parent.getLocation().y + parent.getInsets().top);
            } catch (Exception e) {
                Logger.getLogger(SheetHack.class.getName())
                    .log(Level.WARNING, "Couldn't call setStyleBits", e);
            }
        }
    }
    

    为了更快地获得更好的帮助,请在您的请求下发布;请参阅pastbin链接以获取工作样本。+1以获取工作样本;作为参考,本文引用了一个仅为Mac OS X设置属性的示例:ohhh,抱歉,您必须等待错误解决,直到Apple发布的更新说明从中获取信息,然后等待下一个版本来解决您的问题。您可能需要等待一段时间才能获得Apple JDK。:)对于以后可能遇到此解决方案的任何人(我清楚地知道我是这么做的)。看起来这在动画的第一次迭代中可以正常工作,但是任何后续动画都会将动画表放置在左上角而不是中间。添加
    glass.setLayout(新的GridBagLayout());animatingSheet=新工作表()else
    中,清除/隐藏
    glass
    窗格的块中的code>。这里有一个包含更改的粘贴箱:--应该可以解决这个问题(尽管是通过蛮力)。编辑:链接也断开:(