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

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

ただいまの
回答率

90.36%

  • Java

    15050questions

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

JButtonでボタンを制作し、画面の大きさを切り替えると位置が変わってしまう

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,795

hokusou7500

score 5

前回の質問時にはコマンドラインでの電卓を作っていましたが、現在ではswingを使った電卓の制作に挑戦しています。
JButtonでボタンを作り、親パネルに貼り付けているのですが、フルスクリーン表示にすると位置が変わってしまい、画面サイズを戻しても位置が戻りません。
最初は文字の下にあったボタンが、フルスクリーンにすると横に、という具合です。
説明が下手で申し訳ありませんが、どうかご教授よろしくお願いいたします。

以下が、コードとなります。
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Font;
public class DENTAKU{
    public static void main(String[] args){
        frame();
    }
    //フレームを作成
    public static void frame(){
        JFrame jf = new JFrame("かんたん電卓 by(^.^)");
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         jf.setSize(1000, 600);
            jf.setLocationRelativeTo(null);
        jf.setVisible( true );

        //親パネルを作成し、フレームに貼り付け
        JPanel bc = new JPanel();
        bc.setBackground(Color.CYAN);
        jf.add( bc );

        //タイトルを表示、親パネルに貼り付け
        JLabel ti = new JLabel("かんたん電卓");
        Font f = new Font(Font.MONOSPACED,Font.BOLD,100);
        ti.setForeground( Color.RED );
        ti.setFont(f);
        bc.add( ti );

        //各ボタンを作成、親パネルに貼り付け
        JButton button1 = new JButton("1");
        button1.setLayout(null);
        button1.setBackground(Color.WHITE);
        button1.setBounds(100, 200, 150, 50);
        button1.setPreferredSize(new Dimension(100, 100));
        bc.add( button1 );

    }
}

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

レイアウトマネージャーの問題かな。
gridbaglayout とか使えばいいんじゃないでしょか。

イメージ説明

イメージ説明

模範回答?作ったのでコピペで実行確認してみてください。

変な書き方でかいてありますが、ちゃんとあなたの希望通りです。

動作環境:Mac, Eclipse Luna Java1.8 swing

Debtaku.java で保存

package jp.kanagawa.caron.swing.tools;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * swing で電卓、普通の四則演算ができる電卓を作ります。
 * MC,C, ,
 * (,),+,-
 * 1,2,3,/
 * 4,5,6,*
 * 7,8,9,%
 * =,0,$,_
 * ( 左かっこ
 * ) 右かっこ
 * MC = Memory Clear
 * C = Clear
 * 0-9 Number
 * + prefix / add
 * - prefix / sub
 * "/" div
 * "%" mod
 * "*" mul
 * "$" register $0-$7 まで。
 *
 * 計算部分は、ScriptEngine による大幅な手抜き動作です。
 * 最近はやりの 3 * 1/3 + 1 が 10になるってのも Javascript なら正しい結果になります。
 *
 * @author masa01
 *
 */
public class Dentaku extends JFrame {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    public static void main(String...args) {

        new Dentaku();

    }

    private ScriptEngine engine;

    private Map<String, Object> paramMap;

    private StringBuilder buffer;

    public Dentaku() {
        // JavaScript Engine nathhorn を取得
        engine = new ScriptEngineManager().getEngineByName("JavaScript");
        paramMap = new HashMap<String, Object>();
        buffer = new StringBuilder(500);

        init();

        initLayout();

        super.setDefaultCloseOperation(EXIT_ON_CLOSE);

        super.setSize(400, 400);

        super.setVisible(true);

    }
    private void init() {
        // 電卓計算結果の途中保存用レジスタの登録と初期化
        paramMap.put("$0", null);
        paramMap.put("$1", null);
        paramMap.put("$2", null);
        paramMap.put("$3", null);
        paramMap.put("$4", null);
        paramMap.put("$5", null);
        paramMap.put("$6", null);
        paramMap.put("$7", null);

        //$err エラーメッセージ格納用変数を定義する
        paramMap.put("$err", null);

        // レジスタを使わない計算の結果はすべてここに入る
        paramMap.put("$ans", null);

        // バッファクリア
        buffer.setLength(0);
    }

    /**
     * try { sys.$ans = ("画面で入力した羅列"); } catch (e) { sys.$err = e; }
     * を作ります。ScriptEngine の eval を実行すると結果が java から取得できるっていう感じですね。
     * @return
     */
    private String createJs() {
        return null;
    }

    /**
     * 画面レイアウトを変更するならオーバーライドしてください。
     * デフォルトでは、
     * BorderLayout で、
     *    North : 計算入力用テキストフィールド(直接入力不可)、readonly
     *    Center: 数字と記号とその他パーツを 4 * 4 のマトリクスにしたもの
     *    South : 実行結果の履歴
     *
     */
    protected void initLayout() {

        ActionListener be = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                System.out.println(e.getActionCommand());
            }
        };

        JPanel gp = new GridLayoutPanel(6, 4)
            .add(0,  0, createButton("MC", "MC", "MC", be))
            .add(0,  1, createButton("C", "C", "C", be))
            .add(0,  2, createButton(" ", " ", "NOP", be))
            .add(0,  3, createButton(" ", " ", "NOP", be))

            .add(1,  0, createButton("LPAR", "(", "LPAR", be))
            .add(1,  1, createButton("RPAR", ")", "RPAR", be))
            .add(1,  2, createButton("ADD", "+", "ADD", be))
            .add(1,  3, createButton("SUB", "-", "SUB", be))

            .add(2,  0, createButton("ONE", "1", "ONE", be))
            .add(2,  1, createButton("TWO", "2", "TWO", be))
            .add(2,  2, createButton("TRE", "3", "TRE", be))
            .add(2,  3, createButton("DIV", "/", "DIV", be))

            .add(3,  0, createButton("FOR", "4", "FOR", be))
            .add(3,  1, createButton("FIV", "5", "FIV", be))
            .add(3,  2, createButton("SIX", "6", "SIX", be))
            .add(3,  3, createButton("MUL", "*", "MUL", be))

            .add(4,  0, createButton("SVN", "4", "SVN", be))
            .add(4,  1, createButton("EGT", "5", "EGT", be))
            .add(4,  2, createButton("NIN", "9", "NIN", be))
            .add(4,  3, createButton("MOD", "%", "MOD", be))

            .add(5,  0, createButton("EQU", "=", "EQU", be))
            .add(5,  1, createButton("ZRO", "0", "ZRO", be))
            .add(5,  2, createButton("DOL", "$", "DOL", be))
            .add(5,  3, createButton("USC", "_", "USC", be))

            .done();
        /*
         * MC,C, ,
         * (,),+,-
         * 1,2,3,/
         * 4,5,6,*
         * 7,8,9,%
         * =,0,$,_
         */

        super.getContentPane().add(gp, BorderLayout.CENTER);

    }
    /**
     * ボタンを作る、アイコンボタンにしたいならオーバーライドする
     * @param name
     * @param text
     * @param command
     * @return
     */
    protected JButton createButton(String name, String text, String command, ActionListener actionListener) {
        JButton jb = new JButton(text);
        // アクションコマンド設定、集約イベントハンドラ内でこのコマンドを取得して対応アクションで処理する
        jb.setActionCommand(command);
        // 名前を設定
        jb.setName(name);
        // 集約?イベントを設定する
        jb.addActionListener(actionListener);
        return jb;
    }

    /**
     * @author masa01
     *
     */

}

GridLayoutPanel.java で保存

package jp.kanagawa.caron.swing.tools;

import java.awt.Component;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import javax.swing.JPanel;

public class GridLayoutPanel extends GridLayout {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private List<Compo> comps;
    private int rows, cols;

    class Compo {
        int x, y;
        int val;
        Component compo;
        public Compo(int x, int y, Component compo) {
            this.x = x;
            this.y = y;
            this.compo = compo;
            this.val = (x + 1) * (y + 1);
        }
    }

    public GridLayoutPanel(int row, int col) {
        super(row, col);

        rows = row;
        cols = col;
        comps = new ArrayList<Compo>();
    }

    public GridLayoutPanel add(int row, int col, Component comp) {

        Utils.assertRange(row, 0, rows);
        Utils.assertRange(col, 0, cols);
        Utils.assertNull(comp);

        comps.add(new Compo(col, row, comp));
        return this;
    }
    public JPanel done() {
        comps.sort(new Comparator<Compo>() {
            @Override
            public int compare(Compo o1, Compo o2) {
                // o1 - o2 は昇順ソート
                // o2 - o1 は降順ソート
                int v1 = o1.y * rows + o1.x;
                int v2 = o2.y * rows + o2.x;

                return v1 - v2;


            }
        });
        JPanel jp = new JPanel(this);
        for (Compo c : comps) {
            jp.add(c.compo);
        }

        return jp;
    }
}

Utils.java で保存

package jp.kanagawa.caron.swing.tools;

public final class Utils {

    public static void assertNull(Object o) {
        if (o != null) return;
        throw new RuntimeException("null はいかん。");
    }

    public static void assertRange(int a, int rs, int re) {
        if (a >= rs && a < re) return;
        throw new RuntimeException("範囲が狂っとる");

    }

}

全部対応するファイル名で保存、パッケージパスを自分とこに合わせて、Dentaku.java を実行してみてください。
画面サイズを変更しても元に戻すとちゃんとレイアウトが戻ります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/20 02:10

    ご回答ありがとうございます。 gridbaglayoutの定義はこれでよろしいのでしょうか。
    このやり方ですと、症状が治らないのですが・・・

    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JLabel;
    import javax.swing.JButton;
    import java.awt.Dimension;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.GridBagLayout;
    public class INBEDA{
    public static void main(String[] args){
    frame();
    }
    //フレームを作成
    public static void frame(){
    JFrame jf = new JFrame("かんたん電卓 by(^.^)");
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setSize(300, 600);
    jf.setLocationRelativeTo(null);
    jf.setVisible( true );

    //親パネルを作成し、フレームに貼り付け
    JPanel bc = new JPanel();
    bc.setBackground(Color.CYAN);
    jf.add( bc );

    //タイトルを表示、親パネルに貼り付け
    JLabel ti = new JLabel("かんたん電卓");
    Font f = new Font(Font.MONOSPACED,Font.BOLD,30);
    ti.setForeground( Color.RED );
    ti.setFont(f);
    bc.add( ti );

    //各ボタンを作成、親パネルに貼り付け
    JButton button1 = new JButton("1");
    button1.setLayout(new GridBagLayout() );
    button1.setBackground(Color.WHITE);
    button1.setBounds(20, 200, 80, 50);
    button1.setPreferredSize(new Dimension(100, 100));
    bc.add( button1 );

    }
    }

    キャンセル

  • 2015/12/20 03:42

    初心者だからって、変数名に手抜きしては駄目です。
    java のクラス名の命名ルールは、アッパーキャメルケース、
    変数名の基本は、クラス名の先頭文字を小文字にしたロワーキャメルケースです。
    title を ti とか省略して記述するのは半年くらい早いです。
    なぜ、100万年じゃなくて半年かというと、半年勉強して研鑽を積めば、たぶん君のスキルの方が自分よりも上になるだろうから。経験値では分があるけど、最新技術ではね、

    キャンセル

  • 2015/12/22 18:26

    返信が遅れて申し訳ありません、ご回答ありがとうございます!
    正しいコードまで書いていただき、本当にありがたいです。
    貴方様のお言葉を胸に、これから勉強していきます。

    キャンセル

0

まずはレイアウトマネージャーを検索して理解しましょう。
GridBagLayoutもレイアウトマネージャーの一つです。
GridBagLayoutは多少使い方が複雑なので、初心者向きでないのかもしれません。

BorderLayoutとGridLayoutを使ったサンプルを載せておきます。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Dentaku {
    public static void main(String[] args) {
        frame();
    }

    // フレームを作成
    public static void frame() {
        JFrame jf = new JFrame("かんたん電卓 by(^.^)");
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setSize(1000, 600);
        jf.setLocationRelativeTo(null);
        jf.setVisible(true);

        // 親パネルを作成し、フレームに貼り付け
        JPanel bc = new JPanel(new BorderLayout());
        bc.setBackground(Color.CYAN);
        jf.add(bc);

        // タイトルを表示、親パネルに貼り付け
        JLabel ti = new JLabel("かんたん電卓");
        Font f = new Font(Font.MONOSPACED, Font.BOLD, 100);
        ti.setForeground(Color.RED);
        ti.setFont(f);
        bc.add(ti, BorderLayout.NORTH);

        JPanel mainPanel = new JPanel(new GridLayout(3, 3));
        // 各ボタンを作成、mainパネルに貼り付け
        for(int i = 1; i <= 9; i++) {
            JButton button1 = new JButton(String.valueOf(i));
            button1.setLayout(null);
            button1.setBackground(Color.WHITE);
            button1.setBounds(100, 200, 150, 50);
            button1.setPreferredSize(new Dimension(100, 100));
            mainPanel.add(button1);
        }
        bc.add(mainPanel, BorderLayout.CENTER);
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/22 18:28

    ご回答ありがとうございます!
    僕のコードを修正していただいているのでとてもわかりやすいご回答で、勉強になりました!

    キャンセル

同じタグがついた質問を見る

  • Java

    15050questions

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