任务:有2个标签按行连接,用户必须能够用鼠标移动每个标签,并且标签之间的连接必须相应地移动。
这是我的代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
class BackgroundJPanel extends JPanel {
BackgroundJPanel() {
this.setBounds(0, 0, 200, 200);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.orange);
g.fillRect(0, 0, 198, 198);
g.setColor(Color.black);
g.drawRect(0, 0, 198, 198);
}
}
class LinkJPanel extends JPanel {
JLabel[] labels = null;
LinkJPanel(JLabel[] labelsIn) {
labels = labelsIn;
this.setBounds(0, 0, 200, 200);
this.setOpaque(false);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(labels[0].getX(), labels[0].getY(),
labels[1].getX(), labels[1].getY());
}
}
class LabelJPanel extends JPanel {
AllPanel allPanel = null;
LabelJPanel(AllPanel allPanelIn) {
allPanel = allPanelIn;
this.setOpaque(false);
JLabel[] labels = allPanel.labels;
labels[0] = new JLabel("11");
this.add(labels[0]);
labels[1] = new JLabel("22");
this.add(labels[1]);
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
this.addMouseMotionListener(myMouseAdapter);
this.addMouseListener(myMouseAdapter);
}
class MyMouseAdapter extends MouseAdapter {
JLabel labelToMove = null;
int startDeltaX = -1;
int startDeltaY = -1;
JLabel whichLabel(MouseEvent e) {
for (JLabel label : allPanel.labels) {
int deltaX = e.getX() - label.getX();
int deltaY = e.getY() - label.getY();
if ((deltaX >= 0)
&& (deltaX < label.getPreferredSize().width)
&& (deltaY >= 0)
&& (deltaY < label.getPreferredSize().height)) {
return label;
}
}
return null;
}
@Override
public void mousePressed(MouseEvent e) {
labelToMove = whichLabel(e);
if (labelToMove != null) {
startDeltaX = labelToMove.getX() - e.getX();
startDeltaY = labelToMove.getY() - e.getY();
}
}
@Override
public void mouseDragged(MouseEvent e) {
if (labelToMove != null) {
updateLocation(e);
}
}
@Override
public void mouseReleased(MouseEvent e) {
labelToMove = null;
}
public void updateLocation(MouseEvent e) {
int newXCoord = e.getX() + startDeltaX;
int newYCoord = e.getY() + startDeltaY;
labelToMove.setBounds(newXCoord, newYCoord,
labelToMove.getPreferredSize().width,
labelToMove.getPreferredSize().height);
//allPanel.backgroundJPanel.repaint();
allPanel.linkJPanel.repaint();
}
}
}
class AllPanel extends JPanel {
BackgroundJPanel backgroundJPanel = null;
LinkJPanel linkJPanel = null;
LabelJPanel labelJPanel = null;
JLabel[] labels = null;
AllPanel() {
this.setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(200, 200));
labels = new JLabel[2];
backgroundJPanel = new BackgroundJPanel();
this.add(backgroundJPanel);
linkJPanel = new LinkJPanel(labels);
this.add(linkJPanel);
labelJPanel = new LabelJPanel(this);
this.add(labelJPanel);
this.setComponentZOrder(backgroundJPanel, 2);
this.setComponentZOrder(linkJPanel, 1);
this.setComponentZOrder(labelJPanel, 0);
}
}
class MyFrame extends JFrame {
MyFrame() {
this.setTitle("Test");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(new AllPanel());
this.pack();
this.setVisible(true);
this.setResizable(false);
}
}
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new MyFrame();
}
});
}
}
我使用3个JPanel - 一个用于背景,一个用于绘制连接线,一个用于绘制2个标签。用于绘制标签的JPanel具有MouseMotion和Mouse侦听器。当出现一些鼠标操作时,代码检查必须移动哪个标签,然后更改该标签坐标并用连接线重新绘制JPanel。
所有工作正常,直到我尝试用背景重新绘制JPanel。如果我取消注释该行
//allPanel.backgroundJPanel.repaint();
行动后JLabel和行开始消失。 有人可以解释为什么会这样吗?