-1

顔を表示および操作するためのプロトタイプ描画プログラムを作成するという課題があります。顔を描くためのウィンドウと、描画を制御するためのウィンドウの 2 つのウィンドウを使用することになっています。最初に顔の画像を表示することになっています (形状で描かれています)。

顔は、頭、2 つの目、鼻、口で構成されています。これらの各パーツは、オブジェクトの境界内でマウスをクリックして選択します。目はペアで選択されているので、どちらかの目をクリックすると両方が選択されます。顔パーツを 1 つ選択すると、それまでの選択内容はすべて失われます。

コントロール ウィンドウは、選択したオブジェクトに対してのみ動作します。[イメージの変更] ボタンをクリックすると、次のタスクが実行されます (選択した顔のパーツによって異なります)。

  • 頭:頭が緑→黄→紫→紫→緑に戻る
  • 鼻: 鼻の画像は、考えられる 3 つの鼻の画像の別のものを変更します。
  • 口: 口の画像が 3 つの口の画像の別の画像に変わります
  • 目: 目の画像が 4 つの可能な目の画像の別のものに変わります

動作を伴うスクロール バーを含めます。

  • 選択された頭: スクロール バーの値の変更で頭が広くなったり狭くなったりします
  • Selected Nose: スクロールバーの値変更で鼻画像が上下に移動
  • 選択された口: スクロールバーの値の変更で口が広くなったり狭くなったりします
  • 選択された目: スクロール バーの値を変更すると、目が互いに近づいたり離れたりします。

私の問題は、どこから始めればいいのかわからないことです。私は、swing と awt に関する多くのチュートリアルを見て、NetBeans のパレット マネージャをいじってみました。誰かが私を正しい方向に向けたり、コードを説明したりできますか?

4

1 に答える 1

1

あなたの質問はここでは適切ではありません。また、インストラクターが不正確であると主張したにもかかわらず、人が自分で調査を行って、あなたが持っている特定の要件のかなり良いセットから機能するプログラムに移行することはまだ考えられます. 聞こえるかもしれないほど批判的であるという意味ではありません。

しかし、あなたがインストラクターにアプローチしたという事実に感謝し、また残念に思うので、いくつかの出発点とヒントを与えることができるかもしれません.

まず第一に、Swing は正しい開始方法です。http://zetcode.com/tutorials/javaswingtutorial/でチュートリアルの関連セクションを読み、いくつかのプロジェクトに従ってください。

Swing インターフェースは手作業で非常に簡単にコーディングできます。比較的単純なアプリケーションの場合、および学習経験のために、これは妥当なオプションです。ただし、今後の参考のために、多くの IDE には GUI エディターがあります (NetBeans にはこの機能が付属していると思いますが、Eclipse には WindowBuilder プラグインがあります) - IDE の使用方法の学習をタスク リストに追加する必要があることに注意してください (もちろん、これは最終的には時間を節約できます)。

いずれにせよ、最初のステップはソフトウェアを設計することです。実行する必要があるアクション、対応する必要があるユーザー アクションとその方法、および処理する情報を決定します。次の要件を指定します。

コントロール ウィンドウは、選択したオブジェクトに対してのみ動作します。[イメージの変更] ボタンをクリックすると、次のタスクが実行されます (選択した顔のパーツによって異なります)。

  • 頭:頭が緑→黄→紫→紫→緑に戻る
  • 鼻: 鼻の画像は、考えられる 3 つの鼻の画像の別のものを変更します。
  • 口: 口の画像が 3 つの口の画像の別の画像に変わります
  • 目: 目の画像が 4 つの可能な目の画像の別のものに変わります

動作を伴うスクロール バーを含めます。

  • 選択された頭: スクロール バーの値の変更で頭が広くなったり狭くなったりします
  • Selected Nose: スクロールバーの値変更で鼻画像が上下に移動
  • 選択された口: スクロールバーの値の変更で口が広くなったり狭くなったりします
  • 選択された目: スクロール バーの値を変更すると、目が互いに近づいたり離れたりします。

ここで作業している基本コンポーネントは顔なので、ここで顔を他のプロパティを持つオブジェクトにするように設計上の決定を下しましょう (別のアプローチを取り、顔のさまざまな部分を基本単位にすることもできます)。スクロール バーの説明に基づいて、面には次の変更可能なプロパティがあります。

  • 頭幅。
  • 垂直ノーズポジション。
  • 口幅。
  • 目の間の距離。

もちろん、顔には、目の直径、肌の色などの値を任意に決定するための他の一定の特性があります。それらを解決する必要があります。

上記のプロパティを変更することに加えて、要件に直接基づいて、顔で実行できるようにする必要があることがいくつかあります。

  • 顔を描く(塗る)。
  • プロパティが変更されたときに面を再描画 (再描画) します。
  • ユーザーがクリックしてパーツを選択できるようにします。これは次のように分類されます。
    • マウスクリックへの応答。
    • XY 位置を指定して、カーソルの下のコンポーネントを決定します。
    • 選択に関する情報をアプリケーションに提供します。

最後の「選択に関する情報を提供する」部分は実装の詳細であり、いくつかのオプションがあり、決定する必要があります。たとえば、ある種のイベント リスナー インターフェースを作成し、顔にそれを伝え、選択が変更されたときにそのインターフェースでメソッドを呼び出せるようにすることができます。これは非常にスイング的な方法です。また、現在選択されているプロパティを内部的に維持する面を持たせることもできます。その場合、現在選択されているプロパティの値を取得/設定できるようにする必要があります。また、エディタ UI ウィンドウのメソッドを顔に直接呼び出すこともできます。これらすべての方法には明確な長所と短所があるため、読者が実験するための課題として残しておきます。

ここで、要件に従って、別のウィンドウでユーザーがプロパティを編集するためのスクロール バーを提供する必要もあります。では、必要な UI コンポーネントと、それらをどのように結び付けるかについて考えてみましょう。

  • フェイスウィンドウ
    • 1 つの面コンポーネント (必要に応じて複数) が含まれます。
  • エディタ ウィンドウ
    • スクロールバーが含まれています。
    • 必要に応じて、現在の選択を説明するラベルを含めることができます。

Swing は、これらのコンポーネントのほとんどをすでに提供しています。ウィンドウはJFrame. スクロールバーはJScrollBar. ラベルはJLabel. Swing はフェイスを提供しないため、カスタム コンポーネントを自分で作成する必要があります。

それらがどのように結びついているかについて:

  • 顔のオブジェクト選択を変更すると、次のことが可能になります。
    • 必要に応じて、スクロールバーを現在の値に更新します。
    • スクロールバーの範囲を適切な値に更新します。
    • 必要に応じて、ラベルを更新して現在の選択内容を説明します。
  • スクロールバーを変更するには、次のことを行う必要があります。
    • 面で現在選択されているプロパティを更新します。
    • 最終的に面を再描画します。

ここでの主なタスクは、顔を描画してマウスのクリックに応答する Swing コンポーネントを実装することです。

新しいコンポーネントを作成しているので、適切なベース (おそらく aJComponentまたは) を選択する必要JPanelがあります。新しいコンポーネントを作成する正確な方法は、Google の多くのチュートリアルで簡単に見つけることができます (上でリンクしたもののいくつかの基本を含む)。それはあなた次第です。ただし、基本的に、上記のことを繰り返しますが、カスタムの顔コンポーネントには次のカスタム動作があります。

  • 顔を描きます。
  • マウス イベントを受け取ります
  • マウスの X、Y 座標からクリックされたコンポーネントを特定します。最も基本的なレベルでは、これには数学が必要です。たとえば、頭、目、口、鼻が楕円である場合、指定された X、Y 座標がこれらの楕円の境界内にあるかどうかを計算するのはユーザー次第です。ただし、Shapeを調べると、形状を簡単に定義でき、境界チェック メソッドが既に提供されます。

始めてすべてをまとめるには、これで十分だと思います。次の一般的なタスクが手元にあります。

  • 私がリンクしたチュートリアルを読むと、多くの基本が明確になるはずです。簡単な「hello world」スタイルのアプリケーションを書いてみてください。
  • カスタム コンポーネントを作成してみてください。要件は基本的なものであり、その多くはそのチュートリアルの「ペイント」セクションでカバーされています。
  • Shape使用方法と実験方法に関するチュートリアルまたはいくつかの例を確認してください。

作成したコードについて具体的な質問があり、解決しようとしている特定の問題がある場合は、いつでも戻って SO に投稿できます。

これが役立つことを願っています。さらに重要なことは、要件から一般的な実装に移行する方法について、少なくともある程度のアイデアが得られることを願っています.

編集:

遊んでからしばらく経ったShapeので、この小さな例をまとめました。2 つの図形をクリックまたはドラッグして選択すると、黄色に変わります。

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class ShapeSelect extends JPanel {

    private final Shape firstShape = new Rectangle2D.Float(60, 40, 70, 70);
    private final Shape secondShape = new Ellipse2D.Float(30, 30, 90, 50);
    private Shape selected = null;

    public ShapeSelect () {
        // set up the component
        setPreferredSize(new Dimension(200, 200));
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override public void mouseDragged (MouseEvent event) {
                selectShapeUnder(event.getX(), event.getY());
            }
        });
        addMouseListener(new MouseAdapter() {
            @Override public void mousePressed (MouseEvent event) {
                selectShapeUnder(event.getX(), event.getY());
            }
        });
    }

    // draw our shapes, selected shape is yellow.
    @Override protected void paintComponent (Graphics g) {
        Graphics2D graphics = (Graphics2D)g;
        graphics.setColor((selected == firstShape) ? Color.YELLOW : Color.RED);
        graphics.fill(firstShape);
        graphics.setColor((selected == secondShape) ? Color.YELLOW : Color.GREEN);
        graphics.fill(secondShape);
    }

    // updates 'selected' based on x,y coordinate and redraws component on change.
    public void selectShapeUnder (int x, int y) {
        Shape oldSelected = selected;
        // note that since second shape is draw on top of first, we give second preference.
        // for overlapping shapes the selection should be consistent with the gui display.
        if (secondShape.contains(x, y))
            selected = secondShape;
        else if (firstShape.contains(x, y))
            selected = firstShape;
        else
            selected = null;
        if (selected != oldSelected)
            repaint();
    }


    public static final void main (String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override public void run () {
                JFrame frame = new JFrame("Shape Select");
                frame.getContentPane().add(new ShapeSelect(), BorderLayout.CENTER);
                frame.pack();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }


}
于 2013-11-07T18:02:00.297 に答える