ホームページ > Java > &#&チュートリアル > Java のイベント処理および例外処理メカニズムを分析する

Java のイベント処理および例外処理メカニズムを分析する

高洛峰
リリース: 2017-01-22 16:50:56
オリジナル
1125 人が閲覧しました

1. イベント処理
実際、イベント処理という名前は自然に MFC のメッセージ応答メカニズムを思い出させますが、私の経験からすると、Java のイベント処理は「新しいボトル」であると考えられます。 ". "この「古いワイン」に応答するのは、インストールされている MFC のメッセージであるはずです。
いわゆる「イベント」とは、キーボードのキーやマウスのクリックなど、状態を変化させるアクションや何かによって引き起こされる変化であり、この変化に対する対応する応答が必要です。 Java のイベントは、ボタン、マウス、キーボード、ウィンドウ、その他のイベントなどのいくつかのカテゴリに分類できます。
イベント処理モデル
1. 継承ベースのイベント処理モデル (JDK1.0)
JDK1.0 では、イベント処理は最初にコンポーネントに送信され、次にコンテナー レベルに沿って上方に伝播されます。コンポーネントによって処理されないイベントは、コンポーネントのコンテナに自動的に伝播されます。 ——これは、MFC における本来のイベント応答シーケンスまたはポリモーフィック応答メカニズムと一致しているようであり、後述するエージェント ベースのイベント処理メカニズムは、MFC のコールバック メカニズムと一致しているようです。
具体的な処理方法
action()メソッドまたはhandleEvent()メソッドを呼び出し、プログラム実行時に発生するイベントを取得するメソッドです。
2. エージェントベースのイベント処理モデル (JDK1.1)
このモデルでは、イベントを生成するコンポーネントにイベントが直接送信されます。
各コンポーネントには、リスナーと呼ばれる 1 つ以上のクラスが登録されます。このイベントを受信して​​処理します。
リスナーは、Listenerインターフェースを実装するクラスです。イベントは、登録されたリスナーにのみレポートされるオブジェクトです。各イベントには、対応するリスナー インターフェイスがあります。
Button オブジェクトをマウスでクリックすると、ActionEvent イベントが送信されます。この ActionEvent イベントは、addActionListener() メソッドを使用して登録されたすべての ActionListener の actionPerformed() メソッドによって受信されます。
エージェントベースのイベント処理モデルの特徴
①イベントを誤って処理しない。階層モデルでは、イベントがコンテナに伝播し、予期しないレベルで処理される場合があります。
②イベントアクションを分類するアダプタークラスを作成して利用することが可能です。
③作品をさまざまなカテゴリに分散すると便利です。
このイベント処理モデルの学習に焦点を当てます
3. イベント
イベント処理の 3 つの要素。
(1) イベント ソース イベント ソースは、ボタン、ウィンドウ、テキスト フィールドなどのイベントの生成元です。
(2) イベントの種類 Java のすべてのイベントは java.awt.event パッケージに集約されており、すべてのイベント クラスは AWTEvent クラスを継承し、method-getSouce() メソッドがオブジェクトを返します。そこで事件が起きた。
(3) イベントリスナー さまざまな種類のイベントが発生すると、イベントリスナーはイベントを受け取り、対応するイベント処理メソッドを呼び出します。すべてのイベント リスナーは実際には、java.util.EventListener インターフェイスを導入する java.awt.event パッケージ内のインターフェイスです。さまざまなイベント タイプのリスナーにはさまざまなメソッドがあります。
イベント処理手順
① プログラムを java.awt.event パッケージに追加します:
Import java.awt.event;
② 必要なイベント ソース オブジェクトのイベント リスナーを登録します:
Event source object.addXXXListener (XXXListener); ③実装 対応する方法。リスナー インターフェイスに複数のメソッドが含まれる場合、すべてのメソッドを実装する必要があります
例: b2.addActionListener(this)
4. イベント アダプター(アダプター)
各リスナー インターフェイスのすべてのメソッドを実装する作業負荷は非常に大きくなります。 Java 言語には、複数のメソッドを持つクラスを実装するためのアダプター クラスが用意されています。
定義したリスナーはアダプター クラスを継承でき、必要なメソッドをオーバーライドするだけで済みます。
たとえば、ウィンドウ イベントに対応するリスナーは WindowListener ですが、これは windowOpened()、windowClosed()、windowClosing()、WindowIconfied()、WindowDeicofed()、WindowActivated()、WindowDeactivated() などの複数のメソッドを実装する必要があります。 add 不必要なプログラミング作業負荷の増加。
WindowAdapter を継承する場合、すべてのメソッドではなく、1 つまたはいくつかのメソッドのみを実装する必要があります。次の例の多くは、ウィンドウが閉じられたときにシステムを終了することを目的として、windowClosing() メソッドのみを実装しています。
4.1 ボタンイベントの処理
ボタンがクリックされたときに発生するイベントはアクションイベントです
アクションイベントに対応するイベントクラスはActionEventクラスです
アクションイベントに対応するイベントリスナーはActionListenerです
メインリスナーのメソッド:
actionPerformed(ActionEvent e) アクション イベントの発生時に呼び出されます。
アクション イベントの操作プロジェクトを実装します。
最初のステップは、アクション イベント リスナー addActionListener (ActionListener) を登録することです。
2 番目のステップは、ActionListener インターフェースのメソッドを実装することです: actionPerformed(ActionEvent e)
4.2 マウスイベントの処理
マウスイベントをトリガーするイベントソースは通常コンテナです。マウスがコンテナに出入りしたとき、またはマウスがコンテナ内でクリックまたはドラッグされたときに、マウスイベントが発生します
マウスイベントに対応するイベントクラスは MouseEvent クラスです。
MouseEvent クラスのメソッド:
get MouseMotionListener (または MouseMotionAdapter) は、マウス移動イベントに対応します。
MouseListener(またはMouseAdapter)の主なメソッド
MousePressed(MouseEvent e) マウスが押されたときの処理メソッド
MouseClosed(MouseEvent e) マウスが離されたときの処理メソッド
MouseEntered(MouseEvent e) マウスが入ったときの処理メソッド
Mouse Exited(MouseEvent e) ) マウスが離れた時の処理方法
MouseClicked (MouseEvent e) マウスがクリックされた時の処理方法

キーボード イベントに対応するイベント クラスは、KeyEvent クラスです。押されたキー コードまたは離されたキー コードを取得します。 () 押されたまたは離されたキーのコードを取得します。 盘 キーボード イベントに対応するインシデント リスナーは: KeyListener または KeyAdapter です。
メイン メソッド:
Keypressed (Keyevent E) キーボードを押したときの処理メソッド
KeyClosed (Keyevent E) キーボードが離されたときの処理方法
4.. 4. ウィンドウイベントの処理
ウィンドウがアクティブ化されたことを示すウィンドウイベントをトリガーできるのは、Window とその拡張クラス (Frame、Dialog) などだけです。 /無効状態、アイコン/非アイコン状態、オープン/クローズ状態など。
ウィンドウイベントに対応するクラスは WindowEvent 、リスナーは WindowListener (または WindowAdapter)
主なメソッド:
WindowOpened (WindowEvent e) イベント処理ウィンドウを開く
WindowClosed (WindowEvent e) ウィンドウを閉じるイベント処理
WindowClosing (WindowEvent e) ウィンドウを閉じるイベント処理
WindowActivated( WindowEvent e) 起動状態のイベント処理
WindowDeactivated (WindowEvent e) 無効状態のイベント処理
4.5 その他イベント処理
4.5.1 チェックボックス、ラジオボタンのイベント処理
イベントクラスはItemEvent:
オプションイベントに対応するイベント リスナーはItemListener
メソッド:
オプションイベント発生時にitemStateChanged(ItemEvent e)が呼び出されます
4 .5.2 スクロールバーイベント処理
調整イベントに対応するイベントクラスは AdjustmentEvent クラスです:
調整イベントに対応するイベントリスナーは次のとおりです: AdjustmentListener
メソッド:
調整イベントが発生すると、adjustmentValueChanged (AdjustmentEvent e) が呼び出されます。
4.5.3 ドロップダウンリストのイベント処理
イベントクラスはItemEvent:
オプションイベントに対応するイベントリスナーは:ItemListener
メソッド:
itemStateChanged (ItemEvent e) ドロップダウンリストでアクションが発生したときに呼び出されます(ドロップダウンリストのイベント処理、イベントタイプ、イベントリスナー、メソッドは、チェックボックス、ラジオボタンのイベント処理のイベントタイプ、イベントリスナー、メソッドと同じであることがわかります)
4.5. 4 メニュー イベントの処理
メニュー イベントは、通常、メニュー項目をクリックしたときに発生するイベントです。

2 番目のステップは、ActionListener インターフェースのメソッド actionPerformed(ActionEvent e) を実装することです。このメソッドでは、e.getSource()を使用して、ユーザーが選択したメニュー項目を取得し、対応する処理を実行します。

2 番目のステップは、ItemListener インターフェイスのメソッド itemStateChanged(ItemEvent e) を実装することです。このメソッドでは、e.getSource() を使用してユーザーが選択したメニュー項目を取得し、e.getItem() を使用してユーザーが選択したメニュー項目のラベルを取得し、e.getStateChange() を使用してメニュー項目が選択されているかどうかを取得します。 、対応する処理を実行します。

2. 例外処理
優れたプログラミング言語とプログラマは、人気のあるオブジェクト指向プログラミング言語である Java として、例外処理メカニズムは当然ながらその重要な機能の 1 つです。
一般に、例外を説明する場合、それはプログラミング上のエラーであると言われます。しかし、実際にはこのエラーは非常に頻度が高く、コンパイルエラー、操作エラー(具体的にはシステム操作エラーと論理操作エラーに分けられます。このようなシステム操作エラーはめったにありません)など、さまざまな種類があります。以前はプログラミングの間違いだったと考えてください)
JAVA では、例外は Throwable クラスを継承するクラスです。各例外クラスは実行時エラーを表します (注: これは実行時エラーです)。例外クラスには、実行中のエラーとエラー処理メソッドに関する情報が含まれています。
Java の例外処理メカニズム:
Java プログラムの実行中に認識可能な実行エラーが発生するたびに (つまり、エラーに対応する例外クラスがある場合)、システムは例外クラスの対応するオブジェクトを生成します。注: これを例外クラス オブジェクトの生成といいます。) つまり、例外を生成します。
例外オブジェクトが生成されると、クラッシュ、無限ループ、またはその他のオペレーティング システムへの損傷が発生しないように、システムにはそれを処理する対応するメカニズムが必要です。これにより、プログラム全体の安全性が確保されます。
例外と例外クラス。 :
エラー: Java 仮想マシンによって生成およびスローされたため、Java プログラムは処理しません。
実行時例外 (0 による除算、配列の添字が範囲外などのシステム エラー): システムによって検出され、ユーザーの Java プログラムは処理します。システムはそれらをデフォルトの例外ハンドラーに渡します (注: デフォルトの例外処理があります): Java コンパイラーは、Java プログラムがすべての非例外をキャプチャーまたは宣言する必要があります。実行時例外 例外
ユーザーが自分で例外を生成する
例外クラス
コンストラクター:
public Exception();
public Exception(String s); は、通常、文字列パラメーターによって渡される情報を受け入れることができます。例外 。
Exception クラスは、その親である Throwable からいくつかのメソッドも継承しますが、一般的に使用されるメソッドは次のとおりです:
1) public String toString(); toString() メソッドは、現在の Exception クラス情報を説明する文字列を返します。
2) public void printStackTrace();
printStackTrace() メソッドには戻り値がありません。その機能は、印刷操作を完了し、現在の標準出力 (通常は画面) に現在の例外オブジェクトのスタック使用量トレースを出力することです。つまり、プログラムがどのオブジェクトまたはクラスのどのメソッドを呼び出すかが連続して実行されるため、実行中のプロセス中にこの例外オブジェクトが生成されます。
システム定義の実行例外
これらのサブクラスの一部はシステムによって事前定義されており、システム定義の実行例外と呼ばれる Java クラス ライブラリに含まれています
ユーザー定義の例外
特定のアプリケーションに固有の実行エラーについては、プログラマはプログラムの特別なロジックに従って、ユーザープログラム内にユーザー定義の例外クラスと例外オブジェクトを作成します
ユーザー定義の例外は、通常、例外クラスの親クラスとして Exception を使用します
しかし、まだ理解されていない問題があります。発生 システムはエラーが識別可能であることをどのようにして認識するのでしょうか?対応する例外クラス オブジェクトを生成するにはどうすればよいですか?例外オブジェクトは、対応するメソッドを使用して解決することをどのようにして知るのでしょうか?対応する例外を処理する例外クラス オブジェクトごとに、例外処理メソッドは 1 つだけありますか? ———————————ユーザー定義の例外は throw ステートメントを通じてスローされることがわかります。
ユーザー定義例外を作成する場合、通常は次の作業を完了する必要があります:
1) 新しい例外クラスを宣言し、Exception クラス、他の既存のシステム例外クラス、またはユーザー例外を親クラスとして使用するようにします。
2) 新しい例外クラスの属性とメソッドを定義するか、親クラスの属性とメソッドをオーバーロードして、これらの属性とメソッドがクラスに対応するエラー情報を反映できるようにします。
Java プログラムの異常なスローによって実行時に認識可能なエラーが発生した場合、そのエラーに対応するオブジェクトが生成されます。このプロセスはオブジェクトのインスタンスがスローされます。
例外の種類に応じて、例外をスローするには 2 つの方法があります。システムによって自動的にスローされる方法と、ユーザーによってスローされる方法です。
1. システムによって自動的にスローされるシステムによって定義された実行エラー例外はすべて、システムによって自動的にスローされます。
2 、ユーザーがスローする
ユーザー定義の例外は、システムによって自動的にスローされることはありませんが、Java ステートメントを使用してユーザーがスローする必要があります。 Java ステートメントでは、明示的に「例外」をスローするために throw ステートメントが使用されます。
throw を使用します。スローするステートメント 出力形式
戻り値の型メソッド名(パラメータリスト) throws スローする例外クラス名のリスト {

1) 一般的にプログラム内で特定の条件を満たした場合に例外をスローします
if文のif分岐にthrow文を置くことが多いです。 ,
out out out out out of out of through 次の部分を追加します。 r Throws によってスローされる異常なカテゴリのリストは、メソッド ヘッダーの throws にリストされる必要があります。 3) Java 言語では、 throws キーワードで宣言されたすべてのクラスと throw でスローされるオブジェクトは Throwable クラスまたはそのサブクラスである必要があります。スロー可能ではないオブジェクトをスローしようとすると、Java コンパイラーはエラーを報告します
例外処理:
例外をキャッチする方法、例外をキャッチした後にプログラムをジャンプする方法、例外処理ステートメントをどのように記述するかを主に検討します
1 。 try...catch...finally block
1) try
try ステートメントの { } には、1 つ以上の例外をスローする可能性のあるプログラム コードが含まれています
これらのコードは、実際には、その背後にある catch ブロックがキャッチできる例外を指定します範囲。 Java プログラムが try ブロック内のステートメントを実行するときに例外が発生した場合、Java プログラムは try ブロック内の他のステートメントの実行を続行せず、直接 catch ブロックに入り、最初に一致する例外タイプを見つけて処理します。
2) catch ブロック
catch ステートメントのパラメーターは、例外タイプと例外オブジェクトを含むメソッドの定義に似ています。
例外の種類は、catch ステートメントによって処理される例外の種類を指定する Throwable クラスのサブクラスである必要があります。
例外オブジェクトは、try で指定されたプログラム コード ブロック内の Java ランタイム システムによってスローされます。中括弧 処理メソッドのコード。
異なる種類の例外をそれぞれ処理するために複数の catch ステートメントを使用できます。
Java ランタイム システムは、一致する catch ステートメントが見つかるまで、各 catch ステートメントによって処理される例外タイプを上から下まで検出します。
ここで、型の一致とは、catch 内の例外の型が、生成された例外オブジェクトの型と完全に一致しているか、例外オブジェクトの親クラスであることを意味します。したがって、catch ステートメントのソート順序は特殊から一般の順である必要があります。 (理由を考えてください)
3) Finally ブロック
Finally ステートメントは、例外処理イベントのクリーンアップ メカニズムであると言えます。一般に、ファイルを閉じたり、他のシステム リソースを解放したりするために使用されます
try-catch には、finally 部分がありません。 -finally ステートメント ステートメント。
finally 部分がない場合、try で指定されたプログラム コードが例外をスローした場合、他のプログラム コードは実行されません。
finally 部分がある場合、try ブロックで例外が発生したかどうかは関係ありません。 catch 部分が実行されました。finally 部分のステートメントを実行する必要があります。
ステートメントのfinally部分が、例外処理の統一された終了を提供していることがわかります。
複数の例外処理
try ブロックは複数の異なる例外を生成する場合があります。これらの例外を処理するために異なるメソッドを使用したい場合は、複数の例外処理メカニズムを使用する必要があります。
複数の例外処理は、try ブロックの後に複数の catch ブロックを定義することで実現されます。各 catch ブロックは、特定の例外オブジェクトを受信して​​処理するために使用されます。
catch ブロックのパラメーターを使用して、例外オブジェクトにするかどうかを決定します。 catch ブロックによって受信および処理される例外。
例外オブジェクトと catch ブロックの例外パラメータの一致に基づいてどの catch ブロックが取得されるか: 次の 3 つの条件のいずれかを満たす場合、例外オブジェクトとパラメータは一致するとみなされます:
1) 例外オブジェクトとパラメータは同じ例外の種類に属します。
2) 例外オブジェクトはパラメータ例外クラスのサブクラスに属します。
3) 例外オブジェクトは、パラメータによって定義されたインターフェイスを実装します。
try ブロックによって生成された例外オブジェクトが最初の catch ブロックで受信された場合、プログラム フローはこの catch ステートメント ブロックに直接ジャンプし、ステートメント ブロックが実行された後、try ブロック内の未実行のステートメントが終了します。他の catch ブロックは無視されます
try ブロックによって生成された例外オブジェクトが最初の catch ブロックと一致しない場合、システムは自動的に 2 番目の catch ブロックに進み、2 番目の catch ブロックがまだ一致しない場合は、一致します。例外オブジェクトを受け取ることができる catch ブロックが見つかり、プロセス ジャンプが完了するまで、3 番目、4 番目と進みます。
try ブロックによって生成された例外オブジェクトが最初の catch ブロックによって受信された場合、プログラム フローはこの catch ステートメント ブロックに直接ジャンプし、ステートメント ブロックが実行された後、現在のメソッドが終了し、try 内の未実行のステートメントが削除されます。他の catch ブロックは無視されます
try ブロックによって生成された例外オブジェクトが最初の catch ブロックと一致しない場合、システムは自動的に 2 番目の catch ブロックに進み、2 番目の catch ブロックが一致しない場合は、一致します。例外オブジェクトを受け取ることができる catch ブロックが見つかり、プロセス ジャンプが完了するまで、3 番目、4 番目と進みます。
try ブロック内のすべてのステートメントの実行によって例外が発生しない場合、すべての catch ブロックは無視され、実行されません。
注:
1) catch ブロック内のステートメントは、さまざまな例外に応じて異なる操作を実行する必要があります
したがって、複数の例外を処理する場合は、各 catch ブロックの順序を慎重に設計することに注意を払う必要があります。一般に、より具体的で一般的な例外を処理する catch ブロックは前面に配置し、複数の例外に一致する catch ブロックは背面に配置する必要があります。

/*尝试用户运行错误的异常处理: 
 问题是这样的,当输入的用户工资初值少于800则是错误的,当然工资的变化如果超过20%,则也是错误的 
*/
import java.awt.*; 
import java.applet.*; 
import java.awt.event.*; 
public class UserExceptionApplet extends Applet implements ActionListener{ 
 Label prompt1=new Label("请输入雇员姓名和工资初值:"); 
 Label prompt2=new Label("请输入欲修改的工资"); 
 TextField name,isal,nsal; 
 String msg; 
 Employee Emp; 
 Button okBtn=new Button("OK"); 
 Button cancelBtn=new Button("Cancel"); 
 public void init(){ 
  name=new TextField(5); 
  isal=new TextField(5); 
  nsal=new TextField(5); 
  add(prompt1); 
  add(name); 
  add(isal); 
  add(prompt2); 
  add(nsal); 
  add(okBtn); 
  okBtn.addActionListener(this); 
  cancelBtn.addActionListener(this); 
  add(cancelBtn); 
 } 
 public void paint(Graphics g){ 
  g.drawString(msg,0,80); 
 } 
 public void CreateEmp(String empName,double sa){ 
  try{ 
   Emp=new Employee(empName,sa); 
   msg=new String(Emp.toString()); 
  } 
  catch(IllegalSalaryException ise){ 
   msg=new String(ise.toString()); 
  } 
 } 
 public void ChangeEmpSal(double changeSal){ 
  try{ 
   Emp.setEmpSalary(changeSal); 
   msg=new String(Emp.toString()); 
  } 
  catch(IllegalSalaryException illSal){ 
   msg=new String(illSal.toString()); 
  } 
  catch(IllegalSalaryChangeException illSalChange){ 
   msg=new String(Emp.toString()+illSalChange.toString()); 
  } 
 } 
 public void actionPerformed(ActionEvent e){ 
  String empName; 
  double empSal,changeSal; 
  Object obj=e.getSource(); 
  if(obj==okBtn){ 
   empName=new String(name.getText()); 
   if(empName==null){ 
    msg=new String("请先输入雇员姓名工资并创建之");  
   } 
   if(nsal.getText()==null){ 
    empSal=Double.valueOf(isal.getText()).doubleValue(); 
    CreateEmp(empName,empSal); 
   } 
   else{ 
    changeSal=Double.valueOf(nsal.getText()).doubleValue(); 
    ChangeEmpSal(changeSal); 
   } 
  } 
  if(obj==cancelBtn){ 
   naem.setText(""); 
   isal.setText(""); 
   nsal.setText(""); 
  } 
  repaint(); 
 }  
} 
  
class Employee{ 
 String m_EmpName; 
 double m_EmpSalary; 
   
 Employee(String name,double initsalary)throws IllegalSalaryException{ 
  m_EmpName=name;//看这里有问题没,参考代码为m_EmpName=new String(name); 
  if(initsalary<800){ 
   throw(new IllegalSalaryException(this,initsalary));//throw语句 
  } 
  m_EmpSalary=initsalary; 
 } 
 public String getEmpName(){ 
  return m_EmpName; 
 } 
 public double getEmpSalary(){ 
  return m_EmpSalary; 
 } 
   
 public boolean setEmpSalary(double newSal) throws IllegalSalaryException,IllegalSalaryChangeException{ 
  if(newSal<800) 
   throw(new IllegalSalaryException(this,newSal)); 
  else if(getEmpSalary()==0.0){ 
   m_EmpSalary=newSal; 
   return true; 
  } 
  else if(Math.abs(newSal-getEmpSalary())/getEmpSalary()>=0.2) 
   throw(new IllegalSalaryChangeException(this,newSal-getEmpSalary()));  
  else{ 
   m_EmpSalary=newSal; 
   return true; 
  } 
 } 
 public String toString(){ 
  String s; 
  s="姓名:"+m_EmpName+"工资: "+m_EmpSalary; 
  return s; 
 } 
} 
  
class IllegalSalaryException extends Exception{ 
 private Employee m_ConcernedEmp; 
 private double m_IllegalSalary; 
  
 IllegalSalaryException(Employee emp,double isal){ 
  super("工资低于最低工资"); 
  m_ConcernedEmp=emp; 
  m_IllegalSalary=isal; 
 } 
 public String toString(){ 
  String s; 
  s="为雇员提供的工资不合法:雇员:"+m_ConcernedEmp.getEmpName()+"非法工资:"+m_IllegalSalary+"低于最低工资数额800元"; 
  return s; 
 } 
} 
  
class IllegalSalaryChangeException extends Exception{ 
 private Employee m_ConcernedEmp; 
 private double m_IllegalSalaryChange; 
  
 IllegalSalaryChangeException(Employee emp,double csal){ 
  super("工资变动太大"); 
  m_ConcernedEmp=emp; 
  m_IllegalSalaryChange=csal; 
 } 
 public String toString(){ 
  String s; 
  s="为雇员提供的工资变动不合法:雇员:"+m_ConcernedEmp.getEmpName()+"非法变动工资变化:"+m_IllegalSalaryChange+"高于原工资的20%"; 
  return s; 
 } 
}
ログイン後にコピー

Java のイベント処理と例外処理メカニズムを分析するその他の記事については、PHP 中国語 Web サイトに注目してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート