我想通过使用mouseDrag事件制作一个包含可移动图标的JLabel。它在使用默认布局时工作正常,但是当我通过指定null LayoutManager动画使用AbsoluteLayout时,动画非常糟糕。这是代码。
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Example
{
private static int pX, pY;
public static void main(String[] args)
{
ImageIcon myIcon = new ImageIcon("C:\\Users\\User\\Desktop\\x.png");
JFrame jf = new JFrame();
jf.setLayout(null);
jf.setSize(800, 800);
JLabel label = new JLabel(myIcon);
label.setSize(100, 100);
label.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent arg0) {
pX = arg0.getX();
pY = arg0.getY();
}
});
label.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent arg0) {
label.setLocation(label.getX() + arg0.getX() - pX, label.getY() + arg0.getY() - pY);
}
});
jf.add(label);
jf.setVisible(true);
}
}
编辑:添加了示例代码
答案 0 :(得分:0)
我很久以前写过这个闪烁或说摇晃的方法,
唯一的问题是,直到JComponent MouseExited Listener
被解雇的时间,您的组件才会闪烁,还有一个案例,当组件处于非常靠近的位置时,例如更少比10px
。
闪烁主要是针对JLabel,但是当你连接一个JButton或JPanel类型的组件时,它会垂直或水平摇动它。
此外,您还只允许在水平轴或垂直轴上摇晃。
尝试以下源代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
//Sometimes due to the Cursor contains the bounds of component
//and don't leave the component so the MouseExited event not fired
//which leads to the component not flickering issue
public class FlickerExample {
private static boolean flickerVertical = false;
private static boolean mouseEntered = false;
private static boolean isThreadBusy = false;
private static ArrayList<String>
compAbsoluteFixedFlagHashAddresses = new ArrayList<String>();
public static void main(String[] args) {
JLabel openLabel = new JLabel("click button to open", SwingConstants.CENTER);
openLabel.setForeground(Color.BLACK);
openLabel.setFont(new Font("Dialog", Font.BOLD, 22));
openLabel.setSize(80, 30);
flickerComponent(openLabel, false, false);
JButton openButton = new JButton("click me to open");
openButton.setFocusPainted(false);
openButton.setSize(80, 30);
openButton.setFont(openLabel.getFont());
flickerComponent(openButton, false, false);
JFrame frame = new JFrame();
frame.setTitle("Flicker JComponent");
frame.getContentPane().setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(500, 250, 300, 200);
frame.getContentPane().add(openLabel, BorderLayout.PAGE_START);
frame.getContentPane().add(openButton, BorderLayout.PAGE_END);
frame.setVisible(true);
}
public static void moveComponent(final JComponent comp, final Point p) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
comp.setLocation(p);
}
});
}
public static void setVertical(boolean bool){
flickerVertical = bool;
}
public static void flickerComponent(final JComponent comp){
flickerComponent(comp, false, false);
}
public synchronized static void flickerComponent(final JComponent comp, boolean absoluteFixedFlag, boolean requiredFlag){
if(absoluteFixedFlag){
flickerVertical = requiredFlag;
compAbsoluteFixedFlagHashAddresses.add(String.valueOf(comp.hashCode()) + ":" + String.valueOf(requiredFlag));
}
comp.addMouseListener(new MouseAdapter(){
@Override
public void mouseEntered(MouseEvent evt){
//System.out.println("mouse entered for flickering...");
if(!mouseEntered && !isThreadBusy){
isThreadBusy = true;
mouseEntered = true;
new Thread(new Runnable(){
public void run(){
try{
short min = 0, max = 0;
byte delay = 7;
Font tempFont = null;
final Point loc = comp.getLocation();
if(compAbsoluteFixedFlagHashAddresses.size()>0){
Iterator<String> itr = compAbsoluteFixedFlagHashAddresses.iterator();
String hc = String.valueOf(comp.hashCode());
loop:
while(itr.hasNext()){
String str = itr.next();
if(str.indexOf(hc) != -1){
flickerVertical = new Boolean(str.substring(str.indexOf(":")+1));
break loop;
}
}
itr = null;
}
if(comp instanceof JLabel){
tempFont = ((JLabel)comp).getFont();
((JLabel)comp).setFont(new Font(tempFont.getFamily(), tempFont.getStyle(), tempFont.getSize()+5));
}
if(flickerVertical){
min = (short) (loc.y - 4);
max = (short) (loc.y + 4);
if(comp instanceof JLabel)
((JLabel)comp).setVerticalTextPosition(SwingConstants.BOTTOM);
while(comp.getLocation().y != min){
moveComponent(comp, new Point(loc.x, comp.getY()-2));
Thread.sleep(delay);
}
if(comp instanceof JLabel)
((JLabel)comp).setVerticalTextPosition(SwingConstants.TOP);
delay = 3;
while(comp.getLocation().y != max){
moveComponent(comp, new Point(loc.x, comp.getY()+2));
Thread.sleep(delay);
}
if(comp instanceof JLabel)
((JLabel)comp).setVerticalTextPosition(SwingConstants.BOTTOM);
delay = 5;
while(comp.getLocation().y != loc.y){
moveComponent(comp, new Point(loc.x, comp.getY()-2));
Thread.sleep(delay);
}
if(comp instanceof JLabel)
((JLabel)comp).setVerticalTextPosition(SwingConstants.CENTER);
}else{
min = (short) (loc.x - 4);
max = (short) (loc.x + 4);
if(comp instanceof JLabel)
((JLabel)comp).setHorizontalTextPosition(SwingConstants.RIGHT);
while(comp.getLocation().x != min){
moveComponent(comp, new Point(comp.getX()-2, loc.y));
Thread.sleep(delay);
}
if(comp instanceof JLabel)
((JLabel)comp).setHorizontalTextPosition(SwingConstants.LEFT);
delay = 3;
while(comp.getLocation().x != max){
moveComponent(comp, new Point(comp.getX()+2, loc.y));
Thread.sleep(delay);
}
if(comp instanceof JLabel)
((JLabel)comp).setHorizontalTextPosition(SwingConstants.RIGHT);
delay = 5;
while(comp.getLocation().x != loc.x){
moveComponent(comp, new Point(comp.getX()-2, loc.y));
Thread.sleep(delay);
}
if(comp instanceof JLabel)
((JLabel)comp).setHorizontalTextPosition(SwingConstants.CENTER);
}
if(comp instanceof JLabel)
((JLabel)comp).setFont(tempFont);
moveComponent(comp, loc);
flickerVertical = !flickerVertical;
isThreadBusy = false;
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
}).start();
}
}
@Override
public void mouseExited(MouseEvent evt){
if(!isThreadBusy)
if(mouseEntered)
mouseEntered = false;
}
});
}
}