java - InfiniteProgressDemo 的问题

标签 java loading frame glasspane

我使用 InfiniteProgressDemo 实现了一个小示例并且工作完美,显示“加载轮”在框架中心旋转。

现在我已经将它移植到我的程序中了。我有一个用于连接操作的按钮(不用担心 BussinessException):

public class ConnectAction extends AbstractAction {
private JFrame framePrincipal;
private InfiniteProgressPanel glassPane;


/**
 * Constructor
 * @param m
 * @param pNodos
 * @param pGraficas
 * @param front
 * @throws BusinessException
 */
public ConnectAction(Main main, DockFrontend front) throws BusinessException{
    super();
    this.framePrincipal = main.getFramePrincipal();
    this.glassPane = new InfiniteProgressPanel();
    framePrincipal.setGlassPane(glassPane);
}

private void perform() throws BusinessException {

    // DOING SOME HEAVY STUFF...

    System.out.println("You've successfully waited :)");

    glassPane.stop();
}

@Override
public Object execute() throws BusinessException {  
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            glassPane.start();
            Thread performer = new Thread(new Runnable() {
                public void run() {
                    try {
                        perform();
                    } catch (BusinessException e) {
                        e.printStackTrace();
                    }
                }
            }, "Performer");
            performer.start();
        }
    });

    return null;
}

@Override
public void redo() throws BusinessException {
    // TODO Auto-generated method stub

}

@Override
public void undo() throws BusinessException {
    // TODO Auto-generated method stub

}

@Override
protected void initServices() throws BusinessException {

}

}

InfiniteProgressDemo 演示中我需要的唯一文件是 InfiniteProgressPane。

当我执行并按下按钮时,“加载轮”出现,但不在框架的中心。它出现在一个角落......下一秒它出现在另一个角落,依此类推。我不知道出了什么问题。

我还附上了 InfiniteProgressDemo:

    public class InfiniteProgressPanel extends JComponent implements MouseListener
{
    protected Area[]  ticker     = null;
    protected Thread  animation  = null;
    protected boolean started    = false;
    protected int     alphaLevel = 0;
    protected int     rampDelay  = 300;
    protected float   shield     = 0.70f;
    protected String  text       = "";
    protected int     barsCount  = 14;
    protected float   fps        = 15.0f;

    protected RenderingHints hints = null;

    public InfiniteProgressPanel()
    {
        this("");
    }

    public InfiniteProgressPanel(String text)
    {
        this(text, 14);
    }

    public InfiniteProgressPanel(String text, int barsCount)
    {
        this(text, barsCount, 0.70f);
    }

    public InfiniteProgressPanel(String text, int barsCount, float shield)
    {
        this(text, barsCount, shield, 15.0f);
    }

    public InfiniteProgressPanel(String text, int barsCount, float shield, float fps)
    {
        this(text, barsCount, shield, fps, 300);
    }

    public InfiniteProgressPanel(String text, int barsCount, float shield, float fps, int rampDelay)
    {
        this.text      = text;
        this.rampDelay = rampDelay >= 0 ? rampDelay : 0;
        this.shield    = shield >= 0.0f ? shield : 0.0f;
        this.fps       = fps > 0.0f ? fps : 15.0f;
        this.barsCount = barsCount > 0 ? barsCount : 14;

        this.hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        this.hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        this.hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    }

    public void setText(String text)
    {
        repaint();
        this.text = text;
    }

    public String getText()
    {
        return text;
    }

    public void start()
    {
        addMouseListener(this);
        setVisible(true);
        ticker = buildTicker();
        animation = new Thread(new Animator(true));
        animation.start();
    }

    public void stop()
    {
        if (animation != null) {
            animation.interrupt();
            animation = null;
            animation = new Thread(new Animator(false));
            animation.start();
        }
    }

    public void interrupt()
    {
        if (animation != null) {
            animation.interrupt();
            animation = null;

            removeMouseListener(this);
            setVisible(false);
        }
    }

    public void paintComponent(Graphics g)
    {
        if (started)
        {
            int width  = getWidth();
            int height = getHeight();

            double maxY = 0.0; 

            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHints(hints);

            g2.setColor(new Color(255, 255, 255, (int) (alphaLevel * shield)));
            g2.fillRect(0, 0, getWidth(), getHeight());

            for (int i = 0; i < ticker.length; i++)
            {
                int channel = 224 - 128 / (i + 1);
                g2.setColor(new Color(channel, channel, channel, alphaLevel));
                g2.fill(ticker[i]);

                Rectangle2D bounds = ticker[i].getBounds2D();
                if (bounds.getMaxY() > maxY)
                    maxY = bounds.getMaxY();
            }

            if (text != null && text.length() > 0)
            {
                FontRenderContext context = g2.getFontRenderContext();
                TextLayout layout = new TextLayout(text, getFont(), context);
                Rectangle2D bounds = layout.getBounds();
                g2.setColor(getForeground());
                layout.draw(g2, (float) (width - bounds.getWidth()) / 2,
                                (float) (maxY + layout.getLeading() + 2 * layout.getAscent()));
            }
        }
    }

    private Area[] buildTicker()
    {
        Area[] ticker = new Area[barsCount];
        Point2D.Double center = new Point2D.Double((double) getWidth() / 2, (double) getHeight() / 2);
        double fixedAngle = 2.0 * Math.PI / ((double) barsCount);

        for (double i = 0.0; i < (double) barsCount; i++)
        {
            Area primitive = buildPrimitive();

            AffineTransform toCenter = AffineTransform.getTranslateInstance(center.getX(), center.getY());
            AffineTransform toBorder = AffineTransform.getTranslateInstance(45.0, -6.0);
            AffineTransform toCircle = AffineTransform.getRotateInstance(-i * fixedAngle, center.getX(), center.getY());

            AffineTransform toWheel = new AffineTransform();
            toWheel.concatenate(toCenter);
            toWheel.concatenate(toBorder);

            primitive.transform(toWheel);
            primitive.transform(toCircle);

            ticker[(int) i] = primitive;
        }

        return ticker;
    }

    private Area buildPrimitive()
    {
        Rectangle2D.Double body = new Rectangle2D.Double(6, 0, 30, 12);
        Ellipse2D.Double   head = new Ellipse2D.Double(0, 0, 12, 12);
        Ellipse2D.Double   tail = new Ellipse2D.Double(30, 0, 12, 12);

        Area tick = new Area(body);
        tick.add(new Area(head));
        tick.add(new Area(tail));

        return tick;
    }

    protected class Animator implements Runnable
    {
        private boolean rampUp = true;

        protected Animator(boolean rampUp)
        {
            this.rampUp = rampUp;
        }

        public void run()
        {
            Point2D.Double center = new Point2D.Double((double) getWidth() / 2, (double) getHeight() / 2);
            double fixedIncrement = 2.0 * Math.PI / ((double) barsCount);
            AffineTransform toCircle = AffineTransform.getRotateInstance(fixedIncrement, center.getX(), center.getY());

            long start = System.currentTimeMillis();
            if (rampDelay == 0)
                alphaLevel = rampUp ? 255 : 0;

            started = true;
            boolean inRamp = rampUp;

            while (!Thread.interrupted())
            {
                if (!inRamp)
                {
                    for (int i = 0; i < ticker.length; i++)
                        ticker[i].transform(toCircle);
                }

                repaint();

                if (rampUp)
                {
                    if (alphaLevel < 255)
                    {
                        alphaLevel = (int) (255 * (System.currentTimeMillis() - start) / rampDelay);
                        if (alphaLevel >= 255)
                        {
                            alphaLevel = 255;
                            inRamp = false;
                        }
                    }
                } else if (alphaLevel > 0) {
                    alphaLevel = (int) (255 - (255 * (System.currentTimeMillis() - start) / rampDelay));
                    if (alphaLevel <= 0)
                    {
                        alphaLevel = 0;
                        break;
                    }
                }

                try
                {
                    Thread.sleep(inRamp ? 10 : (int) (1000 / fps));
                } catch (InterruptedException ie) {
                    break;
                }
                Thread.yield();
            }

            if (!rampUp)
            {
                started = false;
                repaint();

                setVisible(false);
                removeMouseListener(InfiniteProgressPanel.this);
            }
        }
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }
}

最佳答案

最后,问题是 getWidth() 和 getHeight() 方法无法获取主窗口 JFrame 的正确尺寸,因为它们被称为直接向前。修改 InfiniteProgressDemo 构造函数以接收 JFrame myFrame,并调用 myFrame.getWidth() 和 myFrame.getHeight() 使动画在屏幕中央正常工作。

关于java - InfiniteProgressDemo 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7645244/

相关文章:

java - JComboBox 可编辑且选择时为空白

jquery - 在jquery中,如何显示ajax进度图像而不将控件向右移动

css - 定位框架集或框架

java - 使用 java.lang.String.matches() 查找匹配项

java - 如何使用java从一组扫描文档中检测空白图像?

javascript - 找到最接近的#loading 并显示它?

javascript - 为什么这个 "loading message"脚本在 FF 中不起作用?(javascript)

swift - 当我从另一个 View 返回后, View 框架改变了它的位置[swift]

尝试将 Siena 与 Play Framework 一起使用时出现 java.lang.AbstractMethodError

java - 数组索引越界错误