検索を実行する単純な Swing Java アプリケーションがあり、結果が新しいタブに表示されます。検索の実行中に、タブのタイトルに進行状況アイコンまたはアニメーションを表示したい。GIFアイコンを追加しようとしましたが、アニメーションしません。これが機能しない理由はありますか?
3 に答える
進行状況バー (および一般的な進行状況の表示)に関するSwing チュートリアルは、開始するのに非常に適した場所です。を使用してワーカー スレッドで長時間持続する操作を実行し、SwingWorker
一定の間隔で UI を更新して長時間持続する操作の進行状況をユーザーに表示する方法を示します。Swing での および 同時実行の詳細については、別のチュートリアルを参照してください。SwingWorker
そしていつものように、このサイトには例がたくさんあります。たとえば、私の以前の回答では、SwingWorker
クラスを使用してユーザーに進行状況を表示しています
編集
あなたの質問のタブ部分のタイトルを逃したので。「進行状況アイコン」を作成し、それをタブに設定できます。その後SwingWorker
、 を使用してアイコンを更新できます。
このようなアイコンの例は です。これは基本的に、進行するたびに回転するイメージです。タブ付きペインのチュートリアルでは、タブにアイコンを追加する方法 (またはカスタム コンポーネントを使用する方法) を示します。
編集2
私の Mac と JDK1.7 を組み合わせると、他のシステムよりもアニメーション GIF を表示するのがはるかに簡単になるように思われるので、小さな SSCCE も作成しました。は「認知症のチンパンジー」によって作成されました。回転するアイコンのコードは、このサイトからのものです(私は簡素化されたバージョンを使用し、タイマーを追加しました)。私があまり満足していないのは、タブ付きペインを回転アイコンに渡してトリガーする必要があるという事実だけです。考えられる解決策は、タイマーを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();
}
});
}
}
@アンドリュー・トンプソン
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
Sn'Oracle が重要なメソッドを削除するため、より良い == 私の見解)
4) @aterai による Swing JComponents のために ..... を強制する必要があります
5) Rob の Animated Iconは、Rob による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;
}
}
}