简体   繁体   English

我怎样才能无条件地让我的 swing 组件呈现在所有其他组件之上?

[英]How can I unconditionally make my swing component render above all others?

I have a JComponent , specifically a JLabel , that I want to render above all other components in my UI.我有一个JComponent ,特别是JLabel ,我想在我的 UI 中呈现在所有其他组件之上。 I've made it draggable viathis code , and I'd like it to render above everything else in the UI while being dragged.我已经通过这段代码使它可以拖动,我希望它在被拖动时呈现在 UI 中的所有其他内容之上。

I've attempted to use a JLayeredPane , but I couldn't get it to work with my UI, which is huge and complicated.我曾尝试使用JLayeredPane ,但我无法让它与我的 UI 一起使用,它又大又复杂。 Ideally there's some sort of solution that I can simply implement in the component's paint(Graphics) method.理想情况下,我可以在组件的paint(Graphics)方法中简单地实现某种解决方案。

solved this myself through the usage of a glass pane, this code should work in nearly every case.通过使用玻璃板自己解决了这个问题,这段代码几乎适用于所有情况。 the only issue I've found is that the mouse/component position may not be exactly synced if the user has a taskbar position other than bottom.我发现的唯一问题是,如果用户的任务栏 position 不是底部,则鼠标/组件 position 可能不会完全同步。

thanks to https://stackoverflow.com/users/992484/madprogrammer for suggesting I use swing's glass pane to fix it.感谢https://stackoverflow.com/users/992484/madprogrammer建议我使用 swing 的玻璃板来修复它。

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class DraggableLabel extends JLabel {
    private JComponent initialParent;

    public DraggableLabel(String text) {
        super(text);
        this.setOpaque(false);

        this.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                // no-op
            }

            @Override
            public void mousePressed(MouseEvent e) {
                // save parent for re-addition after dragging is finished
                DraggableLabel.this.initialParent = (JComponent) DraggableLabel.this.getParent();

                // configure object to be on the glass pane instead of its former pane
                DraggableLabel.this.setVisible(false);
                JPanel glassPane = (JPanel) SwingUtilities.getRootPane(DraggableLabel.this).getGlassPane();
                DraggableLabel.this.initialParent.remove(DraggableLabel.this);
                glassPane.add(DraggableLabel.this);

                // repaint former panel to display removal of element
                DraggableLabel.this.initialParent.repaint();

                // set up glass pane to actually display elements
                glassPane.setOpaque(false);
                glassPane.setVisible(true);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                // remove from glass pane
                JPanel glassPane = (JPanel) SwingUtilities.getRootPane(DraggableLabel.this).getGlassPane();
                glassPane.remove(DraggableLabel.this);

                // add to former panel
                DraggableLabel.this.initialParent.add(DraggableLabel.this);
                DraggableLabel.this.initialParent.repaint();

                DraggableLabel.this.initialParent = null;
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                // no-op
            }

            @Override
            public void mouseExited(MouseEvent e) {
                // no-op
            }

        });
        this.addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent e) {
                // get task bar height
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                Rectangle windowSize = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
                int taskBarHeight = (int) (screenSize.getHeight() - windowSize.getHeight());

                int mouseScreenX = e.getXOnScreen();
                int mouseScreenY = e.getYOnScreen();

                // calculate, offsetting y for the task bar
                // note: task bar offsetting will probably break if people have their taskbar at the top of the screen!
                // good thing I don't care!
                JFrame frame = (JFrame) SwingUtilities.getRoot(DraggableLabel.this);
                int mouseFrameX = mouseScreenX - frame.getX();
                int mouseFrameY = mouseScreenY - frame.getY() - taskBarHeight;

                // set location and ensure visibility
                DraggableLabel.this.setLocation(mouseFrameX, mouseFrameY);
                DraggableLabel.this.setVisible(true);
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                // no-op
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM