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

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

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

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

2回答

317閲覧

JSliderの値に合わせてEllipse2Dコンポーネントの大きさも変化させたい

ikigamikita

総合スコア8

Java

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

1クリップ

投稿2024/02/13 06:04

編集2024/02/13 06:05

実現したいこと

jSliderの値が大きくなると、中央座標を保ったままellipseも大きくなり、
jSliderの値が小さくなると、ellipseも小さくなるようにしたいです。

実装したインターフェース
public void stateChanged(ChangeEvent e) { } の中で、オーバーライドされているメソッドの中のellipseを使おうと
コードの上の方で Ellipse2D ellipse;を定義しましたが、エラーになります。
また、public void stateChanged(ChangeEvent e) { } の中でJsliderのgetValue()を入れた変数を使って、width,heightを変えようとしてもエラーになります。
別のクラスの中でオーバーライドされているメソッドを呼び出して、中身を一部変えたい場合はどうすれば良いのでしょうか?

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

メソッド Double(int, int, int, int) は型 Ellipse2D で未定義です 非 static フィールド ellipse を static 参照できません 非 static フィールド ellipse を static 参照できません

該当のソースコード

java

1import java.awt.Color; 2import java.awt.Graphics; 3import java.awt.Graphics2D; 4import java.awt.geom.Ellipse2D; 5 6import javax.swing.JFrame; 7import javax.swing.JLabel; 8import javax.swing.JPanel; 9import javax.swing.JSlider; 10import javax.swing.event.ChangeEvent; 11import javax.swing.event.ChangeListener; 12 13public class TestFrame extends JFrame implements ChangeListener { 14 JSlider slider; 15 JLabel label; 16 JPanel p; 17 Ellipse2D ellipse; 18 19 20 public static void main(String[] args) { 21 new TestFrame().setVisible(true); 22 } 23 24 TestFrame() { 25 super("Swingサンプル(円の描画)"); 26 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 27 setSize(800, 800); 28 29 setContentPane(new CirclePanel()); 30 31 label = new JLabel("test"); 32 label.setBounds(300, 10, 100,100); 33 add(label); 34 35 JLabel label2 = new JLabel("テスト"); 36 label2.setBounds(300, 500, 100, 100); 37 add(label2); 38 39 slider = new JSlider(); 40 slider.addChangeListener(this); 41 p = new JPanel(); 42 p.add(slider); 43 p.setBounds(300, 300, 100, 50); 44 add(p); 45 46 47 } 48 49 50 51 52 public void stateChanged(ChangeEvent e) { 53 label.setText("値:" + slider.getValue()); 54 int value= slider.getValue(); 55 //p.setBounds(300, 300, value, value); 56// エラーになる 57 ellipse.Double(300,200,value, value); 58 59 60 } 61 62 63 private static class CirclePanel extends JPanel { 64 CirclePanel() { 65 super(null); //レイアウトマネージャ無し 66 setBackground(Color.WHITE); //背景色 67 } 68 @Override 69 public void paintComponent(Graphics g){ 70 super.paintComponent(g); 71 72 Graphics2D g2 = (Graphics2D)g; 73 g2.setColor(Color.BLUE); 74// エラーになる 75 ellipse = new Ellipse2D.Double(300,200,100,100); 76// エラーになる 77 g2.fill(ellipse); 78 } 79 } 80}

###試したこと

どうすれば求める情報が出てくるのか検索方法がわかりませんでしたが、調べた中では。JSliderの値に合わせて図形が大小変化するものは見つけられませんでした。

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

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

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

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

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

guest

回答2

0

しばらく描画のテストになるなら、JPanelベースにしたほうがわかりやすいかなと思いました(mainが長くなるのは個人的には好きじゃないけど^^;

java

1import java.awt.Color; 2import java.awt.Dimension; 3import java.awt.Graphics; 4import java.awt.Graphics2D; 5import java.awt.geom.Ellipse2D; 6 7import javax.swing.JFrame; 8import javax.swing.JLabel; 9import javax.swing.JPanel; 10import javax.swing.JSlider; 11import javax.swing.event.ChangeEvent; 12import javax.swing.event.ChangeListener; 13 14 15public class TestPanel extends JPanel implements ChangeListener { 16 public static void main(String[] args) { 17 JFrame frame = new JFrame("Swingサンプル(円の描画)"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setResizable(false); // nullレイアウトのためリサイズされたくない 20 frame.add(new TestPanel()); 21 frame.pack(); // TestPanelのサイズにframeを合わせる(frameは400x400より大きくなる) 22 frame.setLocationRelativeTo(null); // 画面中央に表示(pack後でないとずれる) 23 frame.setVisible(true); 24 } 25 26 private final JLabel label; 27 private final JSlider slider; 28 29 TestPanel() { 30 setLayout(null); 31 setBackground(Color.WHITE); 32 // (タイトルバーや枠を含まない)クライアントエリアを400x400に設定(正しく中央寄せにできる) 33 setPreferredSize(new Dimension(400, 400)); 34 35 label = new JLabel("test"); 36 label.setHorizontalAlignment(JLabel.CENTER); // 文字中央寄せ 37 // 全幅にしておけば(はみ出さないかぎり)文字数によらず中央寄せに 38 label.setBounds(0, 10, 400, 50); 39// label.setBackground(Color.PINK); label.setOpaque(true); 40 add(label); 41 42 slider = new JSlider(0, 400); 43 slider.addChangeListener(this); 44 slider.setBounds(0, 50, 400, 50); 45 slider.setOpaque(false); 46 add(slider); 47 } 48 49 @Override public void stateChanged(ChangeEvent e) { 50 label.setText("直径:" + slider.getValue()); 51 repaint(); // 再描画(paintComponentが呼ばれる) 52 } 53 54 @Override public void paintComponent(Graphics g) { 55 super.paintComponent(g); 56 57// g.setColor(Color.CYAN); 58// int diameter = slider.getValue(); 59// int radius = diameter / 2; 60// int x = 400 / 2 - radius; 61// int y = 400 / 2 - radius; 62// g.fillOval(x, y, diameter, diameter); 63 64 Graphics2D g2 = (Graphics2D) g; 65 g2.setColor(Color.CYAN); 66 67 int diameter = slider.getValue(); // 円の直径 68 69 double radius = diameter / 2d; // 円の半径 70 double x = 400 / 2d - radius; // xは左上座標のため、描きたい中心より半径ぶん左 71 double y = 400 / 2d - radius; // yは左上座標のため、描きたい中心より半径ぶん上 72 73 Ellipse2D ellipse = new Ellipse2D.Double(x, y, diameter, diameter); 74 g2.fill(ellipse); 75 } 76}

アプリ動画

投稿2024/02/13 12:09

編集2024/02/14 03:38
TN8001

総合スコア9326

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

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

ikigamikita

2024/02/14 01:30

回答ありがとうございます。 不明な点がありまして、 paintComponent(Graphics g)が、stateChanged(ChangeEvent e)によって、slider.getValue()の値がint diameter に代入されるのは分かりますが、 stateChanged(ChangeEvent e)が動作する前のpaintComponent(Graphics g)の中身がどうなっているのかがわかりません。 tateChanged(ChangeEvent e)が動作する前ですと、int diameterにslider.getValue()が代入されていないのでエラーにならないのはどうしてでしょうか? また、2dはどこで定義されていますでしょうか?paintComponent(Graphics g)の中で最初から使える値何でしょうか?2dが具体的に何なのか、何をしているのかわかりかねまして、教えて頂きたいです。よろしくお願いします。
TN8001

2024/02/14 03:42 編集

> tateChanged(ChangeEvent e)が動作する前ですと、int diameterにslider.getValue()が代入されていないのでエラーにならないのはどうしてでしょうか? sliderをnewした後にはgetValueできます。 slider = new JSlider(0, 400); System.out.println(slider.getValue()); 初期値は中間(最小値と最大値の合計を平均した値)の200になります。 [JSlider (Java Platform SE 8 )](https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JSlider.html#JSlider-int-int-) 初期値を自分で決めることもできます。 [JSlider (Java Platform SE 8 )](https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JSlider.html#JSlider-int-int-int-) > また、2dはどこで定義されていますでしょうか? double型の数値リテラルです。2.0と同じ意味です。 [Java | 数値リテラルにサフィックスを付けて型を指定する](https://www.javadrive.jp/start/num/index8.html) int同士の割り算はint(切り捨て)になるので、小数が欲しければどちらかをdouble(あるいはfloat)にする必要があります。 Ellipse2D.Doubleを使う以上、正しく計算したほうがいいのかな。と intで十分な場合(ぱっと見差が分かりませんでした)は、fillOvalがあります。 [Graphics (Java Platform SE 8 )](https://docs.oracle.com/javase/jp/8/docs/api/java/awt/Graphics.html#fillOval-int-int-int-int-) @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.CYAN); int diameter = slider.getValue(); int radius = diameter / 2; int x = 400 / 2 - radius; int y = 400 / 2 - radius; g.fillOval(x, y, diameter, diameter); }
ikigamikita

2024/02/14 05:37

ありがとうございました。理解できました。
guest

0

ベストアンサー

java はオブジェクト指向ですので、オブジェクト指向的な考え方と java-swing での書き方をする必要があります。

円は CirclePanel が自身に書いていますので、円の大きさの指定も CirclePanel を通じて行うのが妥当です。それはフレームの大きさを setSize で設定したりするのと同じことです。
そして、 Swing のコンポーネントは内容が変化した場合は Swing に再描画して欲しい旨を通知して paintComponent を呼んで貰うことで 間接的に再表示 する必要があります。(ただし通知した瞬間に即再表示されるわけでは無いことに注意が必要です。)

java

1import java.awt.*; 2import java.awt.geom.Ellipse2D; 3 4import javax.swing.*; 5import javax.swing.event.ChangeEvent; 6import javax.swing.event.ChangeListener; 7 8public class TestFrame extends JFrame implements ChangeListener { 9 public static void main(String[] args) { 10 new TestFrame().setVisible(true); 11 } 12 13 private JSlider slider; 14 private JLabel label; 15 private CirclePanel circlePanel; //stateChanged メソッドで使うのでフィールド化 16 17 TestFrame() { 18 super("Swingサンプル(円の描画)"); 19 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 20 setSize(800, 800); 21 22 circlePanel = new CirclePanel(); 23 setContentPane(circlePanel); 24 25 label = new JLabel("test"); 26 label.setBounds(300, 10, 100, 100); 27 add(label); 28 29 JLabel label2 = new JLabel("テスト"); 30 label2.setBounds(300, 500, 100, 100); 31 add(label2); 32 33 slider = new JSlider(50, 150, 100); //最小値, 最大値, 初期値 34 slider.addChangeListener(this); 35 JPanel p = new JPanel(); 36 p.add(slider); 37 p.setBounds(300, 300, 200, 50); //見易いようにちょっと大きく 38 add(p); 39 } 40 41 public void stateChanged(ChangeEvent e) { 42 label.setText("値:" + slider.getValue()); 43 int value = slider.getValue(); 44 circlePanel.setDiameter(value); //直径をスライダーの値に変更 45 } 46 47 private static class CirclePanel extends JPanel { 48 private final int X = 350, Y = 250; //円の中心 49 private int diameterOfCircle = 100; //円の直径 50 51 CirclePanel() { 52 super(null); //レイアウトマネージャ無し 53 setBackground(Color.WHITE); //背景色 54 } 55 56 /** 57 * 円の直径を設定する 58 * @param diameter 直径 [px] 59 */ 60 void setDiameter(int diameter) { 61 this.diameterOfCircle = diameter; 62 repaint(); //再描画依頼(後に Swing が paintComponent を呼んでくれる) 63 } 64 65 @Override 66 protected void paintComponent(Graphics g) { 67 super.paintComponent(g); 68 69 Graphics2D g2 = (Graphics2D) g; 70 g2.setColor(Color.BLUE); 71 Ellipse2D ellipse = new Ellipse2D.Double(X-diameterOfCircle/2, Y-diameterOfCircle/2, diameterOfCircle, diameterOfCircle); 72 g2.fill(ellipse); 73 } 74 } 75}

投稿2024/02/13 06:57

編集2024/02/13 07:21
jimbe

総合スコア12648

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

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

jimbe

2024/02/13 18:00

そういえば TN8001 さんの回答を見て思い出しましたが、スライダーだけ入れているパネルは必要なのでしょうか。何の役にもたっていないようですけど。
ikigamikita

2024/02/14 01:47

回答ありがとうございます。考えてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問