使用AbsoluteLayout移动JLabel时,Swing GUI动画闪烁

时间:2018-01-13 07:56:30

标签: java swing

我想通过使用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);
    }
}

编辑:添加了示例代码

1 个答案:

答案 0 :(得分:0)

我很久以前写过这个闪烁或说摇晃的方法,

  1. 唯一的问题是,直到JComponent MouseExited Listener被解雇的时间,您的组件才会闪烁,还有一个案例,当组件处于非常靠近的位置时,例如更少比10px

  2. 闪烁主要是针对JLabel,但是当你连接一个JButton或JPanel类型的组件时,它会垂直或水平摇动它。

  3. 此外,您还只允许在水平轴或垂直轴上摇晃。

  4. Flick JComponent

    尝试以下源代码:

    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;
                }
    
            });
        }
    
    }