Java JTabbedPane:在选项卡中显示任务进度
我有一个简单的Swing Java应用程序来执行搜索,结果显示在一个新的选项卡中。在搜索运行时,我希望在选项卡的标题中显示进度图标或动画。我尝试添加一个gif图标,但它没有动画效果。这有什么不起作用的原因吗?这是一个很好的开始(并显示出总体进展)。它向您展示了如何使用Java JTabbedPane:在选项卡中显示任务进度,java,swing,jtabbedpane,jprogressbar,Java,Swing,Jtabbedpane,Jprogressbar,我有一个简单的Swing Java应用程序来执行搜索,结果显示在一个新的选项卡中。在搜索运行时,我希望在选项卡的标题中显示进度图标或动画。我尝试添加一个gif图标,但它没有动画效果。这有什么不起作用的原因吗?这是一个很好的开始(并显示出总体进展)。它向您展示了如何使用SwingWorker在工作线程上执行长期操作,并以一定的间隔更新UI,以向用户显示长期操作的进度。有另一个教程可获取有关 和往常一样,这个网站充满了例子。例如,使用SwingWorker类向用户显示进度 编辑 因为我错过了你问题的
SwingWorker
在工作线程上执行长期操作,并以一定的间隔更新UI,以向用户显示长期操作的进度。有另一个教程可获取有关
和往常一样,这个网站充满了例子。例如,使用SwingWorker
类向用户显示进度
编辑
因为我错过了你问题的一部分。您可以创建一个“进度图标”,并在选项卡上进行设置。然后可以使用SwingWorker
更新图标
这类图标的一个例子是,它基本上是一个图像,每次取得进展时都会旋转。演示如何将图标添加到选项卡(甚至使用自定义组件)
编辑2
由于我的Mac电脑与JDK1.7的结合使得在其他系统上显示动画gif变得更加容易,因此我也创建了一个小型的SSCCE,与Andrew的非常相似,但带有一个旋转图标,它看起来不像是由“疯狂的黑猩猩”创建的。旋转图标代码来自(我使用了精简版并添加了计时器)。唯一让我不太高兴的是,我需要将我的选项卡式窗格传递给旋转图标来触发。可能的解决方案是将计时器拉到旋转图标
类之外,但嘿,这只是一个SSCCE。图片不包括在内,但是通过谷歌找到的
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();
}
}
}
供参考的屏幕截图。遗憾的是,图标在屏幕截图中没有旋转。
import javax.swing.*;
导入java.awt.*;
导入java.awt.event.*;
导入java.awt.image.*;
公共类ImageOnTab{
ImageOnTab(){
最终缓冲区图像=新缓冲区图像(
32,32,BuffereImage.TYPE_INT_RGB);
最终JTabbedPane窗格=新JTabbedPane();
ImageIcon图标=新的ImageIcon(图像);
addTab(“进度”,图标,新JTree());
ActionListener=新建ActionListener(){
int x=0;
int步长=1;
已执行的公共无效行动(行动事件ae){
Graphics g=image.createGraphics();
x+=阶跃;
如果(步骤>0){
如果(x>32){
步骤=-步骤;
}
}如果(x@Andrew Thompson)
It would be great if the J2SE supported animated GIFs 'out of the box'
in more situations. I tried that animated GIF (nice image, BTW) as a
tab icon, and no, it remains static.
我不想通篇阅读,但请您和“垃圾神陛下”一起编写代码
1) 使用Htlm
(我不擅长纯Html)
2) 使用GlassPane
和JLabel#(setOpaque(true))
3) 使用JLayer
(JXLayer
更好,因为Sn'Oracle remove importional methods==my view)
4) 你必须
5) Rob曾多次表示支持JTabbedPane
代码
import java.awt.*;
导入java.awt.event.*;
导入java.net.MalformedURLException;
导入java.net.URL;
导入java.util.Random;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.swing.*;
//https://stackoverflow.com/questions/3483485/java-jprogressbar-or-equivalent-in-a-jtabbedpane-tab-title/3484251#3484251
公共类JTabbedTest{
私有JFrame f=新JFrame();
私有JTabbedPane jtp=新JTabbedPane();
私有URL=null;
公共jtabbetest(){
试一试{
url=新url(“http://pscode.org/media/starzoom-thumb.gif");
}捕获(格式错误){
Logger.getLogger(jtabbetest.class.getName()).log(Level.SEVERE,null,ex);
}
ImageIcon ii=新的ImageIcon(url);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jtp.setPreferredSize(新尺寸(400200));
createTab(“红色”,Color.RED);
createTab(“绿色”,Color.GREEN);
createTab(“蓝色”,Color.BLUE);
f、 添加(jtp,BorderLayout.CENTER);
jtp.setTitleAt(2“”);
//更改“禁用”选项卡的前景色
/*jtp.setTitleAt(2“)
+jtp.getTitleAt(2)+“”*/
矩形tabBounds=jtp.getBoundsAt(0);
容器玻璃窗格=(容器)f.getRootPane().getGlassPane();
玻璃窗格。设置为可见(真);
setLayout(新的GridBagLayout());
GridBagConstraints gbc=新的GridBagConstraints();
gbc.weightx=1.0;
gbc.weighty=1.0;
gbc.fill=GridBagConstraints.NONE;
gbc.insets=新的insets(tabBounds.y+23,0,0,5);
gbc.anchor=GridBagConstraints.NORTHEAST;
JButton按钮=新JButton(“我的按钮位置”,ii);
setPreferredSize(新维度(button.getPreferredSize().width,(int)tabBounds.getHeight()-2));
玻璃窗格。添加(按钮,gbc);
f、 包装();
f、 setVisible(真);
}
私有void createTab(字符串名称、颜色){
ProgressIcon图标=新的ProgressIcon(颜色);
addTab(名称、图标、新颜色面板(jtp、图标));
}
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
JTabbedTest JTabbedTest=新的JTabbedTest();
}
});
}
私有静态类ColorPanel扩展JPanel实现ActionListener{
私有静态最终随机rnd=新随机();
私有静态最终长serialVersionUID=1L;
专用最终计时器=新计时器(1000,此);
专用最终JLabel标签=新JLabel(“Stackoverflow!”);
私人最终JTabbedPane pa
It would be great if the J2SE supported animated GIFs 'out of the box'
in more situations. I tried that animated GIF (nice image, BTW) as a
tab icon, and no, it remains static.
import java.awt.*;
import java.awt.event.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
//https://stackoverflow.com/questions/3483485/java-jprogressbar-or-equivalent-in-a-jtabbedpane-tab-title/3484251#3484251
public class JTabbedTest {
private JFrame f = new JFrame();
private JTabbedPane jtp = new JTabbedPane();
private URL url = null;
public JTabbedTest() {
try {
url = new URL("http://pscode.org/media/starzoom-thumb.gif");
} catch (MalformedURLException ex) {
Logger.getLogger(JTabbedTest.class.getName()).log(Level.SEVERE, null, ex);
}
ImageIcon ii = new ImageIcon(url);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jtp.setPreferredSize(new Dimension(400, 200));
createTab("Reds", Color.RED);
createTab("Greens", Color.GREEN);
createTab("Blues", Color.BLUE);
f.add(jtp, BorderLayout.CENTER);
jtp.setTitleAt(2, "<html><img src=" + ii + " width=20 height=20></img></html>");
// change foreground Color for disabled tab
/*jtp.setTitleAt(2, "<html><font color=" + (jtp.isEnabledAt(2) ? "black" : "red") + ">"
+ jtp.getTitleAt(2) + "</font></html>");*/
Rectangle tabBounds = jtp.getBoundsAt(0);
Container glassPane = (Container) f.getRootPane().getGlassPane();
glassPane.setVisible(true);
glassPane.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.NONE;
gbc.insets = new Insets(tabBounds.y + 23, 0, 0, 5);
gbc.anchor = GridBagConstraints.NORTHEAST;
JButton button = new JButton("My Button Position", ii);
button.setPreferredSize(new Dimension(button.getPreferredSize().width, (int) tabBounds.getHeight() - 2));
glassPane.add(button, gbc);
f.pack();
f.setVisible(true);
}
private void createTab(String name, Color color) {
ProgressIcon icon = new ProgressIcon(color);
jtp.addTab(name, icon, new ColorPanel(jtp, icon));
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JTabbedTest jTabbedTest = new JTabbedTest();
}
});
}
private static class ColorPanel extends JPanel implements ActionListener {
private static final Random rnd = new Random();
private static final long serialVersionUID = 1L;
private final Timer timer = new Timer(1000, this);
private final JLabel label = new JLabel("Stackoverflow!");
private final JTabbedPane parent;
private final ProgressIcon icon;
private final int mask;
private int count;
public ColorPanel(JTabbedPane parent, ProgressIcon icon) {
super(true);
this.parent = parent;
this.icon = icon;
this.mask = icon.color.getRGB();
this.setBackground(icon.color);
label.setForeground(icon.color);
this.add(label);
timer.start();
}
@Override
public void actionPerformed(ActionEvent e) {
this.setBackground(new Color(rnd.nextInt() & mask));
this.icon.update(count += rnd.nextInt(8));
this.parent.repaint();
}
}
private static class ProgressIcon implements Icon {
private static final int H = 16;
private static final int W = 3 * H;
private Color color;
private int w;
public ProgressIcon(Color color) {
this.color = color;
}
public void update(int i) {
w = i % W;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(color);
g.fillRect(x, y, w, H);
}
@Override
public int getIconWidth() {
return W;
}
@Override
public int getIconHeight() {
return H;
}
}
}