• 締切済み

JComponentを継承して処理をJButtonに委譲

例えば、JButtonのメソッドの仕様を  int getText();  void setText( int value ); と、変更したい場合を考えます。 このとき、 public IntegerButton extends JComponent {    JButton delegator;    public IntegerButton(int value, Icon icon) {   delegator = new JButton(Integer.toString(value), icon);   setLayout(new BorderLayout());   add(delegator);  }    public int getText() {   return Integer.parseInt(delegator.getText());  }  public void setText(int value) {   delegator.setText(Integer.toString(value));  }      //委譲メソッド  public void addMouseListener(MouseListener ml) {   delegator.addMouseListener(ml);  }  public void removeMouseListener(MouseListener ml) {   delegator.removeMouseListener(ml);  }     } という感じで書くことになると思うのですが、疑問なのは JComponent,AbstractButton等継承しているクラスの中の、 どのメソッドを転送する必要があるのかが不明なことです。 addMouseListener(MouseListener ml)は委譲する必要があると 思うのですが、逆にpaint(Graphics g)を委譲すると 上手くいかなくなります。 また、requestFocusInWindow()に関しては、  public boolean requestFocusInWindow() {   super.requestFocusInWindow();   return delegator.requestFocusInWindow();  } とする必要があるのかもしれません。 この正攻法が載っているようなサイト、本や資料等を ご存知でしたらご教示ください。

  • Java
  • 回答数2
  • ありがとう数0

みんなの回答

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.2

JComponentをextendsするのは、ふつう、カスタムコンポーネントを作るときですね。それ以外では意味がないばかりか、使いようがないでしょ。むりやり使うとしたら、このオブジェクトを使うコンテナのadd()メソッドまでオーバライドしなければならないから、もお~~たいへん!。それを避けるためにJComponentにJButtonのUI体系とイベント体系をすべて完全に再演させるとしたら、もお~~の二乗三乗ぐらいたいへん!! Blochが何と言おうと、これぐらいの簡単なやつは、extends JButtonでgetInt()でも定義すれば十分。ていうか、それすら不要です。

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.1

現在のおたくの extends JComponent では、クラスにJComponentとしての実体がまったくないので、おかしいだけでなく、非常に使いづらいクラスになります。むしろ、JButtonのメソッドを増やしたいだけなら、 extends JButton だけで十分です。 もうすこしプロフェッショナルに言えば、  int getText();  void setText( int value ); たかがこの程度のメソッドを設けるために拡張クラスを作るのは、おおげさで不経済です。単純にJButtonのインスタンスをアプリ中で使えば十分です。StringのgetText()の結果をintに変換するのも、またintをStringに変換してsetText()するのも、新たにメソッドを作るほどの処理ではありません。

ggable
質問者

補足

>extends JComponent >では、クラスにJComponentとしての実体がまったくないので、おかしいだけでなく、 どういう意味でしょう。  public class JPanel extends JComponent implements Accessible  public class JScrollPane extends JComponent implements ScrollPaneConstants, Accessible ご存知とは思いますが、JPanelもJScrollPaneも当然JComponentを継承しています。 >もうすこしプロフェッショナルに言えば、 > int getText(); > void setText( int value ); >たかがこの程度のメソッドを設けるために拡張クラスを作るのは、おおげさで不経済です。 不経済かどうかなんて問題ではなく、論理的に継承が向いているか、 コンポジション実装が向いているかの問題でしょう。 Effective Java 4章項目14にも「継承よりもコンポジションを選ぶ」とあります。 >たかがこの程度のメソッドを設けるために拡張クラスを作るのは、 言うまでもなく、これが実現したいことではないですよ。 JComponentの継承の正しい方法が知りたいということです。 String getText()メソッドがJButtonクラスには定義されているので、 JButtonクラスを継承しては、int getText()メソッドは定義できない という意味であげた単なる例です。

関連するQ&A

  • JButtonの座標(0,0)にアイコンをセット

    JButtonに以下のように、画像を書込む際、画像を一番は端(左上角)から乗せたいです。 つまり、ボタンの右上角(0,0)から乗せたいのです。 現状では、左端に隙間があいてしまいます。 この方法がご存知の方がおられましたら教えてください。 よろしくお願いいたします。 import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; public class Zoom extends JComponent { private static final long serialVersionUID = 1L; private ImageIcon icon = null; private int x = 0; private int y = 0; private int h = 0; private int w = 0; private double scale = 1.0d; public Zoom(ImageIcon icon, int x, int y, int w, int h) { super(); this.icon = icon; this.x = x; this.y = y; this.w = w; this.h = h; } public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.scale(scale, scale); g2.drawImage(icon.getImage(), x, y, w, h, this); } public static void main(String[] args) { ImageIcon icon = new ImageIcon("cherry.jpg"); Zoom zoom = new Zoom(icon,0,0,100,100); JButton b = new JButton(); JFrame f = new JFrame(); b.add(zoom); b.setPreferredSize(new Dimension(icon.getIconHeight(), icon.getIconWidth())); f.add(b); f.pack(); f.setVisible(true); } }

    • ベストアンサー
    • Java
  • JButtonの画像をactionPerformedメソッド内で再描画

    JButtonの画像をactionPerformedメソッド内で再描画したい。 以下のソースのようにして、再描画したいのです。 setIconメソッドではなく、 JButtonに対して描画したものに対して再描画したいです。 Graphics2DクラスについてJAVA APIで調べましたが、 仕組の理解に至りませんでした。 仕組みと方法を教えて頂きたいです。 よろしくお願いいたします。 import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; public class test extends JFrame implements ActionListener{ JButton b= new JButton(); public static void main(String a[]) { new test(); } public test() { super(); this.setSize(100,100); b.addActionListener(this); b.add(new Zoom(new ImageIcon("img1.jpg"),0,0,50,50)); this.add(b); this.setVisible(true); } class Zoom extends JComponent { private static final long serialVersionUID = 1L; private ImageIcon icon = null; private int x = 0; private int y = 0; private int h = 0; private int w = 0; private double scale = 1.0d; public Zoom(ImageIcon icon, int x, int y, int w, int h) { super(); this.icon = icon; this.x = x; this.y = y; this.w = w; this.h = h; } public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.scale(scale, scale); ////////////////////////////////// //画僧を再描画したい。 //g2.clearRect(0, 0, 80, 80);//× g2.drawImage(icon.getImage(), x, y, w, h, this); } } public void actionPerformed(ActionEvent e) { if(e.getSource()==b){ System.out.print("ok"); //this.repaint();//× //b.repaint();//× b.add(new Zoom(new ImageIcon("img2.jpg"),0,0,50,50));//(再描画できない) //b.setIcon(new ImageIcon("img2.jpg"));//ok(再描画出来る) } } }

    • ベストアンサー
    • Java
  • 簡単電卓をjavaプログラムで作成しました。

    テキストフィールドに入力し、四則演算ボタンを押すと答えた表示されるように作ったのですが、答えが表示されません。どなたかご教授ください。お願いいたします。 import java.applet.Applet; import java.awt.*; // java.awtパッケージのインポート import java.awt.event.*; public class EasyCulc extends Applet { Button plus, minus, multi, div; // ボタン TextField txta, txtb, ans; // 数値入力用テキストボックス public void init() { plus = new Button("+");// ボタンのインスタンスを作成 plus.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // txtaに入力された値 + txtbに入力された値を計算 int answer = Integer.parseInt(txta.getText()) + Integer.parseInt(txtb.getText());ans.setText(Integer.toString(answer));// 答えをansに表示 } }); minus = new Button("-");// ボタンのインスタンスを作成 minus.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // txtaに入力された値 - txtbに入力された値を計算 int intAnswer = Integer.parseInt(txta.getText()) - Integer.parseInt(txtb.getText()); ans.setText(Integer.toString(intAnswer));// 答えをansに表示 } }); multi = new Button("x");// ボタンのインスタンスを作成 multi.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // txtaに入力された値 x txtbに入力された値を計算 int intAnswer = Integer.parseInt(txta.getText()) * Integer.parseInt(txtb.getText()); ans.setText(Integer.toString(intAnswer));// 答えをansに表示 } }); div = new Button("÷");// ボタンのインスタンスを作成 div.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // txtaに入力された値 ÷ txtbに入力された値を計算 int intAnswer = Integer.parseInt(txta.getText()) / Integer.parseInt(txtb.getText()); ans.setText(Integer.toString(intAnswer));// 答えをansに表示 } }); // コンポーネントの初期化 txta = new TextField("", 5); txtb = new TextField("",5 ); plus = new Button("+"); minus = new Button("-"); multi = new Button("x"); div = new Button("÷"); ans = new TextField("", 5); // コンポーネントを追加 this.add(txta); this.add(txtb); this.add(plus); this.add(minus); this.add(multi); this.add(div); add(new Label("計算結果")); this.add(ans); } }

  • JButton配列でのイベント処理

    JAVA初心者です。 ある、画面にボタン50個を作成しました。(JButtonの配列で作成しました。) そこで質問です。下記のコールバックメソッド(?)btnActionPerformedを50個分作成するのは 煩雑なので1つで処理しようと考えております。 for (int cnt=0; cnt<50; cnt++) { ... JButtonのインスタンス生成処理等 ... btn[cnt-1].addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnActionPerformed(evt); } }); } ... ... ... private void btnActionPerformed(java.awt.event.ActionEvent evt) { ... } btnActionPerformedで受け取ったevtパラメータから押されたボタンのプロパティ等 が判別つくのでしょうか?ActionEventクラスのヘルプを参照しましたが、 いまひとつ良くわかりません。 また、このevtパラメータを使う方法以外で、この様な事が実現できる方法が あれば教えてください。よろしくお願いします。

    • ベストアンサー
    • Java
  • 一桁電卓(setText)

    //<applet code="Calc.class" width="250" height="150" ></applet> import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Calc extends JApplet implements ActionListener{ JTextField display; int row=4,column=4,value=0,d; char str,str2; JButton[][] button=new JButton[row][column]; String[][] buttonName={{"7","8","9","/"}, {"4","5","6","*"}, {"1","2","3","-"}, {"0","C","=","+"}}; public void init(){ Container pane=getContentPane(); JPanel panel=new JPanel(); panel.setLayout(new GridLayout(4,4)); display=new JTextField(String.valueOf(value)); pane.add(display); display.setHorizontalAlignment(JTextField.RIGHT); display.setEditable(false); for(int a=0;a<row;a++){ for(int b=0;b<column;b++){ button[a][b]=new JButton(buttonName[a][b]); panel.add(button[a][b]); button[a][b].addActionListener(this); } } pane.add(panel,BorderLayout.SOUTH); } public void setText(int c){ if(str2!='/'&&str2!='*'&&str2!='-'&&str2!='+'){ value=c; } else if(str=='='){ display.setText(String.valueOf(value)); } if(str!='/'&&str!='*'&&str!='-'&&str!='+'&&str!='='){ display.setText(String.valueOf(c)); if(str2=='/')value=value/c; if(str2=='*')value=value*c; if(str2=='-')value=value-c; if(str2=='+')value=value+c; } else{ display.setText(String.valueOf(value)); if(str2=='/')value=value/c; if(str2=='*')value=value*c; if(str2=='-')value=value-c; if(str2=='+')value=value+c; } } public void actionPerformed(ActionEvent e){ for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ if(e.getSource()==button[i][j]){ str=buttonName[i][j].charAt(0); switch(str){ case '/': str2=str; setText(1); break; case '*': str2=str; setText(1); break; case '-': str2=str; setText(0); break; case '+': str2=str; setText(0); break; case '=': setText(d); break; case 'C': str2=str; value=0; setText(value); break; default: d=Integer.parseInt(buttonName[i][j]); setText(d); break; } } } } } } 上のプログラムは一桁電卓です。 プログラムは思ったように動くんですが、 seText(0、または1)の部分がどういう役目を果たしているか、0と1でどう違ってくるのかが分かりません。できればsetText(char)の説明も交えて教えていただけませんか?

  • javaの不思議

    C言語をたしなむ程度にやっているものです。 Javaを勉強していたのですが、不思議だなと思ったので質問させてください。 Integer value = new Integer(30); value.doubleValue() // <- double型に変換している このプログラムだとvalueはintなのにあらかじめdoubleに変換できることを想定しています。 C言語の癖なのかしらないですが、型変換をするならクラスメソッドではなくキャストするか、 メソッドに投げる(Integer.toString←stringにする例ですが)。 この2つの方法が自然な型変換だと思うのですが、変でしょうか?

    • ベストアンサー
    • Java
  • ボタンクリック後パネルを再描画repaintしたい

    ボタンをクリック後にstaticで保持していた値にプラス1して その値をパネルに再描画したいと思っています。 下記のプログラムだとボタンをクリックすると (<1<2<3<4)となって画像と数字が増えてしまいます 行いたいのは数字の部分だけが再描画されて カウントされて<3と表示されるだけになってもらいたい クラス1つ目 import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.event.MouseEvent; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Sample extends JFrame{ static int value=1; JPanel work = new JPanel(); public static void main(String[] args) { Sample frame = new Sample(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(100, 200, 200, 100); frame.add(frame.createPanel(), BorderLayout.LINE_END); frame.setVisible(true); } public JPanel createPanel() { ImageIcon icon = new ImageIcon("./img/left.gif"); JLabel label = new JLabel(); Cursor c = new Cursor(Cursor.HAND_CURSOR); label.setCursor(c); label.setIcon(icon); JLabel strLabel = new JLabel(); String str = Integer.toString(value); strLabel.setText(str); work.add(label); work.add(strLabel); label.addMouseListener(new myListener()); return work; } class myListener extends MouseAdapter{ public void mouseClicked(MouseEvent e){ System.out.print(Sample.value++); createPanel().repaint(); setVisible(true); } } } クラス2つ目 import java.awt.event.MouseEvent; import java.awt.event.MouseListener; public class MouseAdapter implements MouseListener{ public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e){} }

    • ベストアンサー
    • Java
  • Java 可変長引数と優先度

    Java 可変長引数と優先度  こんにちは。c#初心者兼、java始めました です。  可変長引数の場合のオーバーロードの優先度について困っています(質問と言うより半分愚痴です)。  javaにも可変長引数ってありますよね。(ジェネリックの弱さにイライラしていたけれど)「javaも捨てたものじゃない」と感心しながら使っていると、いきなりコンパイルエラー。  sampleMethod(10, 20); と書いている部分でエラーが発生していました。  自分のメソッド定義を確認しみると、  void sampleMethod(int...);  void sampleMethod(Object...);  の2種類のオーバーロードがあり、ambiguousなため判別不能らしいです。    確かに、AutoBoxingされれば、int...だけでなく、Object...にもマッチしますが、どう考えてもBoxingしない方が優先度が高いはずです。というか、高く設定されるべきです。  個人的に基準にしているc#ではこのようなことは起きませんでした。  (あ、やっぱり捨てたものかもしれない ←心変わり早す(ry )    試しにc#でInteger型のクラスを作り、(実際はタブーですが)暗黙のキャストを双方向でオーバーロードして実験してみました。   public class Integer // ここからc# {   private int _value;   //----------------------------   public Integer(int value) { _value = value; }   //----------------------------   // Integer → int の暗黙の型変換   public static implicit operator int(Integer value)   { return value._value; }   // int → Integer の暗黙の型変換   public static implicit operator Integer(int value)   { return new Integer(value); }   //----------------------------   // javaの sampleMethod(int... values)に相当   public static void SampleMethod(params int[] values) { }   // javaの sampleMethod(Object... values)に相当   public static void SampleMethod(params Object[] values) { } }  そして、Integer.SampleMethod(10, 20); と書いてみると……問題……なし。  ちゃんと、SampleMethod(param int[] values)が選ばれていました。  つまり、(個人的には)java(コンパイラ)の方が不可解な動きをしているのです。  sampleMethod(int, int)とsampleMethod(Object, Object)があるときは問題ないので、可変長引数のときだけambiguousになるようです。  「それなら」と思い、sampleMethod(int, int...)とsampleMethod(Object, Object...)を作ってみましたが、やはりエラーが出ます。  何か良い解決策はあるでしょうか?  可変長じゃない引数のオーバーロードを大量に作ることと、片方の可変長をやめること以外でアドバイスをお願いします。  もしくは、「個人的には~だから、パクリのc#よりjavaの方が動きが正しいぞ!」という方がいらっしゃいましたら、ご意見ください。

  • 配列の型判定の仕方

    メソッドの引数をObjectにして、その引数の型を判定しようとしています。 たとえば以下のような感じです。 String hoge(Object para) { if(para.equals(java.lang.Integer.class)) { return "intです"; } return "わかりません" } 上記は、int型なら判定できるメソッドですが、int[]やString[]を判定するためにはどうしたらよいのでしょうか? paraにint[]型の値が入ってきた場合、 para.equals(java.lang.Integer[].class) としてもtrueにはなりませんでした。 どうすればできるのか、ご教授いただけると幸いです。 手段がなければ、para.getClass().toString()をして出力される文字列で判定しようかと思っています。

    • ベストアンサー
    • Java
  • どこが間違ってますか?

    アプレットを作っています。ここの前まではあっていて、おつりも~円です とでるのですが、計算結果が0以下でもこのおつりが足りませんというのが実行されません。 誰かよかったら教えて下さい。 if(event.getSource() == button2) {int diff = Integer.parseInt(textfield1.getText()) - Integer.parseInt(label3.getText()); if(diff < 0){ String otsuri; otsuri ="おつりが足りません"; label1.setText(otsuri);} String otsuri; otsuri ="お釣りは"+ diff +"円です。"; label1.setText(otsuri);}

    • ベストアンサー
    • Java

専門家に質問してみよう