意味がわからないGUI入門書の中古本のサンプルコードの解説をお願いします

このQ&Aのポイント
  • JavaのGUI入門書を中古で購入しましたが、サンプルコードが意味がわからずコンパイルエラーが発生しています。どなたか解説していただけますか。
  • 私はWin VistaとJDK7を使用しています。以下がソースコードとコンパイルエラーです。
  • このコードでは、MyButtonクラス内にあるmainメソッドでボタンを作成し、ボタンのアクションリスナーとしてMyActionListenerクラスのインスタンスを追加しています。しかし、buttonがstaticではないためにコンパイルエラーが発生しています。
回答を見る
  • ベストアンサー

GUI入門書のサンプルコード

JavaのGUIをやってみようと思い中古で本を買ってきたのですが、 その中のサンプルコードが意味がわからない上にコンパイルエラーを起こすので 誰か解説をお願いします。 OS:Win Vista、それとJDK7です。 以下がソースコードとコンパイルエラーになります。 import java.awt.*; import javax.swing.*; import java.awt.event.*;    //サンプルではActionListenerを使うのに抜けていた public class MyButton { ____JButton button; ________//※1 何故ここで宣言しているのか ____public static void main(String[] args) { ________JFrame frame = new JFrame("MyFrame"); ________Container pane = frame.getContentPane(); ________JButton button = new JButton("MyButton");________//※1 何故ここにもあるのか ________button.addActionListener(new MyActionListener()); //※2 MyActionListenerクラスはstaticでないので使用できない ________pane.add(button); ________frame.setBounds(100, 50, 300, 200); ________frame.setVisible(true); ________frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ____} ____class MyActionListener implements ActionListener { ________public void actionPerformed(ActionEvent e) ________//サンプルではpublicが抜けていた ____________if(e.getSource() == button) ________________System.out.println("button was pressed"); ________} ____} } /* MyButton.java:13: static でない 変数 this を static コンテキストから参照すること はできません。 button.addActionListener(new MyActionListener()); ^ エラー 1 個 */

  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
noname#161640
noname#161640
回答No.1

見てて、頭がくらくらしてくるサンプルコードですね。そのソースをすべて活かした形で修正するのは無理です。まぁ、極力、作者の意図をくんだつもりで修正すると、こんな感じでしょうか。 package jp.sample; // 適当に import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; public class MyButton { static JButton button = new JButton("MyButton"); public static void main(String[] args) { JFrame frame = new JFrame("MyFrame"); Container pane = frame.getContentPane(); button.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e){ if(e.getSource() == button) System.out.println("button was pressed"); } }); pane.add(button); frame.setBounds(100, 50, 300, 200); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } かなり気持ち悪いですが……。 まぁ、本が古いということなので、JDKのバージョンがあがったために引っかかる部分もありますが、それ以前の話として、そのサンプルを考えた人は、クラスとインスタンスの根本的なところがわかっていないように思えます。正直いえば、その本で勉強するのはやめたほうが無難です。この作者は、自分の書いたソースコードが実際に動くかどうかまったく検証していませんね。 いくつか補足を。 ※1 何故ここで宣言しているのか おそらく、その後でMyActionListenerインスタンス内のactionPerformed内でe.getSource() == buttonというようにインスタンスを参照するのでフィールドとして保管しておけばいい……というように考えたのでは、と想像できます。が、この作者は、自分自身(MyButtonクラス自身)をインスタンス化していない、ということに考えが至らなかったようです。したがって、このインスタンスフィールドはまったく意味をなしていません。 ※1 何故ここにもあるのか 結局、これがそのまま使われてしまう、ということになるでしょう。インスタンスフィールドに宣言したのを忘れて、ここでも宣言している、としか思えません。 ※2 MyActionListenerクラスはstaticでないので使用できない staticでない、というか、そもそもこのMyButton自体はインスタンス化されていないのですよ……。インスタンス化されていないクラス内の内部クラスを使うという時点で設計に無理があります。 全体としてもっとも無理がないのは、MyButtonをextends JFrameし、このmyButtonクラスのインスタンスを生成して使う、という感じでしょう。以下のような感じでしょうか。 import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; public class MyButton extends JFrame { JButton button = null; public static void main(String[] args) { MyButton frame = new MyButton("MyFrame"); } public MyButton(String s){ super(s); Container pane = this.getContentPane(); button = new JButton("MyButton"); button.addActionListener(new MyActionListener()); pane.add(button); this.setBounds(100, 50, 300, 200); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } class MyActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e){ if(e.getSource() == button) System.out.println("button was pressed"); } } }

jaxocd
質問者

お礼

ありがとうございます。 スコープの観点から書いたbuttonも、内部クラスもインスタンス化しないとアクセスできないんですね。すっきりしました。 この本は約10年前の物で、サンプルは前例のコピペに追記して…といった感じなので誤植が多いです。 買い替えも検討します。

関連するQ&A

  • JFrame の再表示を禁止したい。

    親ウィンドウのボタンを押して、子ウインドウが表示される仕組みなのですが、1 つ表示した後は、 表示させないようにしたいと考えコードを組みましたが、以下コードでは、null 例外が出てしまいます。 良い方法はありませんでしょうか? みなさん、どうぞよろしくお願い致します。 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class FramesTest { public static void main(String[] args) { JFrame frameMain = new JFrame("Main"); frameMain.setSize(256, 128); frameMain.getContentPane().add( new BT() ); frameMain.setVisible(true); } } class BT extends JPanel implements ActionListener { /** * */ private static final long serialVersionUID = 1L; /*-------------------------* * Variables. * *-------------------------*/ static String cmdName; static JButton button; static JFrame subJFrame; /*-------------------------* * Methods. * *-------------------------*/ BT() { super( new BorderLayout() ); button = new JButton("button"); button.addActionListener(this); add( button ); setPreferredSize(new Dimension(320, 100)); } void createFrame() { subJFrame = new JFrame( "sub" ); subJFrame.setVisible(true); subJFrame.setSize(256, 128); } @Override public void actionPerformed(ActionEvent e) { cmdName = e.getActionCommand(); if ("button".equals(cmdName)) { if ( !subJFrame.isActive() ) { createFrame(); } } } }

    • ベストアンサー
    • Java
  • javaのmainの中のループに割込を掛ける

    毎度、お世話になります。 javaのmainの中のループに割込を掛ける方法をお教えください。 添付コードの『Thread.currentThread().interrup()』は、旨く機能しません。 以上、宜しくお願いします。 =========== import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class T_try_loop extends JFrame{ JFrame frame=new JFrame(); T_try_loop(){ System.out.println("aaaa"); JPanel p1=new JPanel(); JButton button1=new JButton("button1"); button1.addActionListener(new TimButton1()); p1.add(button1); getContentPane().add(p1, BorderLayout.CENTER); } public static void main(String args[]){ T_try_loop frame=new T_try_loop(); frame.setTitle("TTTT"); frame.setBounds(10,10,400,300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); for(int j = 0;j < 80; j++){ try{ Thread.sleep(80); System.out.print("*"); } catch(InterruptedException e){ System.out.println(": main_loopに、今割り込まれました"); } } }//public static void main public class TimButton1 implements ActionListener{ @Override public void actionPerformed(ActionEvent ae){ String cmd =ae.getActionCommand(); if(cmd.equals("button1")){ Thread.currentThread().interrupt(); System.out.println("Button clicked"); } } }//public class TimButton1 }

    • ベストアンサー
    • Java
  • javaのBoxlayoutについて

    下記はBoxLayout用ののコードです。 Q1)Buttonのサイズを設定する方法がありますか? Q2)Buttonの配置を設定する方法がありますか? //===================================== import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.LayoutManager; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class AlignmentX extends JFrame{ JButton button1; JButton button2; JButton button3; public static void main(String[] args){ AlignmentX frame = new AlignmentX(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setTitle("タイトル"); frame.setVisible(true); } AlignmentX(){ button1 = new JButton("AAAAA"); button1.setAlignmentY(0.5f); button1.setPreferredSize(new Dimension(80,20)); button2 = new JButton("BBB"); button2.setAlignmentY(0.5f); button2.setPreferredSize(new Dimension(80,20)); button3 = new JButton("CC"); button3.setAlignmentY(0.5f); button3.setPreferredSize(new Dimension(80,20)); JPanel p = new JPanel(); p.setLayout((LayoutManager) new BoxLayout(p, BoxLayout.Y_AXIS)); p.add(button1); p.add(button2); p.add(button3); getContentPane().add(p, BorderLayout.CENTER); setBounds(10, 10, 300, 200); } } //以上,宜しくお願いします。

    • ベストアンサー
    • Java
  • javaのJTextFieldにマウスフォーカス

    お世話になります。 Q1)下記のコードに於きまして、JTextFieldにマウスフォーカス が当りますと、その旨、System.out.println("JTextField_tt")と表示する方法をお教えください。 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.LineBorder; public class EObjectTest extends JFrame implements ActionListener { public static JButton b1; public static JButton b2; public static JTextField tt; static EObjectTest frame; public static void main(String args[]){ frame=new EObjectTest("AAAA"); frame.setVisible(true); } EObjectTest(String title) { setTitle(title); setBounds(100, 100, 300, 250); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel p = new JPanel(); // ボタン作成・追加 b1 = new JButton("One"); b2 = new JButton("Two"); tt = new JTextField("aaa"); LineBorder border = new LineBorder(Color.RED, 2, true); tt.setBorder(border); tt.setColumns(15); p.add(b1); p.add(b2); p.add(tt); Container contentPane = getContentPane(); contentPane.add(p, BorderLayout.CENTER); // リスナ登録 b1.addActionListener(this); b2.addActionListener(this); tt.addActionListener(this); } public void actionPerformed(ActionEvent e) { // getSource() でイベントソースのオブジェクトを獲得し // Button クラスにキャストする JButton b = (JButton)e.getSource(); // JTextField ttt = (JTextField)e.getSource(); if (b==b1) { System.out.println("Oneのボタン"); } if (b==b2) { System.out.println("Twoのボタン"); } /* if (ttt==tt) { System.out.println("JTextField_tt"); } */ } } 以上

    • ベストアンサー
    • Java
  • JButtonの配置

    FlowLayoutによって、JFrameにボタン6個を2×3に配列するプログラムを考えています。ボタンを配置することはできたのですが、ウインドウの大きさを変えるとボタンが3×2になったりと変更してしまいます。 ウインドウの大きさを変えても、ボタンの大きさは変えず、ボタン6個が2×3配列になるプログラムはどうしたらよいのでしょうか?以下は、途中のプログラムです。 import java.awt.*; import javax.swing.*; public class sample { public static void main(String[] args){ MyFrame frame = new MyFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } } public class MyFrame extends JFrame { public static final int WIDTH = 200; public static final int HEIGHT = 300; public MyFrame(){ setSize(WIDTH,HEIGHT); Container contentPane = getContentPane(); MyPanel panel = new MyPanel(); contentPane.add(panel); } } public class MyPanel extends JPanel{ public static final int MESSAGE_X = 200; public static final int MESSAGE_Y = 200; setLayout(new FlowLayout()); JButton button1 = new JButton("Button1"); contentPane.add(button1); JButton button2 = new JButton("Button2"); contentPane.add(button2); JButton button3 = new JButton("Button3"); contentPane.add(button3); JButton button4 = new JButton("Button4"); contentPane.add(button4); JButton button5 = new JButton("Button5"); contentPane.add(button5); JButton button6 = new JButton("Button6"); contentPane.add(button6); }

    • ベストアンサー
    • Java
  • main()メソッドが無いコード

    最近、Javaアプレット等を勉強してるのですが 今まではmain()メソッドの中に処理を書いて来たのですが、 下記の様なコードにはmain()メソッドが有りません。 import java.applet.Applet; import java.awt.Button; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class Sample6 extends Applet implements ActionListener { Button bt; public void init() { bt = new Button("開始"); add(bt); bt.addActionListener(this); } public void actionPerformed(ActionEvent ae) { bt.setLabel("中止"); } } これはどう言う事なんでしょうか?

    • ベストアンサー
    • Java
  • javaについて質問

    import javax.swing.*; import java.awt.Color; import java.awt.Graphics; import java.awt.event.*; public class tt extends JFrame { public tt(){ setTitle("hogehoge"); setBounds( 10, 10, 300, 200); JButton btn1 = new JButton("続ける"); final JPanel p = new JPanel(); p.setBackground(Color.white); btn1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event){ } } ); p.add(btn1); getContentPane().add(p); } public static void main(String[] args){ tt test = new tt(); test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); test.setVisible(true); /* 実際に表示する */ } } Graphics g; g.drawString("ほげさんじょう",130,120);を追加しても コンパイルが通りません。 どうすれば画面に文字列を表示するんですか? あとテキストフィールドを追加するさいに、座標していとかして追加できないんですか?

  • java(swing)で、登録ボタンを押すとファイルを読み込みDBに登

    java(swing)で、登録ボタンを押すとファイルを読み込みDBに登録する処理です。 その処理で、登録ボタンを押すと、ダイアログを起動して、処理中とメッセージ表示したいのですが、データが多く、画面が固まった状態になり、メッセージが表示されないのです。何かいい方法ありますでしょうか? ******************************************************************* import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; public class topMain { public static void main(String[] args) { //メニュー画面を起動する topMain frame = new topMain(); frame.topFrame(); } private void topFrame() { JFrame jf = new JFrame(); //フレームのサイズ設定 jf.setSize(1000, 600); jf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); jf.getContentPane().setLayout(null); JButton b1 = new JButton("登録ボタン"); b1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //ダイアログボックスを開く     //ダイアログボックスは起動するが、 //メッセージが表示されない、 //おそらく大きいデータを読むとき画面が固まるため //重いファイルを読み込む //DB登録処理 //ダイアログを閉じる } }); jf.getContentPane().add(b1); b1.setBounds(40, 400, 240, 100); jf.setVisible(true); } } *******************************************************************

  • コンパイルエラーの対応

    下記のプログラムをコンパイルしたらエラーが発生しました。 プログラム自体は本をそのまま書き写したのですが、何がいけないのでしょう。 教えてください。よろしくお願いします。 Javaのバージョンは1.3.1です import java.applet.*; import java.awt.*; import java.awt.event.*; public class sample3 extends Applet implements ActionListener { Button bt; public void init() { bt = new Button("押します!"); bt.addActionListener(this); add(bt); } public void actionperformed(ActionEvent ae) { bt.setLabel("押しました!"); } } -----------------エラー内容----------------------- sample3.java:4: sample3 は abstract として宣言する必要があります。 actionPerformed(java.awt.event.ActionEvent) を sample3 で定義しません。 public class sample3 extends Applet implements ActionListener ^

    • ベストアンサー
    • Java
  • フレームを消したい

    こんにちは。 いつもお世話になっております。 また、どうしてもわからないことが出てきてしまいました。 質問よろしいでしょうか? 以下のプログラムを実行して 「次へ」と書かれたボタンをクリックし 次に現れるフレーム上の「このフレームだけ消す」 と書かれたボタンをクリックしたときに 「f2」(2つ目のフレーム)だけ閉じるようにしたいのです。 以下の場合は両方とも閉じてしまうのです。 何かよい方法ご存知ありませんか? よろしくお願いいたします。 ================================================== import java.awt.*; import javax.swing.*; import java.awt.event.*; class unload { public static void main(String[] args) { JFrame f=new JFrame("kiki"); Origin p=new Origin(); Container ct=f.getContentPane(); ct.add(p); f.pack(); f.setVisible(true); } } class Origin extends JPanel implements ActionListener { JButton b; Origin() { b=new JButton("次へ"); this.add(b); b.addActionListener(this); } public void actionPerformed(ActionEvent e) { if (e.getSource()==b) { JFrame f2=new JFrame(); Origin2 p2=new Origin2(); Container ct=f2.getContentPane(); ct.add(p2); f2.pack(); f2.setVisible(true); } } } class Origin2 extends JPanel implements ActionListener { JButton b2; Origin2() { b2=new JButton("このフレームだけ消す"); this.add(b2); b2.addActionListener(this); } public void actionPerformed(ActionEvent e) { if(e.getSource()==b2) { System.exit(0); } } }

    • ベストアンサー
    • Java

専門家に質問してみよう