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

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

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

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

Swing

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

Q&A

解決済

1回答

1918閲覧

JLayeredPaneでFlowLayoutを使う

CreeperSaviour

総合スコア129

Java

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

Swing

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

0グッド

0クリップ

投稿2019/09/03 03:10

編集2019/09/03 03:44

問題

(1)
Main.FrameにFlowLayoutを適用したのですが、実行するとlabelsが横一列に並び期待した見た目にはなりませんでした。

下の方に書いてある「ソースコード(期待する見た目)」ではJLayeredPaneを使用していないのですが、Window.java内にあるlabelsを背面においてlabelを前面においておきたいのでJLayeredPaneを使用しました。

(2)

label.setLocation(50, 50);

としてlabelの位置を変えたつもりですが、反映されませんでした。

この2つの問題が解決せず、質問しました。
どうぞよろしくお願いします。

ソースコード

Main.java

Java

1import javax.swing.SwingUtilities; 2 3public class Main { 4 5 private final static int rows = 5; 6 private final static int columns = 5; 7 8 public static void main(String[] args) { 9 10 SwingUtilities.invokeLater(new Runnable() { 11 public void run() { 12 new Window(rows, columns).setVisible(true); 13 } 14 }); 15 16 } 17 18} 19

Window.java

Java

1import java.awt.Color; 2import java.awt.Dimension; 3import java.awt.FlowLayout; 4 5import javax.swing.JFrame; 6import javax.swing.JLabel; 7import javax.swing.JLayeredPane; 8import javax.swing.border.LineBorder; 9 10public class Window extends JFrame { 11 12 private final int rows; 13 private final int columns; 14 15 Window(final int rows, final int columns) { 16 this.rows = rows; 17 this.columns = columns; 18 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 setBounds(500, 150, columns * 80 + 20, rows * 80 + 40); 20 setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); 21 22 Movement mv = new Movement(); 23 24 Frame frame = new Frame(rows, columns); 25 add(frame); 26 27 } 28 29 public class Frame extends JLayeredPane { 30 31 Frame(final int rows, final int columns) { 32 setSize(columns * 80 + 20, rows * 80 + 40); 33 setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); 34 35 Movement mv = new Movement(); 36 37 JLabel[][] labels = new JLabel[rows][columns]; 38 for(int i = 0; i < rows; i++) { 39 for(int j = 0; j < columns; j++) { 40 labels[i][j] = new JLabel(); 41 labels[i][j].setPreferredSize(new Dimension(80, 80)); 42 labels[i][j].setText(i + ", " + j); 43 labels[i][j].setBorder(new LineBorder(Color.BLACK, 2, true)); 44 labels[i][j].setOpaque(true); 45 labels[i][j].setBackground(Color.WHITE); 46 add(labels[i][j]); 47 setLayer(labels[i][j], DEFAULT_LAYER); 48 } 49 } 50 51 JLabel label = new JLabel("Label"); 52 label.setPreferredSize(new Dimension(80, 80)); 53 label.setLocation(50, 50); 54 label.setBorder(new LineBorder(Color.BLACK, 5, true)); 55 label.setOpaque(true); 56 label.setBackground(Color.WHITE); 57 add(label); 58 setLayer(label, DRAG_LAYER); 59 mv.addMovementListener(label); 60 61 } 62 63 } 64 65} 66 67

Movement.java

Java

1package que; 2 3import java.awt.event.MouseEvent; 4import java.awt.event.MouseListener; 5import java.awt.event.MouseMotionListener; 6 7import javax.swing.JLabel; 8 9public class Movement implements MouseListener, MouseMotionListener { 10 11 private int X, Y; 12 13 public Movement() {} 14 15 public void addMovementListener(JLabel... labels) { 16 for(JLabel label : labels) { 17 label.addMouseListener(this); 18 label.addMouseMotionListener(this); 19 } 20 } 21 22 @Override 23 public void mouseDragged(MouseEvent e) { 24 e.getComponent().setLocation(e.getX() + e.getComponent().getX() - X, e.getY() + e.getComponent().getY() - Y); 25 } 26 27 @Override 28 public void mouseMoved(MouseEvent e) {} 29 30 @Override 31 public void mouseClicked(MouseEvent e) {} 32 33 @Override 34 public void mousePressed(MouseEvent e) { 35 X = e.getX(); 36 Y = e.getY(); 37 } 38 39 @Override 40 public void mouseReleased(MouseEvent e) {} 41 42 @Override 43 public void mouseEntered(MouseEvent e) {} 44 45 @Override 46 public void mouseExited(MouseEvent e) {} 47 48} 49

ソースコード(期待する見た目)

Main.javaとMovement.javaは同じ

Window.java

Java

1import java.awt.Color; 2import java.awt.Dimension; 3import java.awt.FlowLayout; 4 5import javax.swing.JFrame; 6import javax.swing.JLabel; 7import javax.swing.border.LineBorder; 8 9public class Window extends JFrame { 10 11 private final int rows; 12 private final int columns; 13 14 Window(final int rows, final int columns) { 15 this.rows = rows; 16 this.columns = columns; 17 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 setBounds(500, 150, columns * 80 + 20, rows * 80 + 40); 19 setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); 20 21 Movement mv = new Movement(); 22 23 JLabel[][] labels = new JLabel[rows][columns]; 24 for(int i = 0; i < rows; i++) { 25 for(int j = 0; j < columns; j++) { 26 labels[i][j] = new JLabel(); 27 labels[i][j].setPreferredSize(new Dimension(80, 80)); 28 labels[i][j].setText(i + ", " + j); 29 labels[i][j].setBorder(new LineBorder(Color.BLACK, 2, true)); 30 labels[i][j].setOpaque(true); 31 labels[i][j].setBackground(Color.WHITE); 32 add(labels[i][j]); 33 } 34 } 35 36 JLabel label = new JLabel("Label"); 37 label.setPreferredSize(new Dimension(80, 80)); 38 label.setLocation(50, 50); 39 label.setBorder(new LineBorder(Color.BLACK, 5, true)); 40 label.setOpaque(true); 41 label.setBackground(Color.WHITE); 42 add(label); 43 mv.addMovementListener(label); 44 45 } 46 47} 48 49

期待する見た目

期待する見た目
(↑ではlabelがlabelsの背面にありますが、期待するのはlabelを前面にすることです。)

その他

Eclipse 2019-06
Java SE 8

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

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

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

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

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

guest

回答1

0

ベストアンサー

labelsを背面においてlabelを前面においておきたいのでJLayeredPaneを使用

されたのに, JLayeredPane をそのように使用していないように思います.
ドキュメントの「詳細」をご確認頂くと良いかと思います.

JLayeredPane (Java Platform SE 8)

詳細
JLayeredPaneは、Containerと同じように子のリストを管理しますが、内部で複数のレイヤーを定義することができます。同じレイヤーに属する子は、通常のContainerオブジェクトとまったく同じように管理されますが、子コンポーネントどうしがオーバーラップした場合には、上位のレイヤーのコンポーネントの方が下位レイヤーのコンポーネントより上に表示されます。
各レイヤーには個別の整数値が割り当てられます。Componentのレイヤー属性を設定するには、add呼出しでIntegerオブジェクトを渡します。
たとえば、

(以下略)


以下で labels の上に label が表示されました.
Frame コンストラクタ内での setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); では, レイアウトマネージャが全てのコンポーネントの配置を司る為に, setLocation が効かず label も並べてしまい, (確認していませんが)描画領域が制限されずに全て横一列に並べた上で中央部分を表示していたものと思われます.
また, Window コンストラクタ内の setLayout が有効では(これも原因は確認していませんが)表示がされませんでしたので, コメントにしました.

Window.java

java

1import java.awt.Color; 2 3import javax.swing.JFrame; 4import javax.swing.JLabel; 5import javax.swing.JLayeredPane; 6import javax.swing.border.LineBorder; 7 8import que.Movement; 9 10public class Window extends JFrame { 11 12 private final int rows; 13 private final int columns; 14 15 Window(final int rows, final int columns) { 16 this.rows = rows; 17 this.columns = columns; 18 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 setBounds(500, 150, columns * 80 + 20, rows * 80 + 40); 20 //setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); 21 22 Movement mv = new Movement(); 23 24 Frame frame = new Frame(rows, columns); 25 add(frame); 26 } 27 28 public class Frame extends JLayeredPane { 29 Frame(final int rows, final int columns) { 30 setSize(columns * 80 + 20, rows * 80 + 40); 31 //setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); 32 setLayout(null); 33 34 Movement mv = new Movement(); 35 36 JLabel[][] labels = new JLabel[rows][columns]; 37 for(int i = 0; i < rows; i++) { 38 for(int j = 0; j < columns; j++) { 39 labels[i][j] = new JLabel(); 40 labels[i][j].setBounds(i * 80, j * 80, 80, 80); 41 labels[i][j].setText(i + ", " + j); 42 labels[i][j].setBorder(new LineBorder(Color.BLACK, 2, true)); 43 labels[i][j].setOpaque(true); 44 labels[i][j].setBackground(Color.WHITE); 45 add(labels[i][j], DEFAULT_LAYER); 46 } 47 } 48 49 JLabel label = new JLabel("Label"); 50 label.setBounds(50, 50, 80, 80); 51 label.setBorder(new LineBorder(Color.BLACK, 5, true)); 52 label.setOpaque(true); 53 label.setBackground(Color.WHITE); 54 add(label, DRAG_LAYER); 55 56 mv.addMovementListener(label); 57 } 58 } 59}

投稿2019/09/03 04:27

編集2019/09/04 05:17
jimbe

総合スコア12648

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

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

CreeperSaviour

2019/09/03 04:48

回答ありがとうございます。 私はソースコード>Window.javaで setLayer(labels[i][j], DEFAULT_LAYER);や setLayer(label, DRAG_LAYER); としているのですが、これは間違っているのでしょうか。
jimbe

2019/09/03 12:25 編集

setLayer の前に add があります. そして, ドキュメントの setLayer の説明には > 指定されたコンポーネントのレイヤー属性を設定し、レイヤー内でいちばん下のコンポーネントとします。親に追加する前に呼び出す必要があります。 とあります. 試していませんので言い切ることは出来ませんが, add と setLayer を逆にしてみては如何でしょうか. もしくは, setLayer では無く単に add の第二引数としてレイヤーを指定されては如何でしょうか.
CreeperSaviour

2019/09/03 13:33

2つとも試してみましたが、見た目は変化なく解決してません。 私の理解が出来ていないのかもしれませんが、 > setLayer では無く単に add の第二引数としてレイヤーを指定されては如何でしょうか. というのは、 - setLayer(hoge, DEFAULT_LAYER); - add(hoge); + add(hoge, DEFAULT_LAYER); でしょうか。
jimbe

2019/09/03 17:16

ダメでしたか, setLayer の動作が分かり難いですね. > add(hoge, DEFAULT_LAYER); そのつもりです. 回答に示しました JLayeredPane のドキュメントには The Java Tutorial の「How to Use a Layered Pane」へのリンクがあり, 「How to Use a Layered Pane」にあるサンプル( LayeredPaneDemo.java )では add(Component, Object) で追加しているようです.
jimbe

2019/09/04 05:18

失礼しました, 期待と現状をごちゃまぜにしてしまっていたようです. コードを試して回答に追記致しました.
CreeperSaviour

2019/09/04 05:46

期待通りの画面になりました。ありがとうございます。 質問が解決したのですが、この問題を調べているときにSOでたまにsetLayout(null)は推奨しないなどのコメントを見ました。ただ私はこれが何故なのかが理解できません。もし何か知っていれば教えてください。
jimbe

2019/09/04 09:19 編集

個人的な考えとしましては, Swing のレイアウトは(ウインドウの拡縮や各コンポーネントの位置・大きさの変動に対し)レイアウトマネージャによって自動的に調整する形にするのが目指す形であり, レイアウトマネージャを null とするということはつまり setLocation 等で固定することになり拡縮等に適切に対応出来ないためということかと思います. これは Windows 等では分かり難いかもしれませんが, Android のようにディスプレイサイズそのものが多種多様にある状態ですと, テストした機種では丁度良くても, ディスプレイが大きな機種ではコンテンツが小さく纏まって空白ばかり多くなってしまいますし, 小さい機種では入りきらずに読めないとかボタンが押せない等となります. そうならないようにするためにはディスプレイの大きさによって各種計算を行い適切に配置する必要があり, それを担うのがレイアウトマネージャということになります. (Android では Swing は使いませんが, 位置や大きさを相対的にする(具体的な値は計算される)ほうが良いことは同じです.)
CreeperSaviour

2019/09/04 09:43

なるほど、分かりやすい説明ありがとうございます。 今回制作するものは画面のサイズを変更する必要が無いのでその点は問題ないかと思います。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問