我有一個擴展了JPanel的類的ExamplePanel,它由2個JPanels- labelsPanel和subPanel組成。 Labelspanel包含任意JLabels,而subPanel包含ExamplePanel嵌套實例的不同實例。Java在拖動時總是將JLabel保留在JPanels上
我想能夠將JLabel拖動到嵌套的實例,但是當我這樣做時,它們最終會落在子面板後面。 我相信答案在於setComponentZOrder方法,但我沒有取得任何進展。它使得JLabel被繪製在labelsPanel中的其他JLabel之上,但是一旦JLabel超出該面板的範圍,JLabel就不會起作用。我試過把JLabel和JPanel都帶到Z序位0和1,並且首先繪製子面板,但是沒有一個具有預期的效果。 簡化代碼如下。 (我試着切出儘可能多的,所以請原諒我,如果有剩餘的代碼中的一些反常段)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class ExamplePanel extends JPanel implements MouseListener,
MouseMotionListener {
public JPanel labelsPanel;
public JPanel subPanel;
public ArrayList<JLabel> labels;
public ArrayList<ExamplePanel> panels;
private int xOffset = 0, yOffset = 0;
private Rectangle prevBounds = null;
private boolean isDragged;
public ExamplePanel(ArrayList<JLabel> labels, ArrayList<ExamplePanel> panels) {
this.invalidate();
this.labels = labels;
this.panels = panels;
addMouseListener(this);
this.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.GRAY),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
this.setLayout(new BorderLayout());
this.setAlignmentX(Component.LEFT_ALIGNMENT);
addLabels();
addPanels();
this.validate();
}
public void addLabels() {
if (labelsPanel != null) {
this.remove(labelsPanel);
}
labelsPanel = new JPanel(new GridBagLayout());
labelsPanel.setBorder(BorderFactory.createLineBorder(Color.GREEN));
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.CENTER;
c.ipadx = 50;
c.ipady = 30;
c.gridx = 0;
c.gridy = 0;
System.out.println("labels size: " + labels.size());
for (int i = 0; i < labels.size(); i++) {
c.gridx = i;
labels.get(i).addMouseListener(this);
labels.get(i).addMouseMotionListener(this);
labelsPanel.add(labels.get(i), c);
}
this.add(labelsPanel, BorderLayout.NORTH);
}
public void addPanels() {
System.out.println("panels size: " + panels.size());
if (subPanel != null) {
this.remove(subPanel);
}
subPanel = new JPanel(new BorderLayout());
subPanel.setBorder(BorderFactory.createLineBorder(Color.RED));
subPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
subPanel.setOpaque(false);
for (ExamplePanel panel : panels) {
subPanel.add(panel);
this.validate();
}
this.add(subPanel, BorderLayout.CENTER);
}
public void addLabel(JLabel label) {
labels.add(label);
}
public void addPanel(ExamplePanel panel) {
panels.add(panel);
}
@Override
public void mouseDragged(MouseEvent e) {
isDragged = true;
JLabel dragged = (JLabel) e.getSource();
int newX = (e.getX() + dragged.getBounds().x - xOffset < 0) ? 0 : e
.getX() + dragged.getBounds().x - xOffset;
int newY = (e.getY() + dragged.getBounds().y - yOffset < 0) ? 0 : e
.getY() + dragged.getBounds().y - yOffset;
dragged.setLocation(newX, newY);
}
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
System.out.println("++++++ Start Of Pressed ++++++");
System.out.println("Mouse Pressed At: " + arg0.getX() + " "
+ arg0.getY());
// Collect the clicked source and return if it's
// not a JLabel (might have to be modified if we
// want to click on other things than JLabels.
Object source = (Object) arg0.getSource();
if (source instanceof JLabel) {
JLabel jlb = (JLabel) arg0.getSource();
prevBounds = jlb.getBounds();
xOffset = arg0.getX();
yOffset = arg0.getY();
((JLabel) arg0.getSource()).getParent().setComponentZOrder(
((JLabel) arg0.getSource()), 0);
}
JLabel clicked = null;
if (source instanceof JLabel) {
clicked = (JLabel) source;
} else {
System.out.println("++++++ End Of Pressed ++++++");
return;
}
System.out.println("++++++ End Of Pressed ++++++");
}
@Override
public void mouseReleased(MouseEvent arg0) {
System.out.println("++++++ Start Of Released ++++++");
if (!isDragged) {
System.out.println("++++++ End Of Released, not dragging ++++++");
return;
}
isDragged = false;
xOffset = yOffset = 0;
// The object being dragged
JLabel source = (JLabel) arg0.getSource();
System.out.println("Source is: " + source.toString());
source.setBounds(prevBounds);
System.out.println("++++++ End Of Released ++++++");
}
}
一個基本的主類是如下;
import java.awt.Dimension;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Main extends JFrame {
public Main() {
setSize(new Dimension(600, 600));
ArrayList<JLabel> labels = new ArrayList<JLabel>();
JLabel label1 = new JLabel("Example 1");
JLabel label2 = new JLabel("Example 2");
labels.add(label1);
labels.add(label2);
ArrayList<ExamplePanel> panels = new ArrayList<ExamplePanel>();
ArrayList<ExamplePanel> panels2 = new ArrayList<ExamplePanel>();
System.out.println("LAbels size = " + labels.size());
ExamplePanel secondPanel = new ExamplePanel(labels, panels2);
panels.add(secondPanel);
ExamplePanel firstPanel = new ExamplePanel(labels, panels);
this.add(firstPanel);
this.setVisible(true);
}
public static void main (String [] args) {
Main main = new Main();
}
}
我省略了代碼實際添加JLabel以子面板,並刷新面板,因爲它是沒有必要這個問題。
三江源提前任何幫助
爲了更好地幫助越早,張貼[SSCCE(http://sscce.org/) –
所包含的代碼是最小的,我可以得到它,我很害怕。問題可以從這兩個類中運行。謝謝你的回覆 – Bruce0
*「包含的代碼是我能得到的最小的代碼」*'短'只是SSCCE的第一個任期,人們對它過分關注。如果他們是**源文件**(這是SSCCE的另一個條件),我會認爲這些代碼是潛在的SSCCE。 –