【问题标题】:is there a way to make JTextField do a little shake when input from the user is invalid?当用户的输入无效时,有没有办法让 JTextField 稍微摇晃一下?
【发布时间】:2019-10-24 00:29:36
【问题描述】:

我正在为我的课程作业创建一个程序,并希望它做得尽可能好。我想知道当输入错误的密码时,有没有办法让 JTextField 像在 Mac 中一样进行小摇晃? 在我的情况下,我希望用户输入一个数字,而不是字符串,而不是空白,如果它没有输入,我希望文本字段做一点摇动:)

【问题讨论】:

  • “有办法吗?”是的,总是有办法的。一个更好的问题是“我该怎么做?”

标签: java user-interface


【解决方案1】:

我很久以前就把它放在一起了。可以在以下位置找到更简洁的版本:https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/ui/ex/ShakeablePanel.java

package tjacobs.ui.ex;

import java.awt.BorderLayout;

import java.awt.Component;

import java.awt.Graphics;

import java.util.Properties;

import java.util.Random;



import javax.swing.JPanel;



import tjacobs.ui.dialogs.ParamDialog;

import tjacobs.ui.dialogs.StandardDialog;



public class ShakeablePanel extends JPanel {



    public static final long serialVersionUID = 0;



    public static final int SMALL_SHAKE = 3;

    public static final int MEDIUM_SHAKE = 8;

    public static final int LARGE_SHAKE = 15;



    public static final long SHORT_TIME = 300;

    public static final long MEDIUM_TIME = 1000;

    public static final long LONG_TIME = 2000;



    private int xOffset = 0, yOffset = 0;



    public ShakeablePanel() {

        super();

    }



    public ShakeablePanel(Component c) {

        super(new BorderLayout());

        add(c, BorderLayout.CENTER);

    }

    /**

     * Shakes the panel. Will not work right if called in the

     * GUI painter thread

     * @param width_variance

     * @param height_variance

     * @param time

     */

    public void _shake(int width_variance, int height_variance, long duration) {

        long time = System.currentTimeMillis();

        long endTime = time + duration;

        Random r = new Random(time);

        while (System.currentTimeMillis() < endTime) {

            xOffset = r.nextInt(width_variance) - width_variance / 2;

            yOffset = r.nextInt(height_variance) - height_variance / 2;

            repaint();

            try {

                Thread.sleep(50);

            }

            catch (InterruptedException ie) {

                return;

            }

        }

        xOffset = 0;

        yOffset = 0;

        repaint();

    }



    public void shake(int variance, long duration) {

        shake(variance, variance, duration);

    }



    public void shake(final int width_variance, final int height_variance, final long duration) {

        Runnable r = new Runnable() {

            public void run() {

                _shake(width_variance, height_variance, duration);

            }

        };

        Thread t = new Thread(r);

        t.start();

    }



    /**

     * Overrides paint in JPanel.

     * 

     * Must override paint and not just paintComponent so

     * that children will be shaken as well

     */

    public void paint(Graphics g) {

        g.translate(xOffset, yOffset);

        super.paint(g);

    }



    public static void main(String[] args) {

        final ShakeablePanel sp = new ShakeablePanel();

        final ParamDialog pd = new ParamDialog(new String[] {

            "Time(SHORT MEDIUM LONG" + ParamDialog.COMBO,

            "Shaking(SMALL MEDIUM LARGE" + ParamDialog.COMBO

        }) {

            /**

             * 

             */

            private static final long serialVersionUID = 1L;



            public boolean showApplyButton() {



                return true;

            }



            public void apply() {

                Properties p = getProperties();

                String time = p.getProperty("Time");

                String shaking = p.getProperty("Shaking");

                int shake = shaking.equals("SMALL") ? SMALL_SHAKE : shaking.equals("MEDIUM") ? MEDIUM_SHAKE : LARGE_SHAKE;

                long tm = time.equals("SHORT") ? SHORT_TIME : time.equals("MEDIUM") ? MEDIUM_TIME : LONG_TIME;

                sp.shake(shake, shake, tm);

                //sp.shake(MEDIUM_SHAKE, MEDIUM_SHAKE, MEDIUM_TIME);

            }

        };

        Component main = pd.getMainContent();

        sp.setLayout(new BorderLayout());

        sp.add(main, BorderLayout.CENTER);

        //final ShakeablePanel sp = new ShakeablePanel(main);

        pd.setMainContent(sp);

        StandardDialog.showStandardDialog(pd);

    }



}

【讨论】:

  • 现在看这个,重写shake 并使用swing timer 而不是启动一个单独的线程可能更有意义...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-31
  • 1970-01-01
  • 2021-03-26
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
  • 2012-08-09
相关资源
最近更新 更多