4

Model-View-Controller パラダイムに基づいたプロジェクトを持っていますが、それを適切に機能させるのに苦労しています。

このプログラムには 4 つのパネルがあり、画面に描かれた楕円形をさまざまな方法で変更できるようになっています。これらはうまく機能しているようで、かなりのトラブルの後、シバン全体を保持する JFrame に表示することができました。提供された指示から離れてそれらを表示することができましたが、それを行うと、楕円を更新できないようです。しかし、手紙の指示に従うと、空のフレームしか表示されません。

プロジェクトにはかなり具体的な方向性があり、私はそれをある程度まで追跡しましたが、一部のドキュメントは不明確でした. 意味をなさないものは何も飛び出していないので、私が見逃しているのは単純なものに違いないと思います。ただし、私の Java の経験は限られており、GUI 設計/パラダイムの経験はさらに限られていることを認めなければなりません。

とにかく、私はウェブとこのサイトを広範囲に検索して、何が問題なのかを突き止めようとしていますが、これはやや具体的な例であり、正直なところ、オンラインで見つけた回答を一般化するのに十分な知識がありません。足りないものを見つけます。私はこのコードをあまりにも長い間調べてきたので、誰かが私を助けてくれることを本当に望んでいます.

public class Model {
    private Controller controller;
    private View view;
    private MvcFrame mvcFrame;

    private int radius = 44;
    private Color color = Color.BLUE;
    private boolean solid = true;

    //bunch of mutators and accessors for the above variables

    public Model() {
        controller = new Controller(this);
        view = new View(this);
        mvcFrame = new MvcFrame(this);
    }
}

モデルクラスはこちら。これはかなり単純なようです。ここで何が起こっているのかについての私の理解はしっかりしていると思いますし、何も間違っているようには見えません。主に文脈のために含まれています。

public class Controller extends JPanel{
    private Model model;

    public Controller(Model model) {
        this.model = model;
        setBorder(BorderFactory.createLineBorder(Color.GREEN));
        setLayout(new GridLayout(4,1));
        add(new RadiusPanel(model));
        add(new ColorPanel(model));
        add(new SolidPanel(model));
        add(new TitlePanel(model));
    }
}

これがコントローラ クラスです。私が知る限り、setBorder、setLayout、および一連の add は、ここでは何もしません。それらをコメントアウトしてもらいましたが、これは指示が私に指示した方法なので、そこに間違いがあるか、私の設定に何か問題があります. ただし、この方法で実行すると、空のウィンドウ (JFrame) が表示されますが、パネルは表示されません。これを修正するために私がしたことは、これらの add 関数を mvcFrame クラスに配置することです。

public class MvcFrame extends JFrame {
    private Model model;

    public MvcFrame(Model model){
        this.model = model;
        //setLayout(new GridLayout(4,1));
        //add(new RadiusPanel(model));
        //add(new ColorPanel(model));
        //add(new SolidPanel(model));
        //add(new TitlePanel(model));

        //add(new View(model));


        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setSize(800,600);
        setVisible(true);
    }
}

ここで、物事が奇妙になり始めました。コメントアウトされたコードの最初のブロックは、Controller クラスにあるものと同じです。私がコメントアウトした理由は、それがただの幸運な推測だったからです。ただし、これはパネルを表示するために機能しましたが、その時点で、楕円形を表示しようとして髪を引き裂いていました.

他のコメント行 ( add(new View(model)); ) は、物事を機能させるための別の試みでした。この場合、これらの add 関数を View クラスに配置します (以下のコメントアウトされたコードを参照)。これは実際には楕円形とパネルの両方を表示するために機能しましたが、その方法では楕円形を更新できませんでした。また、楕円形の表示をしたばかりですが、何が原因なのか正確にはわからず、元に戻すこともできません。

public class View extends JPanel{
private Model model;

    public View(Model model) {
        this.model = model;
        //setLayout(new GridLayout(4,1));
        //add(new RadiusPanel(model));
        //add(new ColorPanel(model));
        //add(new SolidPanel(model));
        //add(new TitlePanel(model));

        repaint();
    }

    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);

        //center of view panel, in pixels:
        int xCenter = getWidth()/2;
        int yCenter = getHeight()/2;

        int radius = model.getRadius();
        int xStart = xCenter - radius;
        int yStart = yCenter - radius;
        int xWidth = 2 * radius;
        int yHeight = 2 * radius;
        g.setColor(model.getColor());

        g.clearRect(0, 0, getWidth(), getHeight());

        if (model.isSolid()){
            g.fillOval(xStart, yStart, xWidth, yHeight);
        } else {
            g.drawOval(xStart, yStart, xWidth, yHeight);
        }        
    }
}

前と同じ考え方 - コメント アウトされたコードは、動作させるために追加したものですが、提供された指示に基づいていません。そのようなものがコメント解除された場合、私は add(new View(model)); を持っていました。mvcFrame 行からの行もコメント解除されています。

さまざまなパネル クラス (SolidPanel、ColorPanel など) は、JPanel を拡張する ControlPanel というクラスを単純に拡張します。これらはすべて期待どおりに機能しているようで、大きな問題はありません。GUI を起動するドライバーもあります。これも期待どおりに動作するようです。

私が抱えている主な問題は、楕円形を表示できないことです。一度表示させることができたのに、それを変更するためのオプションがどれも機能していないように見えました。私は近づいているように感じますが、現時点で他のことを試すには途方に暮れています.

お手伝いいただける方は、心から感謝いたします。

4

3 に答える 3

2

これは、「機能させるためだけに」という非常に急いで書き直したものです。

main.java

public class main {
    public static void main(String[] args) {
        // The JFrame could be created here, since it lasts the life
        // of the program.

        //...then, later, the model.
        Model mdl = new Model();    

        // ...and then move on to applying the view and control to the frame.
    }
}

コントローラー.java

// Nothing interesting here, added for consistency.
public class Controller {
    private final Model model;

    public Controller(Model model) {
        // The frame is shown automatically in the model here.
        this.model = model;

        // The frame's setVisible is a control issue, should be called
        // from in here, not automatically in the model.
    }
}

MvcFrame.java

import javax.swing.JFrame;

public class MvcFrame extends JFrame {
    private final Model model;

    public MvcFrame(Model model){
        this.model = model;
        // Anytime you add anything to a JFrame, use the content pane.
        this.getContentPane().add(model.getView());

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // This line centers the frame on your screen.
        setLocationRelativeTo(null);
        setSize(800,600);
        // The frame won't paint until it's visible.
        // This means if you check dimensions, everything will be 0 x 0
        // until this line is called.
        setVisible(true);
    }
}

モデル.java

import java.awt.Color;

public class Model {
    private final Controller controller;  // Not used yet
    private final View view;
    private final MvcFrame mvcFrame; // Not used yet

    // Mutators and accessors needed for these guys (set/get)
    private final int radius = 44;
    private final Color color = Color.BLUE;
    private final boolean solid = true;

    public Model() {
        controller = new Controller(this);
        view = new View(this);
        mvcFrame = new MvcFrame(this);
    }

    public View getView() {
        return view;        
    }

    public int getRadius() {
        return radius;      
    }

    public Color getColor() {
        return color;       
    }

    public boolean isSolid() {
        return solid;       
    }
}

View.java

import java.awt.Graphics;
import javax.swing.JPanel;

public class View extends JPanel{
    private final Model model;

    public View(Model model) {
        this.model = model;
    }

    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);

        //center of view panel, in pixels:
        int xCenter = getWidth()/2;
        int yCenter = getHeight()/2;

        int radius = model.getRadius();
        int xStart = xCenter - radius;
        int yStart = yCenter - radius;
        int xWidth = 2 * radius;
        int yHeight = 2 * radius;
        g.setColor(model.getColor());

        g.clearRect(0, 0, getWidth(), getHeight());

        if (model.isSolid()){
            g.fillOval(xStart, yStart, xWidth, yHeight);
        } else {
            g.drawOval(xStart, yStart, xWidth, yHeight);
        }        
    }
}
于 2012-12-06T05:00:56.100 に答える
1

あなたの質問は少しとりとめのない、長々としたものです。コードの重要な部分をコメントアウトした理由はわかりませんが、最初の質問は次のとおりです。

//add(new View(model));

ビューをフレームに追加していますか? 楕円は問題なく描画できますが、ビューは追加されません。


次のコードで問題が発生する可能性が最も高くなります。

public class MvcFrame extends JFrame {
    ...

    public MvcFrame(Model model){
        ...
        //setLayout(new GridLayout(4,1));
        //add(new RadiusPanel(model));
        ...
    }
}

直接呼び出すとadd、スーパークラス (JFrame) を参照します。残念ながら、JFrames はcontentPaneレイアウトを保持する を持っているため、卑劣です。さらに卑劣なこと: そのコンテンツ ペインは null レイアウトであり、独自のパネルを配置することによってのみ変更できます。

だから、おそらくこのようなものを作るべきです。正確に従わなくても、これらの方法は大いに役立つはずです。

...
JPanel pnl = new JPanel(new GridLayout(4, 1));
this.setContentPane(pnl);
pnl.add(new RadiusPanel(model));
...

コンテンツ ペインを明示的に設定したくない場合は、 を使用できますthis.getContentPane().add(foo)

JPanel を追加すると、そのサイズが指定されていないため、デフォルトで(0,0).


また、コントローラが JPanel を拡張する理由がわかりません。ビューはコントローラーで使用できる必要があり、swing コンポーネントを含む唯一のものである必要があります。

于 2012-12-06T04:42:12.853 に答える
0

別の問題がありましたが、表示されている行は次のとおりです。

g.clearRect(0, 0, getWidth(), getHeight());

以前のオーバルを消去していなかったため、プロジェクトですべてを解決しました。そのため、大きくした場合にのみ変更が表示されました。ありがとうございました。

于 2013-04-30T15:03:26.107 に答える