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

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

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

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

Swing

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

Q&A

解決済

2回答

1513閲覧

JSpinnerの値が変化することによって、その最大値、また、別のJSpinnerの値が変化する機能を実現したいですが、どうすればいいですか?

Kuroiwa_haruka

総合スコア13

Java

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

Swing

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

0グッド

0クリップ

投稿2019/02/02 23:54

RPGゲームを作りたく、ステータスを振るところで詰んでしまいました。
トータルで10pを、二つの項目に点数を振りたいのですが、なかなかできなくて困っています。
ChangeListener使っても、どうや「ラムダ式」と「ローカル変数」などなどの関係で、思い通りに行かなかったです。

理想では、一つのJSpinnerの値を変更した際に、すべてのJSpinnerの最大値が変化することです。別にJSpinnerにこだわっていません。このような機能が実現できるモノなら、ぜひ教えていただきたいです!!!

package

1 2import javax.swing.BoxLayout; 3import javax.swing.JFrame; 4import javax.swing.JSpinner; 5import javax.swing.SpinnerNumberModel; 6import javax.swing.event.ChangeEvent; 7import javax.swing.event.ChangeListener; 8 9public class Test extends JFrame { 10 public Test() { 11 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 12 this.setTitle("test"); 13 this.setSize(650, 420); 14 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.X_AXIS)); 15 16 //can plus 10 totally 17 JSpinner spinner = new JSpinner(); 18 SpinnerNumberModel model = new SpinnerNumberModel(10, 10, 20, 1); 19 spinner.setModel(model); 20 getContentPane().add(spinner); 21 22 JSpinner spinner_1 = new JSpinner(); 23 SpinnerNumberModel model_1 = new SpinnerNumberModel(10, 10, 20, 1); 24 spinner_1.setModel(model_1); 25 getContentPane().add(spinner_1); 26 27 int used = 0; 28 29 ChangeListener listener = new ChangeListener() { 30 @Override 31 public void stateChanged(ChangeEvent e) { 32 used = (int) spinner.getValue() - 10; 33 model.setMaximum(20 - used); 34 } 35 36 }; 37 spinner.addChangeListener(listener); 38 } 39 40 public static void main(String[] args) { 41 Test test = new Test(); 42 test.setVisible(true); 43 44 } 45 46} 47

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

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

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

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

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

jimbe

2019/02/03 03:26

ラムダ式やローカル変数がどんなものかご理解頂けているでしょうか. ラムダ式はこのコードには書かれておりません. ローカル変数がどういうものかが分かっていらっしゃらないと, プログラミングがコンパイルの段階でトライ&エラーになり, 動いたとしてもなぜなのかが分からないままになってしまうと思います. 変数はプログラムの基礎ですので, 先にそちらをお調べになったほうが良いかと思います.
Kuroiwa_haruka

2019/02/03 05:03

このコードが動けないのは承知しております。これ以外の方法でどうすればいいのか分からないので、質問させていただきました。
jimbe

2019/02/03 05:51

失礼ですが、ご質問の内容から察するには『「マラソンランナーとして大成したいけどどうしたらいいでしょうか」と質問される「マラソンを殆ど走ったことのない方」』のように感じられます. (先ほどマラソン中継を見たものですから.) 例示するためプログラムは書いておりますが, 急な外出をしていますので, もう暫く時間がかかってしまいます, すいません.
guest

回答2

0

回答ありがとうございます!
とても参考になりました。

投稿2019/02/06 04:18

Kuroiwa_haruka

総合スコア13

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

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

0

ベストアンサー

スピナ2つではコードが限定的(Aで無ければBと決まる状態)になるので, 3つに増やしました.
また、残りステータス値が分かりやすいようにスピナ群の上に表示を付けました.
各ステータス値が 10 (合計30) からレベルアップして合計40まで設定できるようになったという状況です.
各ステータスの変化を全てのスピナに反映する必要があるため, 全体を管理するクラス (StatusSpinnerNumberModelManager) を作りまして, 内部でモデルの通知を受け取り, 全モデルの最大値を変更しています.

このような動作を考えられていると思いましたが, 合っているでしょうか.

java

1import java.awt.BorderLayout; 2import java.util.HashSet; 3import java.util.Set; 4 5import javax.swing.BoxLayout; 6import javax.swing.JFrame; 7import javax.swing.JPanel; 8import javax.swing.JSpinner; 9import javax.swing.JTextField; 10import javax.swing.SpinnerNumberModel; 11import javax.swing.event.ChangeListener; 12 13public class Test extends JFrame { 14 15 /** このマネージャにモデルを登録すると, 最大値最小値を設定し, 値の変化によって各モデルの最大値が変化するようになります. */ 16 static class StatusSpinnerNumberModelManager { 17 /** 登録されたモデルのいずれかが変更されたら呼び出される */ 18 interface ChangeStatusListener { 19 void onChangeStatus(StatusSpinnerNumberModelManager source); 20 } 21 private ChangeStatusListener listener; 22 /** ステータスの合計値 */ 23 private int new_status_total; 24 /** モデルセット. この現在値の合計が new_status_total 以下になるよう制御します */ 25 private Set<SpinnerNumberModel> modelSet = new HashSet<>(); 26 /** 残っているステータス値 */ 27 private int leftStatus; 28 /** スピナモデルのリスナ */ 29 private ChangeListener changeListener = e->changeMaximum(); 30 31 /** @param new_status_total ステータスの合計値 */ 32 StatusSpinnerNumberModelManager(int new_status_total) { 33 this.new_status_total = new_status_total; 34 } 35 /** モデルを登録します. 登録すると最大最小値とリスナが設定されます. */ 36 void add(SpinnerNumberModel model) { 37 if(modelSet.contains(model)) return; //二重登録防止 38 modelSet.add(model); 39 model.setMinimum(new Integer(model.getNumber().intValue())); //現在値を最小値とします. 40 model.addChangeListener(changeListener); //リスナを登録します. 41 changeMaximum(); 42 } 43 int getLeftStatus() { return leftStatus; } 44 void setChangeStatusListener(ChangeStatusListener listener) { 45 this.listener = listener; 46 } 47 /** 全てのモデルの現在値を合計します */ 48 private int getTotal() { 49 int total = 0; 50 for(SpinnerNumberModel model : modelSet) { total += model.getNumber().intValue(); } 51 return total; 52 } 53 /** 54 * 最大値を変更します. 55 * この変更では ChangeEvent は発火しません. 56 */ 57 private void changeMaximum() { 58 leftStatus = new_status_total - getTotal(); //現在値から幾つまで設定できるか. 59 for(SpinnerNumberModel model : modelSet) { 60 model.removeChangeListener(changeListener); //setMaximumでChangeEventが発火するのを防ぐ 61 model.setMaximum(model.getNumber().intValue() + leftStatus); //最大値を変更 62 model.addChangeListener(changeListener); //リスナを戻す 63 } 64 if(listener != null) listener.onChangeStatus(this); 65 } 66 }; 67 68 public Test() { 69 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 70 this.setTitle("test"); 71 this.setSize(650, 420); 72 73 //レベルアップでステータスが(現在合計30から)合計40まで設定できるようになった!(と仮定) 74 int new_status_total = 40; 75 76 StatusSpinnerNumberModelManager statusModelManager = new StatusSpinnerNumberModelManager(new_status_total); 77 78 //残りステータス値 79 JTextField textfield = new JTextField(); 80 textfield.setEditable(false); 81 getContentPane().add(textfield, BorderLayout.NORTH); 82 statusModelManager.setChangeStatusListener(source->textfield.setText(""+source.getLeftStatus())); 83 84 JPanel panel = new JPanel(null); 85 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); 86 getContentPane().add(panel, BorderLayout.CENTER); 87 88 //can plus 10 totally 89 JSpinner spinner1 = new JSpinner(); 90 SpinnerNumberModel model1 = new SpinnerNumberModel(10, null, null, 1); 91 spinner1.setModel(model1); 92 panel.add(spinner1); 93 statusModelManager.add(model1); 94 95 JSpinner spinner2 = new JSpinner(); 96 SpinnerNumberModel model2 = new SpinnerNumberModel(10, null, null, 1); 97 spinner2.setModel(model2); 98 panel.add(spinner2); 99 statusModelManager.add(model2); 100 101 JSpinner spinner3 = new JSpinner(); 102 SpinnerNumberModel model3 = new SpinnerNumberModel(10, null, null, 1); 103 spinner3.setModel(model3); 104 panel.add(spinner3); 105 statusModelManager.add(model3); 106 } 107 108 public static void main(String[] args) { 109 Test test = new Test(); 110 test.setVisible(true); 111 } 112}

投稿2019/02/03 10:20

編集2019/02/03 10:22
jimbe

総合スコア12648

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

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

Kuroiwa_haruka

2019/02/06 04:18

ありがとうございます! とても参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問