JTabbedPane:在选项卡中显示任务进度

Pac*_*aco 3 java swing jtabbedpane jprogressbar

我有一个简单的Swing Java应用程序执行搜索,结果显示在一个新选项卡中.搜索正在运行时,我想在选项卡的标题中显示进度图标或动画.我尝试添加一个gif图标,但它没有动画.有没有理由不这样做?

Rob*_*bin 11

关于进度条Swing教程(并显示一般的进度)是一个非常好的起点.它向您展示了如何使用a在工作线程上执行持久操作SwingWorker,并以特定间隔更新UI以向用户显示持久操作的进度.还有另一个教程可用于获取有关Swing中的并发性的更多信息SwingWorker

和往常一样,这个网站充满了例子.例如,我之前的答案使用SwingWorker该类向用户显示进度

编辑

因为我错过了你问题标签部分的标题.您可以创建"进度图标"并在选项卡上进行设置.该SwingWorker则可以使用更新的图标.

这种图标的一个例子是 示例进度图标,这基本上是每次进行一些进展时旋转的图像.该选项卡窗格教程将向您展示如何将图标添加到您的标签(甚至可以使用自定义组件)

EDIT2

因为看起来我的Mac与JDK1.7结合使得在其他系统上显示GIF动画更加容易,我创建了一个小型SSCCE,非常类似于Andrew,但带有一个看起来不像它的旋转图标我引用了'疯狂的黑猩猩'.旋转图标代码来自此站点(我使用了精简版并添加了计时器).我唯一不高兴的事实是我需要将选项卡式窗格传递给旋转图标才能触发.可能的解决方案是将计时器拉到RotatingIcon课堂外,但是嘿,它只是一个SSCCE.图片不包括在内,但可以在Google上找到.

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;
import javax.swing.Timer;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;

public class ProgressTabbedPane {

  public static void main( String[] args ) {
    EventQueue.invokeLater( new Runnable() {
      @Override
      public void run() {
        JFrame frame = new JFrame( "RotatingIcon" );
        JTabbedPane tabbedPane = new JTabbedPane(  );
        tabbedPane.addTab( "Searching", new RotatingIcon( new ImageIcon( "resources/images/progress-indeterminate.png" ), tabbedPane ),
                           new JLabel( new ImageIcon( "resources/images/rotatingIcon.gif" ) ) );
        frame.getContentPane().add( tabbedPane );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible( true );
      }
    } );
  }

  private static class RotatingIcon implements Icon{
    private final Icon delegateIcon;
    private double angleInDegrees = 90;
    private final Timer rotatingTimer;
    private RotatingIcon( Icon icon, final JComponent component ) {
      delegateIcon = icon;
      rotatingTimer = new Timer( 100, new ActionListener() {
        @Override
        public void actionPerformed( ActionEvent e ) {
          angleInDegrees = angleInDegrees + 10;
          if ( angleInDegrees == 360 ){
            angleInDegrees = 0;
          }
          component.repaint();
        }
      } );
      rotatingTimer.setRepeats( false );
      rotatingTimer.start();
    }

    @Override
    public void paintIcon( Component c, Graphics g, int x, int y ) {
      rotatingTimer.stop();
      Graphics2D g2 = (Graphics2D )g.create();
      int cWidth = delegateIcon.getIconWidth() / 2;
      int cHeight = delegateIcon.getIconHeight() / 2;
      Rectangle r = new Rectangle(x, y, delegateIcon.getIconWidth(), delegateIcon.getIconHeight());
      g2.setClip(r);
      AffineTransform original = g2.getTransform();
      AffineTransform at = new AffineTransform();
      at.concatenate(original);
      at.rotate(Math.toRadians( angleInDegrees ), x + cWidth, y + cHeight);
      g2.setTransform(at);
      delegateIcon.paintIcon(c, g2, x, y);
      g2.setTransform(original);
      rotatingTimer.start();
    }

    @Override
    public int getIconWidth() {
      return delegateIcon.getIconWidth();
    }

    @Override
    public int getIconHeight() {
      return delegateIcon.getIconHeight();
    }
  } 
}
Run Code Online (Sandbox Code Playgroud)

截图供参考.遗憾的是,图标不会在屏幕截图中旋转. SSCCE截图

  • @AndrewThompson在我的Mac(JDK1.7)上,图像很好地旋转,没有任何额外的步骤.两者都在选项卡中作为JLabel中的内容.将尝试使用静态图标进行操作 (2认同)

And*_*son 7

动画图像作为选项卡图标

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

public class ImageOnTab {

    ImageOnTab() {

        final BufferedImage image = new BufferedImage(
            32,32,BufferedImage.TYPE_INT_RGB);
        final JTabbedPane pane = new JTabbedPane();
        ImageIcon icon = new ImageIcon(image);
        pane.addTab( "Progress", icon, new JTree() );

        ActionListener listener = new ActionListener() {

            int x = 0;
            int step = 1;

            public void actionPerformed(ActionEvent ae) {
                Graphics g = image.createGraphics();
                x+=step;
                if (step>0) {
                    if (x>32) {
                        step=-step;
                    }
                } else if (x<0) {
                    step=-step;
                }

                g.setColor(Color.ORANGE);
                g.fillRect(0,0,32,32);

                g.setColor(Color.RED);
                g.fillRect(0,0,x,32);

                g.dispose();

                pane.repaint();
            }
        };

        Timer timer = new Timer(100,listener);
        timer.start();

        JOptionPane.showMessageDialog(null, pane);
    }

    public static void main(String[] args) throws Exception {
        //Create the GUI on the event dispatching thread
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                new ImageOnTab();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 优秀!另请参阅此相关[示例](http://stackoverflow.com/a/3484251/230513). (3认同)
  • 我认为这两者在所有方面都是互补的; 引用. (2认同)