プロが教えるわが家の防犯対策術!

 型Containerのメソッドadd(String ,Component)は引数(JPanel ,String)に適用できません。


 今晩は、java初心者です、エラーの意味が理解出来ません、宜しくお願い致します。

 《A》というプログラムと《B》というプログラムで、クラスを「class MyPanel extends JPanel」と「class JPanel」に変えただけで、「型Containerのメソッドadd(String ,Component)は引数(JPanel ,String)に適用できません。」というエラーがでます。

 一体何が原因でしょうか。
 JPanelを継承したクラス(MyPanel)を呼び出すのか、そのまま、JPanelクラスを呼び出すのかの違いだけで、内容的には何も変わるところがないはずだと思うのですが。
 意味が理解出来ません。

========================================================================
《A》

public class Sample extends JFrame
{
Sample()
{
this.setSize(300,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
this.add(panel , BorderLayout.CENTER);
this.setVisible(true);
}

public static void main(String[] args)
{
new Sample();
}
}

class MyPanel extends JPanel
{
public void paintComponent(Graphics g)
{
g.setColor(Color.red);
g.fillOval(50,50,100,100);
}
}

============================================================
《B》
public class Sample extends JFrame
{
Sample()
{
this.setSize(300,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
this.add(panel , BorderLayout.CENTER);
this.setVisible(true);
}

public static void main(String[] args)
{
new Sample();
}
}

class JPanel
{
public void paintComponent(Graphics g)
{
g.setColor(Color.red);
g.fillOval(50,50,100,100);
}
}
=======================================================================

A 回答 (6件)

>MyPanel panel = new MyPanel(); と


>JPanel panel = new MyPanel(); とはどのように違うのでしょうか。

元の質問の《A》の範囲では何も違いません。
JPanelを継承したクラスがMyPanel以外にもあったり、JPanelにないメソッドをMyPanelで定義したりすれば、どちらの宣言を使うかで差がつく例を作れますが。
    • good
    • 0
この回答へのお礼

salsberryさん、有難うございました。

今後ともよろしくお願いします。

お礼日時:2010/09/30 11:43

他の誰かが作ったクラスABCがあったとき、


class ABC {
public void m() { ~ }
}
のように書けば元のABCのメソッドm()を自分で好きなようにオーバーライドできると質問者さんは思っていたわけですか。
Javaにはそのような仕組みはありません。
自分で新しいクラス名をつけて
class DEF extends ABC {
public void m() { ~ }
}
のように書く必要があります。
ここでDEFのインスタンスはABC型の変数に代入できるので、
ABC v = new DEF();
という書き方ができます。

元の《A》に戻ると
MyPanel panel = new MyPanel();
のところの変数panelの型を変えて
JPanel panel = new MyPanel();
と書けます。これでJPanel型のpanelをJFrameにadd()できて、しかもMyPanelの中のpaintComponent()が有効になります。
質問者さんのやりたかったことはそういうことでしょうか?
    • good
    • 0
この回答へのお礼

salsberry さん回答有難うございます。

>元の《A》に戻ると
>MyPanel panel = new MyPanel();
>のところの変数panelの型を変えて
>JPanel panel = new MyPanel();
>と書けます。これでJPanel型のpanelをJFrameにadd()できて、しかもMyPanelの中のpaintComponent()
>が有効になります。

すみません、そもそも、
 MyPanel panel = new MyPanel(); と
 JPanel panel = new MyPanel(); とはどのように違うのでしょうか。

 両者のもつ意味の違いがわかりません。
 宜しくお願いします。

お礼日時:2010/09/26 23:52

> 「class JPane」を「class javax.swing.JPanel」と書いてやりましたが、


> "classの構文にエラーがあります"と吹き出しが表示されます。

class XXX { ~ }はクラス定義の構文ですが、
・javax.swing.のようなパッケージ名を付けたクラス名をXXXの部分に書くことは許されていません。
・javax.swing.JPanelのような既存のクラスと名前が衝突するクラスを定義しようとしないでください。パッケージ名なしのJPanelクラスを定義するのも、混乱の原因になるので避けるべきです。

ANo.3に書いた「質問者さんがJFrameにadd()したいものは次のどれですか?」には答えてもらえないのですね。
paintComponent()の内容を反映させたいということなので[b]ではないのだろうと思いますが、その一方で質問者さんが実際に試した
> javax.swing.JPanel panel = new javax.swing.JPanel();
> に書き直したらうまくいったのですが、
これは[b]の場合の書き方なので質問者さんが何をしたいのかが結局分かりません。

paintComponent()の内容を反映させたいのであれば、javax.swing.JPanelを継承したクラスを作って、その中でpaintComponent()をオーバーライドしてください。具体的には、《A》の書き方のままにするか、ANo.3に書いた「[a]の応用編」を使ってください。
質問者さんが定義しようとしているJPanelクラスはjavax.swing.JPanelを継承していませんし、上に書いたように同名のクラスを自分で定義するのは混乱の元です。
    • good
    • 0
この回答へのお礼

 salsberryさん、回答有難うございます。

>質問者さんがJFrameにadd()したいものは次のどれですか?

[a] 「javax.swing.JPanelクラスを継承してpaintComponent()をオーバーライドしたクラス」の
   インスタンス
[b] javax.swing.JPanelクラスそのもののインスタンス (継承していないのでpaintComponent()
   のオーバーライドはなし)
[c] その他

[a]は《A》の書き方そのものです。
[b]をお望みなら、《B》のコードから class JPanel { ~ } の部分を取っ払ってください。
  自分で定義したJPanelがなくなれば、JPanel panel = new JPanel();の部分はjavax.swing.JPanel
  を意味するようになります。
  さらにパッケージ名を省略せずにjavax.swing.JPanel panel = new javax.swing.JPanel();と
  書けば誤解の余地はなくなります。

[c]の場合は、何をどうしたいのかもっと説明してください。

 実は上の質問の意味が理解出来ません。
 私のやりたいことは、
 ・JFrameにJPanelをaddする
 ・そのためには、JPanelを別クラスとして作成し、paintComponent(Graphics g)をオーバーライドする
 ・JFrameにJPanelをaddするためには、JPanelのインスタンス化が必要
 ・JPanelクラスを承継したクラスを作成しなくても、直接親クラスを呼んで、その中のメソッドを
  オーバーライドしてやればよいと考えたのです。

 ・しかし、「JPanel」のみの記述では、親クラスとして認識されず、ユーザーが独自に定義したクラスと
  して認識されたというわけです。

 ・>javax.swing.のようなパッケージ名を付けたクラス名をXXXの部分に書くことは許されていません。
  (このルールは知りませんでした。)

 ・因みに、「class JPanel」のみの記述で、「javax.swing.JPanel」をimportしてやりましたが、
  import文の箇所で「JPanel」が衝突していますみたいなエラーメッセジが出ました。

 ・ならばという訳で、import文を削除し、「class javax.swing.JPanel」と書いた訳です。

 ・というわけで私には、[a]も[b]もしたいという答えになりそうな気がするのですが。

  色々試した結果、結論として、「「JPanel」のみの記述では、ユーザーが独自に定義したクラスとして認識
 され、必ず親クラスを承継しないとダメ」ということがわかりました。

お礼日時:2010/09/25 20:54

> # 通常親クラス(この場合JPanel)の、直接このような呼び出し方は文法違反になるのでしょうか。



《B》の書き方には「親クラスのJPanel」はどこにもありませんし、文法違反もありません。panelの型とadd()メソッドの型が合っていないので呼べないだけです。

> また、この書き方は、ユーザー独自の定義したクラスになるのでしょうか。

class JPanel { ~ }の部分でJPanelという名前の自前のクラスを定義していることは理解していますよね? そのクラスはjavax.swing.JPanelクラスとは何の関係もありません。

ちょっと視点を変えます。
質問者さんがJFrameにadd()したいものは次のどれですか?

[a] 「javax.swing.JPanelクラスを継承してpaintComponent()をオーバーライドしたクラス」のインスタンス
[b] javax.swing.JPanelクラスそのもののインスタンス (継承していないのでpaintComponent()のオーバーライドはなし)
[c] その他

[a]は《A》の書き方そのものです。
[b]をお望みなら、《B》のコードから class JPanel { ~ } の部分を取っ払ってください。自分で定義したJPanelがなくなれば、JPanel panel = new JPanel();の部分はjavax.swing.JPanelを意味するようになります。さらにパッケージ名を省略せずにjavax.swing.JPanel panel = new javax.swing.JPanel();と書けば誤解の余地はなくなります。
[c]の場合は、何をどうしたいのかもっと説明してください。

[a]の応用編で、「MyPanelというクラスを定義したくはないが、javax.swing.JPanelのpaintComponent()はオーバーライドしたい」のであればこういう書き方もあります。
javax.swing.JPanel panel = new javax.swing.JPanel() {
public void paintComponent(Graphics g) {
g.setColor(Color.red);
g.fillOval(50, 50, 100, 100);
}
};
this.add(panel, BorderLayout.CENTER);
this.setVisible(true);
無名クラスを使っているだけで本質的には《A》と変わらないのですが、初心者レベルだと混乱の度合いが深まるだけかもしれません。
    • good
    • 0
この回答へのお礼

salsberryさん、分かり易い回答有難うございます。

javax.swing.JPanel panel = new javax.swing.JPanel();
に書き直したらうまくいったのですが、

======================================================

class JPane
{
public void paintComponent(Graphics g)
{
g.setColor(Color.red);
g.fillOval(50,50,100,100);
}
}

======================================================

の内容は、反映されません。

そこで、「class JPane」を「class javax.swing.JPanel」と書いてやりましたが、
"classの構文にエラーがあります"と吹き出しが表示されます。

「class JPane」の場合には、何故「class javax.swing.JPanel」としても、エラー
になるのでしょうか。

お礼日時:2010/09/25 11:37

《B》 で定義したクラス JPanel と 《A》 で extends しているクラス JPanel は別物ではないだろうか.

    • good
    • 0

質問文では省略されている部分に「import javax.swing.JPanel;」とか「import javax.swing.*;」という宣言があるんじゃないかと思います。


《A》のプログラムに書かれているJPanelはjavax.swing.JPanelのことですが、《B》では自分でJPanelというクラスを定義してしまっており、これはjavax.swing.JPanelとは別物です。当然、SwingのJPanelの持っている様々な特性 (SwingのJComponentを継承していることなど) は質問者さんのJPanelにはありません。

JFrame (とその親クラス) が持っている二引数のadd()メソッドは
add(java.awt.Component, int)
add(java.awt.Component, java.lang.Object)
add(java.lang.String, java.awt.Component)
がありますが、このいずれも引数の型が (質問者さん独自のJPanel, BorderLayout.CENTER) の組み合わせとは合わないのでエラーになります。
    • good
    • 0
この回答へのお礼

salsberryさん、回答有難うございます。

>《B》では自分でJPanelというクラスを定義してしまっており、これはjavax.swing.JPanelとは別物です。

# 通常親クラス(この場合JPanel)の、直接このような呼び出し方は文法違反になるのでしょうか。
  また、この書き方は、ユーザー独自の定義したクラスになるのでしょうか。

お礼日時:2010/09/23 22:09

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!