我希望能够在中心为JLabel
设置一个锚点,这样我就可以根据它来移动它。
答案 0 :(得分:3)
如果您试图将JLabel置于某一点的中心位置,那么您只需要简单的数学就可以做到这一点,仅此而已。
假设您有一个JLabel,或者我们将其命名为" component"的任何组件,它保存在JPanel中,或者我们将调用的任何容器中" container",并假设屏幕上有一个鼠标点 ,比如称为" mousePoint",那么数学很简单:
Point mousePoint = e.getLocationOnScreen();
Point containerLocation = container.getLocationOnScreen();
Dimension componentSize = component.getSize();
int x = mousePoint.x - componentSize.width / 2 - containerLocation.x;
int y = mousePoint.y - componentSize.height / 2 - containerLocation.y;
component.setLocation(x, y);
那就是它。
例如,假设您有两个JLabel,一个带有图像,另一个带有一些文本,那么您可以将相同的MouseListener和MouseMotionListener添加到两者,这将允许您按中心点拖动。以下是我在上述评论中提到的MCVE示例:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ClickDragLabel extends JPanel {
public static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/"
+ "Theodore_Comnenus-Ducas_cropped.jpg/133px-Theodore_Comnenus-Ducas_cropped.jpg";
private static final int PREF_W = 1000;
private static final int PREF_H = 850;
private JLabel imageLabel;
private JLabel textLabel = new JLabel("Some Random Text");
public ClickDragLabel(Icon icon) {
setBackground(Color.WHITE);
imageLabel = new JLabel(icon);
setLayout(null);
imageLabel.setSize(imageLabel.getPreferredSize());
textLabel.setSize(textLabel.getPreferredSize());
imageLabel.setLocation(250, 250);
textLabel.setLocation(10, 10);
MyMouse myMouse = new MyMouse();
imageLabel.addMouseListener(myMouse);
imageLabel.addMouseMotionListener(myMouse);
textLabel.addMouseListener(myMouse);
textLabel.addMouseMotionListener(myMouse);
add(imageLabel);
add(textLabel);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouse extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
center(e);
}
@Override
public void mouseReleased(MouseEvent e) {
center(e);
}
@Override
public void mouseDragged(MouseEvent e) {
center(e);
}
private void center(MouseEvent e) {
JComponent component = (JComponent) e.getSource();
Container container = component.getParent();
Point mousePoint = e.getLocationOnScreen();
Point containerLocation = container.getLocationOnScreen();
Dimension componentSize = component.getSize();
int x = mousePoint.x - componentSize.width / 2 - containerLocation.x;
int y = mousePoint.y - componentSize.height / 2 - containerLocation.y;
component.setLocation(x, y);
container.repaint();
}
}
private static void createAndShowGui() {
Image img = null;
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
Icon icon = new ImageIcon(img);
ClickDragLabel mainPanel = new ClickDragLabel(icon);
JFrame frame = new JFrame("Click-Drag Label");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
发布这个之后,如果我没有提到使用空布局的弊端,那将是我的疏忽。虽然null布局和setBounds()
似乎是Swing新手,比如创建复杂GUI的最简单和最好的方法,但是你创建的Swing GUI越多,你在使用它们时会遇到更严重的困难。 。当GUI调整大小时,他们不会调整组件的大小,他们是增强或维护的皇室女巫,当他们放置在滚动窗格中时,他们完全失败,当他们在所有平台或屏幕分辨率不同时看起来很糟糕原来的。我只将它们用于动画,例如上面的动画,而不是别的。
答案 1 :(得分:3)
有没有办法在JLabel上设置锚点?
您可以通过将EmptyBorder
设置并更改为标签来实现您的目的。
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.*;
public class MovableLabel {
private JComponent ui = null;
String anchorString = new String(Character.toChars(9875));
private JLabel label = new JLabel(anchorString);
int pad = 200;
SpinnerNumberModel xModel = new SpinnerNumberModel(0, 0, pad, 1);
SpinnerNumberModel yModel = new SpinnerNumberModel(0, 0, pad, 1);
MovableLabel() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
Font font = null;
for (Font f : fonts) {
if (f.canDisplayUpTo(anchorString) < 0) {
font = f.deriveFont(40f);
break;
}
}
label.setFont(font);
label.setBackground(Color.BLUE);
setBorder();
ui.add(label);
JToolBar tb = new JToolBar();
ui.add(tb, BorderLayout.PAGE_START);
ChangeListener changeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
setBorder();
}
};
tb.add(new JLabel("X"));
JSpinner xSpinner = new JSpinner(xModel);
xSpinner.addChangeListener(changeListener);
tb.add(xSpinner);
tb.add(new JLabel("Y"));
JSpinner ySpinner = new JSpinner(yModel);
ySpinner.addChangeListener(changeListener);
tb.add(ySpinner);
}
private void setBorder() {
int x = xModel.getNumber().intValue();
int y = yModel.getNumber().intValue();
EmptyBorder border = new EmptyBorder(x, y, pad - x, pad - y);
label.setBorder(border);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
MovableLabel o = new MovableLabel();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}