2つのJPanels-labelsPanelとsubPanelで構成されるJPanelを拡張するクラスExamplePanelがあります。Labelspanelには任意のJLabelが含まれ、subPanelにはExamplePanelのネストされたインスタンスのさまざまなインスタンスが含まれます。
JLabelをネストされたインスタンスにドラッグできるようにしたいのですが、ドラッグすると、サブパネルの後ろに移動してしまいます。答えはsetComponentZOrderメソッドにあると思いますが、私はそれを前進させていません。これにより、JLabelはlabelsPanel内の他の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をサブパネルに追加してパネルを更新するコードを省略しました。
よろしくお願いします