質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

3回答

6262閲覧

JavaのJlabelのsetIconの画像がクリアできない

taxshi

総合スコア7

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

0クリップ

投稿2016/08/09 09:50

編集2016/08/10 03:00

Windows上のJavaで半透明のローディングアニメーションを作成しようとしています。

JlabelのsetIconにImageIconを、順番に指定することでダミー画像をアニメーションさせることは成功しているのですが、半透明のpngファイルを使用しているためか、指定するたびに以下のように画像が合成されてしまいます。

半透明
イメージ説明
不透明
イメージ説明

そこで、以下のソースのように、setIconにnullを指定して画像を消した後に、次の画像を表示しようとしたのですが、setIconにnullを指定しても画像がクリアされません。

以下のクラスを、ダミーのmainから呼び出しています。

package customwaitanimation; import java.awt.Color; import java.awt.Container; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class CustomWaitAnimation extends Thread { private boolean running; private JFrame frame; private JPanel panel; private JLabel label1; private Container contentPane; private static final int ANIMATION_FRAMES = 10; // コンストラクタ public CustomWaitAnimation() { // this.running = true; // this.frame = new JFrame(); this.frame.setSize(110, 110); this.frame.setAlwaysOnTop(true); this.frame.setLocationRelativeTo(null); this.frame.setUndecorated(true); this.frame.setBackground(new Color(0, 0, 0, 0)); this.panel = new JPanel(); this.panel.setBackground(new Color(0, 0, 0, 0)); ImageIcon icon = new ImageIcon("loading01.png"); this.label1 = new JLabel(); this.label1.setIcon(icon); this.panel.add(this.label1); this.contentPane = this.frame.getContentPane(); this.contentPane.add(this.panel); } @Override public void run() { this.frame.setVisible(true); int index = 1; while(this.running) { //画像を消したあと次の画像をセットする this.label1.setIcon(null); String filename = "loading" + String.format("%02d", index) + ".png"; ImageIcon icon = new ImageIcon(filename); this.label1.setIcon(icon); //ファイル名のインデックスをインクリメントorリセット if(index >= ANIMATION_FRAMES) { index = 1; } else { index ++; } //0.1秒更新 try { sleep(100); } catch (InterruptedException ex) { Logger.getLogger(CustomWaitAnimation.class.getName()).log(Level.SEVERE, null, ex); } } this.frame.setVisible(false); } public void stopRunning() { // this.running = false; } }

ダミーのmain

import customwaitanimation.CustomWaitAnimation; public class TestMain { public static void main(String[] args) { CustomWaitAnimation w = new CustomWaitAnimation(); w.start(); try{ Thread.sleep(10000); }catch(InterruptedException e){} w.stopRunning(); } }

nullを指定すると、画像がクリアされるという認識だったのですが、間違っているでしょうか?
また、このような状況になった方や、回避策をご存知の方はいらっしゃらないでしょうか?

使用しているツールのバージョンは、
・Windows10 pro
・NetBeans 8.1
・Java 1.7.0
です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

argius

2016/08/10 02:45

Windowsのバージョンは何でしょうか? Windows7で試しましたが、再現しませんでした。他の箇所に原因がある可能性もありますので、Javaのコードの全体を見たいのですが、公開していただくことは可能でしょうか?
taxshi

2016/08/10 03:02

追記いたしました。 画像ファイルのパスだけは短くしています。
guest

回答3

0

ベストアンサー

フレームを透明化しているまたはUndecoratedしている影響だと思いますが、フレームを完全に再描画させる必要があるようです。
setIcon(icon)の後でSwingUtilities.updateComponentTreeUI(frame)を実行して、フレームを強制的に再描画してみてください。
おそらくsetIcon(null)も不要だと思います。

描画タイミングを確実にするために、SwingUtilities.invokeLater()で呼び出してください。

// import javax.swing.SwingUtilities; // ※ImageIcon icon は 匿名クラスから参照するためfinalをつけてください // label1.setIcon(icon); // ここを下記コードで置き換え SwingUtilities.invokeLater(new Runnable() { @Override public void run() { label1.setIcon(icon); SwingUtilities.updateComponentTreeUI(frame); } });

投稿2016/08/10 03:39

編集2016/08/10 04:13
argius

総合スコア9388

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taxshi

2016/08/10 04:08

ご提案の方法で、希望通りの半透明の画像のアニメーションすることができました。 1点ご報告として、 「ローカル変数iconは内部クラスからアクセスされます。finalで宣言される必要があります」 と怒られてしまったため、iconの定義はfinalで宣言しなおしています。
argius

2016/08/10 04:13

すみません、finalの件は説明を忘れていました。 おっしゃるとおり、finalをつければOKです。 コードに説明を追加しました。
guest

0

setDisabledIcon

java

1setDisabledIcon(消したいアイコン);

としてはいかがでしょうか

投稿2016/08/10 00:28

asahina_dev

総合スコア610

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taxshi

2016/08/10 00:46

setDisabledIconメソッドは、 Jlabel.setEnable(false)にしたときに、Jlabelに表示される画像を設定するメソッドのようなので、 this.label1.setDisabledIcon(icon); を実行しても、特になにも変化はありませんでした。 また、 this.label1.setIcon(icon1); this.label1.setDisabledIcon(icon2); としたのち、setEnableメソッドのtrueとfalseを切り替えると、 icon1とicon2の画像が交互に切り替わるだけのようです。
asahina_dev

2016/08/10 00:54 編集

微妙に間違えてたので削除
guest

0

Stackoverflowの質問で似たようなものを見かけました。
このMadProgrammerの回答の様に、ImageIOを使った場合どうなりますか?

つまり以下の部分を:

java

1ImageIcon icon = new ImageIcon(filename);

以下の様に変えたらうまくいくでしょうか?

java

1// import javax.imageio.ImageIO; が必要かもしれません。 2ImageIcon icon = new ImageIcon(ImageIO.read(new File(filename)));

投稿2016/08/09 11:56

flied_onion

総合スコア2604

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taxshi

2016/08/09 23:59

ご回答ありがとうございます。 ImageIOを使用する方法にしてみましたが状況に変化はありませんでした。 Stackoverflowの質問を読むと、画像自体が切り替わらなくて困っているように読めました。 質問本文の画像をアニメーションGIFに変更しましたが、画像のパラパラマンガ状の切り替えはできているのですが、透明部分がどんどん上書きされているような状態になっているため、一旦表示をクリアしてから次の半透明の画像をセットできないかなと思った次第です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問