DnD - 为什么拖动的标签显示在其他组件下面? [英] DnD - Why is dragged label displayed below other components?

查看:131
本文介绍了DnD - 为什么拖动的标签显示在其他组件下面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个基本的DnD程序,它连续有四个JLabels。我注意到
,当我将标签拖到左边时,它显示在下一个标签的下方。但是,当我将标签拖到右侧时,
显示在下一个标签的上方。
标签按顺序添加,从左到右。因此,拖放的标签是在拖放的标签之前添加的其他标签下面显示的
,并且在拖动的标签之后添加的其他标签上显示

任何人都可以解释为什么会这样吗?任何人都可以提供修复,以便拖放的标签
显示在其他标签之上?
谢谢。



源代码:

  public class LabelDnd扩展了JPanel {

private JLabel [] labels;
private Color [] colors = {Color.BLUE,Color.BLACK,Color.RED,Color.MAGENTA};

public LabelDnd(){
super();
this.setLayout(new FlowLayout(FlowLayout.CENTER,0,0));
this.setBackground(Color.WHITE);
this.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));

JPanel basePanel = new JPanel();
basePanel.setLayout(new GridLayout(1,4,4,4));
basePanel.setBackground(Color.CYAN);

MouseAdapter listener = new MouseAdapter(){

Point p = null;

@Override
public void mousePressed(MouseEvent e){
p = e.getLocationOnScreen();
}

@Override
public void mouseDragged(MouseEvent e){
JComponent c =(JComponent)e.getSource();
Point l = c.getLocation();
指向这里= e.getLocationOnScreen();
c.setLocation(l.x + here.x - p.x,l.y + here.y - p.y);
p =这里;
}
};

this.labels = new JLabel [4]; (int i = 0; i< this.labels.length; i ++){
this.labels [i] = new JLabel(String.valueOf(i),JLabel)

中央);
this.labels [i] .setOpaque(true);
this.labels [i] .setPreferredSize(new Dimension(100,100));
this.labels [i] .setBackground(this.colors [i]);
this.labels [i] .setForeground(Color.WHITE);
this.labels [i] .addMouseListener(listener);
this.labels [i] .addMouseMotionListener(listener);
basePanel.add(this.labels [i]);
}

this.add(basePanel);
}

public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JFrame frame = new JFrame(LabelDnd);
frame.getContentPane()。setLayout(new BorderLayout());

LabelDnd panel = new LabelDnd();

frame.getContentPane()。add(panel,BorderLayout.CENTER);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}


解决方案

你不会更改标签在代码中添加或正在绘制的顺序。考虑将JLabel升级到玻璃板时(从主容器中卸下它),然后在鼠标释放时将其重新添加到主容器。



例如:

  import java.awt.BorderLayout; 
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event。*;
import java.util.Comparator;
import java.util.PriorityQueue;

import javax.swing。*;

@SuppressWarnings(serial)
public class LabelDnd extends JPanel {
private static final String X_POS =x position;
私人JLabel []标签;
private Color [] colors = {Color.BLUE,Color.BLACK,Color.RED,Color.MAGENTA};

public LabelDnd(){
super();
// this.setLayout(new FlowLayout(FlowLayout.CENTER,0,0));
this.setBackground(Color.WHITE);
this.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));

JPanel basePanel = new JPanel();
basePanel.setLayout(new GridLayout(1,4,4,4));
basePanel.setBackground(Color.CYAN);

MouseAdapter listener = new MouseAdapter(){
Point loc = null;
容器parentContainer = null;
容器glasspane = null;
JLabel placeHolder = new JLabel();
private Point glassLocOnScn;

@Override
public void mousePressed(MouseEvent e){
JComponent selectedLabel =(JComponent)e.getSource();

loc = e.getPoint();
Point currLocOnScn = e.getLocationOnScreen();

parentContainer = selectedLabel.getParent();

JRootPane rootPane = SwingUtilities.getRootPane(selectedLabel);
glasspane =(Container)rootPane.getGlassPane();
glasspane.setVisible(true);
glasspane.setLayout(null);
glassLocOnScn = glasspane.getLocationOnScreen();

组件[] comps = parentContainer.getComponents();

//从父
中删除所有标签parentContainer.removeAll();

//添加标签,除了选定的一个
(Component comp:comps){
if(comp!= selectedLabel){
parentContainer.add );
} else {
//添加占位符代替所选组件
parentContainer.add(placeHolder);
}
}

selectedLabel.setLocation(currLocOnScn.x - loc.x - glassLocOnScn.x,
currLocOnScn.y - loc.y - glassLocOnScn.y) ;
glasspane.add(selectedLabel);
glasspane.setVisible(true);

parentContainer.revalidate();
parentContainer.repaint();

}

@Override
public void mouseDragged(MouseEvent e){
JComponent selectedLabel =(JComponent)e.getSource();

glassLocOnScn = glasspane.getLocationOnScreen();
Point currLocOnScn = e.getLocationOnScreen();
selectedLabel.setLocation(currLocOnScn.x - loc.x - glassLocOnScn.x,
currLocOnScn.y - loc.y - glassLocOnScn.y);

glasspane.repaint();
}

@Override
public void mouseReleased(MouseEvent e){
JComponent selectedLabel =(JComponent)e.getSource();

if(parentContainer == null || glasspane == null){
return;
}

//根据屏幕上的x位置对标签进行排序
PriorityQueue< JComponent> compQueue = new PriorityQueue< JComponent>(
4,new Comparator< JComponent>(){

@Override
public int compare(JComponent o1,JComponent o2){
//排序一个kludge - 检查客户端属性
//持有x位置
整数i1 =(整数)o1.getClientProperty(X_POS);
整数i2 =(整数)o2.getClientProperty(X_POS);
return i1.compareTo(i2);
}
});

//排序一个kludge - 将x位置删除组件
//到客户端属性中以将其与JLabel
selectedLabel.putClientProperty(X_POS,selectedLabel)关联。 getLocationOnScreen()x)的。
glasspane.remove(selectedLabel);
compQueue.add(selectedLabel);
Component [] comps = parentContainer.getComponents();
for(Component comp:comps){
JLabel label =(JLabel)comp;
if(!label.getText()。trim()。isEmpty()){//如果占位符!
label.putClientProperty(X_POS,label.getLocationOnScreen()。x);
compQueue.add(label); //添加到队列
}
}
parentContainer.removeAll();

//添加由屏幕上的x位置排序的标签
while(compQueue.size()> 0){
parentContainer.add(compQueue.remove()) ;
}

parentContainer.revalidate();
parentContainer.repaint();
glasspane.repaint();

}
};

this.labels = new JLabel [4]; (int i = 0; i< this.labels.length; i ++){
this.labels [i] = new JLabel(String.valueOf(i),JLabel)

中央);
this.labels [i] .setOpaque(true);
this.labels [i] .setPreferredSize(new Dimension(100,100));
this.labels [i] .setBackground(this.colors [i]);
this.labels [i] .setForeground(Color.WHITE);
this.labels [i] .addMouseListener(listener);
this.labels [i] .addMouseMotionListener(listener);
basePanel.add(this.labels [i]);
}

this.add(basePanel);
}

public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JFrame frame = new JFrame(LabelDnd);
frame.getContentPane()。setLayout(new BorderLayout());

LabelDnd panel = new LabelDnd();

frame.getContentPane()。add(panel,BorderLayout.CENTER);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}


I've written a basic DnD program that has four JLabels in a row. I've noticed that when I drag a label to the left, it is displayed below the next label. However, when I drag the label to the right, it is displayed above the next label. The labels are added in order, left to right. So the dragged label is being displayed below other labels that were added before the dragged label, and displayed above other labels that were added after the dragged label. Can anyone explain why this happens? Can anyone offer a fix so that the dragged label is displayed above the other labels? Thanks.

source code:

public class LabelDnd extends JPanel {

    private JLabel[] labels;
    private Color[] colors = { Color.BLUE, Color.BLACK, Color.RED, Color.MAGENTA };

    public LabelDnd() {
        super();
        this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
        this.setBackground(Color.WHITE);
        this.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));

        JPanel basePanel = new JPanel();
        basePanel.setLayout(new GridLayout(1, 4, 4, 4));
        basePanel.setBackground(Color.CYAN);

        MouseAdapter listener = new MouseAdapter() {

            Point p = null;

            @Override
            public void mousePressed(MouseEvent e) {
              p = e.getLocationOnScreen();
            }

            @Override
            public void mouseDragged(MouseEvent e) {
              JComponent c = (JComponent) e.getSource();
              Point l = c.getLocation();
              Point here = e.getLocationOnScreen();
              c.setLocation(l.x + here.x - p.x, l.y + here.y - p.y);
              p = here;
            }
          };

        this.labels = new JLabel[4];

        for (int i = 0; i < this.labels.length; i++) {
            this.labels[i] = new JLabel(String.valueOf(i), JLabel.CENTER);
            this.labels[i].setOpaque(true);
            this.labels[i].setPreferredSize(new Dimension(100, 100));
            this.labels[i].setBackground(this.colors[i]);
            this.labels[i].setForeground(Color.WHITE);
            this.labels[i].addMouseListener(listener);
            this.labels[i].addMouseMotionListener(listener);
            basePanel.add(this.labels[i]);
        }

        this.add(basePanel);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("LabelDnd");
                frame.getContentPane().setLayout(new BorderLayout());

                LabelDnd panel = new LabelDnd();

                frame.getContentPane().add(panel, BorderLayout.CENTER);

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

解决方案

You are not changing the order that the labels have been added or are being painted in your code. Consider elevating the JLabel to the glasspane when dragging (after removing it from the main container), and then re-adding it to the main container on mouse release.

For example:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.*;
import java.util.Comparator;
import java.util.PriorityQueue;

import javax.swing.*;

@SuppressWarnings("serial")
public class LabelDnd extends JPanel {
   private static final String X_POS = "x position";
   private JLabel[] labels;
   private Color[] colors = { Color.BLUE, Color.BLACK, Color.RED, Color.MAGENTA };

   public LabelDnd() {
      super();
      // this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
      this.setBackground(Color.WHITE);
      this.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));

      JPanel basePanel = new JPanel();
      basePanel.setLayout(new GridLayout(1, 4, 4, 4));
      basePanel.setBackground(Color.CYAN);

      MouseAdapter listener = new MouseAdapter() {
         Point loc = null;
         Container parentContainer = null;
         Container glasspane = null;
         JLabel placeHolder = new JLabel("");
         private Point glassLocOnScn;

         @Override
         public void mousePressed(MouseEvent e) {
            JComponent selectedLabel = (JComponent) e.getSource();

            loc = e.getPoint();
            Point currLocOnScn = e.getLocationOnScreen();

            parentContainer = selectedLabel.getParent();

            JRootPane rootPane = SwingUtilities.getRootPane(selectedLabel);
            glasspane = (Container) rootPane.getGlassPane();
            glasspane.setVisible(true);
            glasspane.setLayout(null);
            glassLocOnScn = glasspane.getLocationOnScreen();

            Component[] comps = parentContainer.getComponents();

            // remove all labels from parent
            parentContainer.removeAll();

            // add labels back except for selected one
            for (Component comp : comps) {
               if (comp != selectedLabel) {
                  parentContainer.add(comp);
               } else {
                  // add placeholder in place of selected component
                  parentContainer.add(placeHolder);
               }
            }

            selectedLabel.setLocation(currLocOnScn.x - loc.x - glassLocOnScn.x,
                  currLocOnScn.y - loc.y - glassLocOnScn.y);
            glasspane.add(selectedLabel);
            glasspane.setVisible(true);

            parentContainer.revalidate();
            parentContainer.repaint();

         }

         @Override
         public void mouseDragged(MouseEvent e) {
            JComponent selectedLabel = (JComponent) e.getSource();

            glassLocOnScn = glasspane.getLocationOnScreen();
            Point currLocOnScn = e.getLocationOnScreen();
            selectedLabel.setLocation(currLocOnScn.x - loc.x - glassLocOnScn.x,
                  currLocOnScn.y - loc.y - glassLocOnScn.y);

            glasspane.repaint();
         }

         @Override
         public void mouseReleased(MouseEvent e) {
            JComponent selectedLabel = (JComponent) e.getSource();

            if (parentContainer == null || glasspane == null) {
               return;
            }

            // sort the labels based on their x position on screen
            PriorityQueue<JComponent> compQueue = new PriorityQueue<JComponent>(
                  4, new Comparator<JComponent>() {

                     @Override
                     public int compare(JComponent o1, JComponent o2) {
                        // sort of a kludge -- checking a client property that
                        // holds the x-position 
                        Integer i1 = (Integer) o1.getClientProperty(X_POS);
                        Integer i2 = (Integer) o2.getClientProperty(X_POS);
                        return i1.compareTo(i2);
                     }
                  });

            // sort of a kludge -- putting x position before removing component
            // into a client property to associate it with the JLabel
            selectedLabel.putClientProperty(X_POS, selectedLabel.getLocationOnScreen().x);
            glasspane.remove(selectedLabel);
            compQueue.add(selectedLabel);
            Component[] comps = parentContainer.getComponents();
            for (Component comp : comps) {
               JLabel label = (JLabel) comp;
               if (!label.getText().trim().isEmpty()) { // if placeholder!
                  label.putClientProperty(X_POS, label.getLocationOnScreen().x);
                  compQueue.add(label); // add to queue
               }
            }
            parentContainer.removeAll();

            // add back labels sorted by x-position on screen
            while (compQueue.size() > 0) {
               parentContainer.add(compQueue.remove());
            }

            parentContainer.revalidate();
            parentContainer.repaint();
            glasspane.repaint();

         }
      };

      this.labels = new JLabel[4];

      for (int i = 0; i < this.labels.length; i++) {
         this.labels[i] = new JLabel(String.valueOf(i), JLabel.CENTER);
         this.labels[i].setOpaque(true);
         this.labels[i].setPreferredSize(new Dimension(100, 100));
         this.labels[i].setBackground(this.colors[i]);
         this.labels[i].setForeground(Color.WHITE);
         this.labels[i].addMouseListener(listener);
         this.labels[i].addMouseMotionListener(listener);
         basePanel.add(this.labels[i]);
      }

      this.add(basePanel);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            JFrame frame = new JFrame("LabelDnd");
            frame.getContentPane().setLayout(new BorderLayout());

            LabelDnd panel = new LabelDnd();

            frame.getContentPane().add(panel, BorderLayout.CENTER);

            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
         }
      });
   }
}

这篇关于DnD - 为什么拖动的标签显示在其他组件下面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆