0

そのため、グラフ全体が画面に表示されるようにフレームを中央に配置するのに問題があります。現在、プログラムを実行すると、座標系の x 値は正しい範囲ですが、グラフが描画される数百ピクセル上にフレームが中心にあるため、グラフがほとんど見えません。これが私のコードです:

public static int startx = 1;
public static int endx = 500;
static Scanner input = new Scanner(System.in);

int WIDTH = 0;  
int HEIGHT = 0;


public GraphSigma(int WIDTH, int HEIGHT) {
    this.WIDTH = WIDTH;
    this.HEIGHT = HEIGHT;
}

// Draw your spiral here!!!
// You'll need to use a FOR loop to calculate the
// points on the spiral


public void paintSigma(Graphics g){

    int prevX=startx;
    int prevY=Sigma.Sigma(startx);
     Graphics2D g2 = (Graphics2D) g;
    g2.translate(0, Sigma.Sigma(endx));
    g2.scale(1,-1);
    if (endx-startx < 50)
        for (int i = startx; i <= endx; i++) {
            int x = i;
            int y = Sigma.Sigma(i);
            g.drawLine(0+prevX, 0+prevY, x, y);
            prevX=x;
            prevY=y;

            };
    if (51 < endx-startx && endx-startx < 300)
        for (int i = startx; i <= endx; i+=2) {
        int x = i;
        int y = Sigma.Sigma(i);
        g.drawLine(0+prevX, 0+prevY, x, y);
        prevX=x;
        prevY=y;

        };
        if (301 < endx-startx  && endx-startx < 1000)
        for (int i = startx; i <= endx; i+=4) {
            int x = i;
            int y = Sigma.Sigma(i);
            g.drawLine(0+prevX, 0+prevY, x, y);
            prevX=x;
            prevY=y;

        };
        if (1000<endx-startx)
            for (int i = startx; i <= endx; i+=10) {
                int x = i;
                int y = Sigma.Sigma(i);
                g.drawLine(0+prevX, 0+prevY, x, y);
                prevX=x;
                prevY=y;

                };

}

// This special method is automatically called when the scene needs to be drawn.
public void paintComponent(Graphics g) {

    paintSigma(g);
}

public static void main(String[] args) {
    // Graphics window size

    int WINDOW_WIDTH = endx-startx+20;
    int WINDOW_HEIGHT = endx;

    JFrame frame = new JFrame();

    frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);

    frame.setTitle("Sigma Function");

    GraphSigma d = new GraphSigma(endx-startx+20, Sigma.Sigma(endx));
    frame.add(d);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

}

私が呼び出しているシグマ メソッドは別のクラスにあります。そのためのコードは次のとおりです。 public class Sigma {

static Scanner input = new Scanner(System.in);

public static int Sigma(int s){
    int a = 0;
    for(int i=1;i<=s;i++){
        if(s%i==0)
            a = a + i;

    }
    return a;

}
public static void main(String[] args) {
    System.out.println("Please enter the number you want to perform the sigma function on");
    int s = input.nextInt();
    System.out.print(Sigma.Sigma(s) +" is the sum of all the divisors of your input" ); 
    }

}

正直なところ、これを正しく中央に配置する方法がわかりません。方法がありませんか? 私は変数をいじっていますが、フレームがどのように中央に配置されるかを変更していないようです。本当にありがとう!

4

1 に答える 1

0

まず、コードをクリーンアップしましょう。次に、どこで問題が発生したかを示します。

シグマクラス

これが私のバージョンのSigmaクラスです。

1) メソッドにクラス名と同じ名前を付けない。メソッド名を calculateSigma に変更しました。

2) スキャナーを開いたら、終了後に閉じます。

3)あなたがしたように、クラスでスキャナー変数を定義して開かないでください。特に、calculateSigma メソッドを何度でも呼び出します。

import java.util.Scanner;

public class Sigma {

    public static int calculateSigma(int s) {
        int a = 0;
        for (int i = 1; i <= s; i++) {
            if (s % i == 0)
                a = a + i;
        }
        return a;
    }

    public static void main(String[] args) {
        Scanner input   = new Scanner(System.in);
        System.out.println("Please enter the number you want " +
                "to perform the sigma function on");
        int s = input.nextInt();
        System.out.print(Sigma.calculateSigma(s)
                + " is the sum of all the divisors of your input");
        input.close();
    }

}

グラフシグマ クラス

これが私のバージョンの GraphSigma クラスです。

Swing アプリケーションは常にイベント ディスパッチ スレッド (EDT) で呼び出します。これにより、問題が防止されます。

最初はグラフの問題が見えなかったので、drawLine メソッドのデバッグ表示メソッドを追加しました。これは、(1,1) と (497,576) の間に線を引いていることを示しています。

この情報を基に、描画コードの変換メソッドと拡大縮小メソッドに焦点を当てました。

translate メソッドは、グラフの原点を移動します。

scale メソッドは、計算された座標に係数を掛けてグラフ座標を取得することにより、計算された座標をグラフ座標に変換します。

問題を修正するために最初にしたことは、translate メソッドを呼び出すために使用した数値を変更して、グラフの原点を JPanel の左下隅に移動することです。

問題を修正するために私が行った 2 番目のことは、グラフが JPanel に収まるようにスケーリング係数を計算することです。デバッグ情報により、倍率が正しいという確信が持てました。

クラスにデバッグ コードを残したので、Java クラスをデバッグし、何が問題なのかを自分で理解する 1 つの方法を皆さん (および他の人) が確認できます。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GraphSigma extends JPanel {

    public static boolean   DEBUG   = false;

    public static int       startx  = 1;
    public static int       endx    = 500;
    static Scanner          input   = new Scanner(System.in);

    int                     WIDTH   = 0;
    int                     HEIGHT  = 0;

    public GraphSigma(int WIDTH, int HEIGHT) {
        this.WIDTH = WIDTH;
        this.HEIGHT = HEIGHT;
    }

    // Draw your spiral here!!!
    // You'll need to use a FOR loop to calculate the
    // points on the spiral

    public void paintSigma(Graphics g) {

        int prevX = startx;
        int prevY = Sigma.calculateSigma(startx);
        Graphics2D g2 = (Graphics2D) g;
        if (DEBUG) {
            System.out.println("Sigma of endx: " 
                    + Sigma.calculateSigma(endx));
        }
        g2.translate(0, this.getHeight());
        g2.scale(1, -((double) this.getHeight()) / 
                Sigma.calculateSigma(endx));
        if (endx - startx < 50)
            for (int i = startx; i <= endx; i++) {
                int x = i;
                int y = Sigma.calculateSigma(i);
                if (DEBUG) {
                    debugOutput(0 + prevX, 0 + prevY, x, y);
                }
                g.drawLine(0 + prevX, 0 + prevY, x, y);
                prevX = x;
                prevY = y;

            }
        ;
        if (51 < endx - startx && endx - startx < 300)
            for (int i = startx; i <= endx; i += 2) {
                int x = i;
                int y = Sigma.calculateSigma(i);
                if (DEBUG) {
                    debugOutput(0 + prevX, 0 + prevY, x, y);
                }
                g.drawLine(0 + prevX, 0 + prevY, x, y);
                prevX = x;
                prevY = y;

            }
        ;
        if (301 < endx - startx && endx - startx < 1000)
            for (int i = startx; i <= endx; i += 4) {
                int x = i;
                int y = Sigma.calculateSigma(i);
                if (DEBUG) {
                    debugOutput(0 + prevX, 0 + prevY, x, y);
                }
                g.drawLine(0 + prevX, 0 + prevY, x, y);
                prevX = x;
                prevY = y;

            }
        ;
        if (1000 < endx - startx)
            for (int i = startx; i <= endx; i += 10) {
                int x = i;
                int y = Sigma.calculateSigma(i);
                if (DEBUG) {
                    debugOutput(0 + prevX, 0 + prevY, x, y);
                }
                g.drawLine(0 + prevX, 0 + prevY, x, y);
                prevX = x;
                prevY = y;

            }
        ;

    }

    private void debugOutput(int x1, int y1, int x2, int y2) {
        System.out.println("Line drawn from (" + x1 + "," + y1 + ") to (" + x2
                + "," + y2 + ").");
    }

    // This special method is automatically called when the scene needs to be
    // drawn.
    @Override
    public void paintComponent(Graphics g) {
        paintSigma(g);
    }

    public static void main(String[] args) {
        // Graphics window size
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createGUI();
            }
        });
    }

    private static void createGUI() {
        int WINDOW_WIDTH = endx - startx + 20;
        int WINDOW_HEIGHT = endx;

        JFrame frame = new JFrame();

        frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);

        frame.setTitle("Sigma Function");

        GraphSigma d = new GraphSigma(endx - startx + 20,
                Sigma.calculateSigma(endx));
        frame.add(d);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}
于 2013-04-08T16:34:39.363 に答える