我有一個簡單的Swing Java應用程序執行搜索,結果顯示在一個新選項卡中。搜索正在運行時,我想在標籤的標題中顯示進度圖標或動畫。我嘗試添加一個gif圖標,但它不生成動畫。有沒有理由爲什麼這不起作用?JTabbedPane:在選項卡中顯示任務進度
回答
Swing tutorial about progress bars(並顯示一般進展)是一個非常好的開始。它向您展示瞭如何通過使用SwingWorker
在工作線程上執行持久操作,並以特定間隔更新您的UI以向用戶顯示持久操作的進度。有另一個教程可用於獲取更多信息SwingWorker
and concurrency in Swing
和往常一樣,本網站充滿了實例。例如a previous answer of mine使用SwingWorker
類顯示進度用戶
編輯
正如我錯過了標題你的問題的標籤一部分。您可以創建一個「進度圖標」並在選項卡上進行設置。 SwingWorker
然後可以用來更新圖標。
這樣的圖標的一個例子是,它基本上是您每次進行一些進度時旋轉的圖像。該tabbed pane tutorial展示瞭如何將圖標添加到您的標籤(甚至可以使用自定義組件)
EDIT2
,因爲它似乎我的Mac結合JDK1.7使得它更容易顯示GIF動畫,然後在其他系統上,我也創建了一個小型SSCCE,與Andrew非常相似,但帶有旋轉圖標,看起來不像它是由創建的,我引用'瘋狂的黑猩猩'。旋轉圖標代碼來自this site(我使用了一個精簡版本並添加了定時器)。只有我不太滿意的事實是我需要將我的選項卡窗格傳遞給旋轉圖標才能觸發。可能的解決方案是將計時器拉到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();
}
}
}
截圖僅供參考。一個恥辱的圖標不會在屏幕截圖中旋轉。
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();
}
});
}
}
非常好!另請參閱此相關的[示例](http://stackoverflow.com/a/3484251/230513)。 – trashgod 2012-04-07 17:17:09
@trashgod Jeesh ..我應該知道a)你已經有了這樣一個例子b)與那些可愛的Mac之一。屏幕截圖。c)我已經投了票,d)這比我在幾個'瘋狂'時刻可以攻破的任何東西都要好! (除非我仍然喜歡這個事實,我的方法不需要重寫任何東西,不確定這是否構成這種情況下的「優秀設計」,或者僅僅是「鞭a一匹死馬」。) – 2012-04-07 17:27:43
我認爲這兩者在所有計數上都是互補的;引用。 – trashgod 2012-04-07 19:58:42
@Andrew湯普森
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.
我不想讀整....,但你放在一起碼和@ trashgod的威嚴
1)使用Htlm
(我不擅長在普通的HTML)
2)使用GlassPane
與JLabel#(setOpaque(true))
3)使用JLayer
(JXLayer
是好,becasue Sn'Oracle刪除重要方法==我的看法)
4),你必須force ..... for Swing JComponents by @aterai
5)Rob's Animated Icon分幾次支持文件檔案羅布對JTabbedPane
代碼
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;
}
}
}
在'ColorPanel'中作爲'JLabel'添加時也可以使用。 – trashgod 2012-04-09 09:52:43
感謝您重新解決此問題。 +1 :) – 2012-04-09 12:50:20
- 1. 顯示JTabbedPane的第一個選項卡
- 2. 當選擇JTabbedPane選項卡時更改JFrame顯示
- 3. 從JTabbedPane隱藏選項卡
- 4. 在JTabbedPane中具有相等(恆定)寬度的選項卡
- 5. JTabbedPane首先顯示錯誤的選項卡組件
- 6. JTabbedPane沒有顯示添加的其他選項卡
- 7. 帶有2個選項卡的JTabbedPane沒有顯示
- 8. 在子選項卡上顯示進度條,直到WebView加載
- 9. 如何克隆JTabbedPane中的選項卡?
- 10. 遍歷JTabbedPane中的選項卡組件
- 11. 在JTabbedPane禁止選項卡更改
- 12. 在JTabbedpane選項卡上添加圖標
- 13. 如何在Jtabbedpane的工作區中顯示選項卡的內容?
- 14. 高度選項卡(JTabbedPane中)不會改變
- 15. 如何處理JTabbedPane中選項卡標題的高度
- 16. JTabbedPane:更改選項卡標題時更改選項卡大小
- 17. 執行任務時顯示進度條
- 18. TFS 2015構建vNext - 在時間軸選項卡下顯示構建任務進度
- 19. Firefox上的'打開新選項卡'JTabbedPane
- 20. 帶自動滾動選項卡的JTabbedPane
- 21. Java JTabbedPane切換選項卡立即
- 22. JTabbedPane TabComponent默認選項卡突出
- 23. 更改JTabbedpane的選項卡外觀
- 24. 如何在項目選項卡被點擊時刷新JTabbedPane選項卡?
- 25. 如何點擊JList項目在JTabbedPane中打開新選項卡?
- 26. Kibana在「發現」選項卡中不顯示任何結果
- 27. Kibana在「發現」選項卡中不顯示任何結果
- 28. 如何在SubActivity中顯示選項卡?
- 29. 在選項卡中顯示DevTools
- 30. 如何在phalcon中顯示選項卡
這樣做的「最驚喜的路」將是A'JProgressBar'感興趣的標籤,或共同進步的組件之間欄(在選項卡窗格外部),顯示所選選項卡的進度。 *「任何建議?tnx」* 1)不要這樣做。 2)拼寫正確的單詞,比如「謝謝」,或者更好,將它們排除在外 - 它們是噪音。 – 2012-04-07 14:47:38
謝謝,但我想實現類似Firefox的選項卡(帶有顯示加載進度的圖標)。 – Paco 2012-04-07 15:02:05
好吧,亞克,但'我們有技術',所以看到我的答案。作爲練習,讀者可以選擇顏色(和圖像樣式等),看起來不像他們被癡呆的黑猩猩想象。 – 2012-04-07 15:22:51