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

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

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

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

Swing

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

Q&A

解決済

1回答

1454閲覧

別PanelでrepaintされるたびにJButtonの画像が消えないようにしたい。

me262

総合スコア1

Java

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

Swing

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

1グッド

0クリップ

投稿2020/08/23 09:30

前提・実現したいこと

360°回転する背景のPanelの上に、画像のみのボタン(以下ボタン)Panelを設置し、ボタンを押されるたびに定型文を
出力するプログラムを実装しています。
単体で2つとも完成したので、今は結合を実施しています。

発生している問題・エラーメッセージ

背景はうまく動いていますが、ボタンの方がうまく動いていません。
具体的には、背景側で1°回転するごとにrepaintが行われているのですが、そのたびにボタンの画像が
消えてしまいます。クリックすると一瞬画像が出力されますが、すぐに消えてしまいます。
このボタンの画像の消失を解決したいです。

普段は出力されていませんが
普段は出力されていませんが

ボタン設置部分をクリックした時のみ画像が出力されます
ボタン設置部分をクリックした時のみボタンが出力されます

該当のソースコード

基盤となるPanelです。ここに下記panelを追加していきます。

java

1import javax.swing.JButton; 2import javax.swing.JLayeredPane; 3import javax.swing.JPanel; 4 5public class GameScreen extends JLayeredPane{ 6 public static final int GAMEPANEL_HEIGHT=mainFoundationFrame.FRAME_HEIGHT; 7 public static final int GAMEPANEL_WEIGHT=430; 8 public GameScreen() { 9 JPanel panelGame =new JPanel(); 10 panelGame.setBounds(0, 0, 11 gamePanel_WEIGHT,gamePanel_HEIGHT); 12 panelGame.setLayout(null); 13 14 RotationBackground rotationBackground =new RotationBackground(); 15 panelGame.add(rotationBackground);//回る背景 16 this.setLayer(rotationBackground,DEFAULT_LAYER, 0); 17 18 KookieButton kookieButton =new KookieButton(); 19 panelGame.add(kookieButton); 20 this.setLayer(kookieButton, DEFAULT_LAYER,100); 21 22 JButton jp =new JButton(); 23 panelGame.add(jp); 24 this.setLayout(null); 25 this.setBounds(0, 0,DriverTest12TitlePanel.FRAME_WIDTH,DriverTest12TitlePanel.FRAME_HEIGHT); 26 this.add(panelGame); 27 this.add(panelItemAndScore); 28 this.setLayout(null); 29 this.setBounds(0, 0,640,480); 30 this.add(panelGame); 31 this.add(panelItemAndScore); 32 33

360°回転するpanelのコードです

java

1import java.awt.AlphaComposite; 2import java.awt.Graphics; 3import java.awt.Graphics2D; 4import java.awt.Image; 5import java.awt.Toolkit; 6import java.awt.event.ActionEvent; 7import java.awt.event.ActionListener; 8import java.awt.geom.AffineTransform; 9 10import javax.swing.JPanel; 11import javax.swing.Timer; 12 13public class RotationBackground extends JPanel { 14 Image puhaImg = Toolkit.getDefaultToolkit().getImage("src/photo/puha.png"); 15 public RotationBackground() { 16 // TODO 自動生成されたコンストラクター・スタブ 17 this.setBounds(0, 0,GameScreen.gamePanel_WEIGHT,GameScreen.gamePanel_HEIGHT); 18 Timer t = new Timer(4000, new TimerListener()); 19 t.start(); 20 } 21 int count = 0; 22 public void paintComponent(Graphics g) { 23 super.paintComponent(g); 24 Graphics2D g2 = (Graphics2D) g; 25 AffineTransform at = g2.getTransform(); 26 // count度回転させます。 27 at.setToRotation(Math.toRadians(count), 200, 150); 28 g2.setTransform(at); 29 //a 透明度を50%に設定する 30 AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); 31 g2.setComposite(ac); 32 g2.drawImage(puhaImg, 0, 150, this); 33 } 34 class TimerListener implements ActionListener { 35 @Override 36 public void actionPerformed(ActionEvent e) { 37 // TODO 自動生成されたメソッド・スタブ 38 if (count > 360) 39 count = 0; 40 count++; 41 repaint();// 20ms毎にrepaint→paint→paintComponent呼ばれる 42 } 43 }

画像のみのボタンのコードです。

java

1 2import java.awt.event.ActionEvent; 3import java.awt.event.ActionListener; 4 5import javax.swing.ImageIcon; 6import javax.swing.JButton; 7import javax.swing.JPanel; 8 9public class KookieButton extends JPanel implements ActionListener { 10 public KookieButton() { 11 // TODO 自動生成されたコンストラクター・スタブ 12 this.setBounds(0,0,GameScreen.gamePanel_WEIGHT,GameScreen.gamePanel_HEIGHT); 13 this.setLayout(null); 14 this.add(button()); 15 System.out.println(this); 16 } 17 public JButton button() { 18 ImageIcon icon=new ImageIcon("src/photo/1r.png"); 19 JButton jButton = new JButton(icon); 20 jButton.setLayout(null); 21 jButton.setBounds(100, 100, 230,280); 22 jButton.addActionListener(this); 23 jButton.setContentAreaFilled(false);//ボタンの背景を透明化 24 jButton.setBorderPainted(false);//枠線を透明化 25 return jButton; 26 } 27 @Override 28 public void actionPerformed(ActionEvent e) { 29 // TODO 自動生成されたメソッド・スタブ 30 System.out.println("イクヨー");//aキャラをクリックされたらイクヨー 31 } 32

試したこと

http://www.kisse-logs.com/2017/06/11/swing-jlayeredpane/
URLのLayeredPaneを試しました。
JLayeredPaneを、基盤となるPanel(プログラム一つ目)で継承し、背景及びボタンをsetLayerで順位付け、ボタンが優先的に前の
Layerに出力されるようにしましたが、効果がありませんでした。

補足情報(FW/ツールのバージョンなど)

実装環境はEclipseです。

TN8001👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

setLayerposition指定が間違っている(逆になっている)と思います(0以上は小さいほど上 -1は最下層)
How to Use Layered Panes (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)

なので回転画像の再描画で消えるのではなく、「ボタンが塗りなおされたときに、一瞬上になったように見える。」が正解だと思います(本来見えたらダメだと思うのですが^^;

ここまではすぐにわかったのですが、ボタンの中?に回転画像がずれて表示されるようになってしまいました。
あれこれ試行錯誤してやっと期待通りに動いたのですが、どうしてなのかはさっぱりわかりません^^;

注意
mainがなかったので、適当にでっち上げました。
よくわからない定数は、適当な数値を直接入れました。
KookieButtonの役割がよくわからないので、直接JButtonを作りました。
ActionListenerをラムダにしました。

Java

1import java.awt.AlphaComposite; 2import java.awt.Graphics; 3import java.awt.Graphics2D; 4import java.awt.Image; 5import java.awt.Toolkit; 6import javax.swing.ImageIcon; 7import javax.swing.JButton; 8import javax.swing.JFrame; 9import javax.swing.JLayeredPane; 10import javax.swing.JPanel; 11import javax.swing.Timer; 12 13 14class GameScreen extends JLayeredPane { 15 public static void main(String[] args) { 16 JFrame frame = new JFrame(); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setSize(800, 600); 19 frame.setLocationRelativeTo(null); 20 frame.add(new GameScreen()); 21 frame.setVisible(true); 22 } 23 24 public GameScreen() { 25 JPanel rotationBackground = new RotationBackground(); 26 add(rotationBackground); 27// setLayer(rotationBackground, DEFAULT_LAYER, 0); 28 setLayer(rotationBackground, DEFAULT_LAYER, -1); 29 30 JButton kookieButton = new JButton(new ImageIcon("src/photo/1r.png")); 31 kookieButton.setBounds(100, 100, 230, 280); 32 kookieButton.addActionListener((e) -> System.out.println("イクヨー")); 33 kookieButton.setContentAreaFilled(false); 34 kookieButton.setBorderPainted(false); 35 kookieButton.setFocusPainted(false); 36 add(kookieButton); 37// setLayer(kookieButton, DEFAULT_LAYER, 100); 38 setLayer(kookieButton, DEFAULT_LAYER, 0); 39 } 40} 41 42class RotationBackground extends JPanel { 43 private final Image puhaImg = Toolkit.getDefaultToolkit().getImage("src/photo/puha.png"); 44 private int count = 0; 45 46 public RotationBackground() { 47 setBounds(0, 0, 430, 430); 48 new Timer(200, e -> { 49 count++; 50 count %= 360; 51 repaint(); 52 }).start(); 53 } 54 55 @Override 56 protected void paintComponent(Graphics g) { 57 super.paintComponent(g); 58 59 Graphics2D g2 = (Graphics2D) g; 60// これだとなぜかずれて描画される 61// AffineTransform at = g2.getTransform(); 62// at.setToRotation(Math.toRadians(count), 200, 150); 63// g2.setTransform(at); 64 g2.rotate(Math.toRadians(count), 200, 150); 65 66 AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); 67 g2.setComposite(ac); 68 g2.drawImage(puhaImg, 0, 150, this); 69 } 70}

投稿2020/08/24 21:18

TN8001

総合スコア9855

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

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

me262

2020/08/25 13:49

回答ありがとうございます。今確認したところ動作しました。 ネットの記事を鵜呑みにするのではなく、上手くいかない時は公式APIを見るべきですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問