InfiniteProgressDemo 的问题
我使用 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) {
}
}
I have implemented a small example using InfiniteProgressDemo and works perfectly, showing the "loading wheel" rotating at the center of the frame.
Now I have ported it to my program. I have a button for a connect action (do not worry about the 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 {
}
}
The only file I needed from the InfiniteProgressDemo demo was InfiniteProgressPane.
When I execute and push my button, the "loading wheel" appears, but not at the center of the frame. It appears on one corner... next second it appears on another corner, and so on. I don't know what's wrong.
I also attach here the 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) {
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最后的问题是 getWidth() 和 getHeight() 方法无法获取主窗口 JFrame 的正确尺寸,因为它们被称为直接向前。修改 InfiniteProgressDemo 构造函数以接收 JFrame myFrame,并调用 myFrame.getWidth() 和 myFrame.getHeight() 使动画在屏幕中央正常工作。
Finally the problem is that getWidth() and getHeight() methods aren't getting the correct dimensions of the JFrame of my main windows, because they are called straigth forwards. Modifying the InfiniteProgressDemo constructors to receive a JFrame myFrame, and calling myFrame.getWidth() and myFrame.getHeight() got the animation working correctly in the center of the screen.