[英]How can I unconditionally make my swing component render above all others?
我有一個JComponent
,特別是JLabel
,我想在我的 UI 中呈現在所有其他組件之上。 我已經通過這段代碼使它可以拖動,我希望它在被拖動時呈現在 UI 中的所有其他內容之上。
我曾嘗試使用JLayeredPane
,但我無法讓它與我的 UI 一起使用,它又大又復雜。 理想情況下,我可以在組件的paint(Graphics)
方法中簡單地實現某種解決方案。
通過使用玻璃板自己解決了這個問題,這段代碼幾乎適用於所有情況。 我發現的唯一問題是,如果用戶的任務欄 position 不是底部,則鼠標/組件 position 可能不會完全同步。
感謝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.