2016-12-28 115 views
0

我正在嘗試與Java Swing一起練習我的OOP技能,但我目前被卡住了。我正在嘗試製作一個計算器,類似於你在手機上看到的計算器。我不知道我應該如何實現每個按鈕的功能。現在我只是試圖在按下按鈕時在屏幕上顯示數字(JLabel對象)。我還附上了迄今爲止我所用的GUI的圖片。我在哪裏實現我的功能?

我應該在單獨的.java文件中實現這些功能嗎?還是應該在Calculator.java或Keyboard.java文件中實現它們?

它們是如何實現的,因爲我不知道如何在Calculator.java文件中的JLabel對象上顯示,如果我的按鈕對象在Keyboard.java文件中的話。

Calculator.java

package calculator; 

import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 

public class Calculator extends JFrame 
{ 
    public static void main(String[] args) 
    { 
     new Calculator(); 
    } 

    public Calculator() //Calculator constructor?? 
    { 
     setLayout(new GridLayout(2,1)); 
     this.setSize(400,600); 
     this.setLocationRelativeTo(null); //center the window 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JLabel display = new JLabel(); 
     this.add(display); 

     Keyboard kb = new Keyboard(); 
     this.add(kb); 

     this.setVisible(true); 
    } 

} 

Keyboard.java

package calculator; 
import javax.swing.JPanel; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 

public class Keyboard extends JPanel implements ActionListener 
{ 
    public Keyboard() 
    { 
     setLayout(new GridLayout(4,4)); 

     JButton one = new JButton("1"); 
     this.add(one); 
     JButton two = new JButton("2"); 
     this.add(two); 
     JButton three = new JButton("3"); 
     this.add(three); 
     JButton plus = new JButton("+"); 
     this.add(plus); 
     JButton four = new JButton("4"); 
     this.add(four); 
     JButton five = new JButton("5"); 
     this.add(five); 
     JButton six = new JButton("6"); 
     this.add(six); 
     JButton minus = new JButton("-"); 
     this.add(minus); 
     JButton seven = new JButton("7"); 
     this.add(seven); 
     JButton eight = new JButton("8"); 
     this.add(eight); 
     JButton nine = new JButton("9"); 
     this.add(nine); 
     JButton times = new JButton("x"); 
     this.add(times); 
     JButton zero = new JButton("0"); 
     this.add(zero); 
     JButton clear = new JButton("clear"); 
     this.add(clear); 
     JButton equals = new JButton("="); 
     this.add(equals); 
     JButton divide = new JButton("/"); 
     this.add(divide); 
    } 

    public void actionPerformed(ActionEvent e) { 

    } 
} 

enter image description here

+0

按下按鈕是做什麼的?如果你只是構造一個表達式以便稍後評估並將其顯示給用戶,那麼處理'[0-9x/- +]'按鈕將是相同的,將該按鈕的符號追加到表達式並更新顯示的字符串。其餘按鈕明顯用於不同的目的,並需要自定義動作監聽器。 – dramzy

+0

另請參閱此[計算器示例](http://stackoverflow.com/a/7441804/418556)。它使用'ScriptEngine'來評估文本字段中的表達式。 –

回答

1

使用MVC模式,並將邏輯代碼放入actionPerformed(...)方法(或任何此類問題的邏輯代碼)到控制器類中的相應方法中。


MVC圖案由三個班,ModelViewControl,即共同努力,使一個GUI。

MVC模式的簡要總結,從最初this answer拍攝,但略作修改:

  1. 你的用戶 - 您使用視圖交互。控制器採取你的行動並解釋它們。如果你點擊一個按鈕,控制者的工作就是根據這個動作找出它的意義以及如何操作模型。
  2. 控制器要求模型改變其狀態。當控制器從視圖中接收到一個動作時,它可能需要告訴視圖作爲結果進行更改。例如,控制器可以啓用或禁用界面中的某些按鈕或菜單項。
  3. 該模型在狀態發生變化時通知視圖。當模型發生某些變化時,根據您採取的某些操作(如單擊按鈕)或某些其他內部變化(如播放列表中的下一首歌曲已開始),模型會通知視圖其狀態已更改。
  4. 控制器也可能要求視圖改變。
  5. 該視圖詢問模型的狀態。視圖獲取它直接從模型顯示的狀態。例如,當模型通知視圖新歌已經開始播放時,視圖從模型請求歌曲名稱並顯示它。該視圖也可能會要求模型的狀態,因爲控制器請求視圖中的某些更改。

MVC圖案的更詳細和深入的解釋可以在上面的鏈接,on Oracle's website中找到,並且通過簡單的谷歌搜索。


我選擇使用the observer pattern進行模型 - 視圖交互。

使用MVC結構的程序的例子:

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Observable; 
import java.util.Observer; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.WindowConstants; 

class Test { 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       final Model model = new Model(); 
       final Control control = new Control(model); 
       final View view = new View(model, control); 

       final JFrame frame = new JFrame("MVC Example"); 
       frame.getContentPane().add(view); 
       frame.pack(); 
       frame.setLocationByPlatform(true); 
       frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
       frame.setVisible(true); 
      } 

     }); 
    } 

    static class Model extends Observable { 

     private int number; 

     void setNumber(int newValue) { 
      number = newValue; 
      setChanged(); 
      notifyObservers(number); 
     } 

     int getNumber() { 
      return number; 
     } 

    } 

    static class View extends JPanel { 

     View(Model model, Control control) { 
      final JLabel label = new JLabel(Integer.toString(model.getNumber())); 
      final JButton button = new JButton("Click me!"); 
      button.addActionListener(new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        control.buttonPressed(); 
       } 

      }); 

      setLayout(new BorderLayout()); 
      add(label); 
      add(button, BorderLayout.SOUTH); 

      model.addObserver(new Observer() { 

       @Override 
       public void update(Observable o, Object arg) { 
        label.setText(Integer.toString((int) arg)); 
       } 

      }); 
     } 

    } 

    static class Control { 

     private Model model; 

     Control(Model model) { 
      this.model = model; 
     } 

     void buttonPressed() { 
      model.setNumber(model.getNumber() + 1); 
     } 

    } 

} 

注意您的代碼:

  • arrays看看和for loop,以幫助您簡化您的按鈕的聲明。
  • 代替JFrame的尺寸,請在JFrame上添加JFrame,以便JFrame符合孩子的尺寸。請在JFrame之後致電pack()
  • 不要擴展JFrame,而應創建一個實例並進行必要的修改。
  • EDT(Event Dispatch Thread)上運行您的代碼以避免在GUI中「凍結」。欲瞭解更多信息,請看看The Java™ Tutorials - Concurrency in Swing
  • 下次發佈評論發佈,爲更好地爲您提供幫助,請發送MCVE
1

你應該寫的actionPerformed()在 'Keyboard.java' 文件本身

方法

Keyboard.java

one.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      jButton1ActionPerformed(evt); 
     } 
    }); 
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) 
    { 
     displaystring = displaystring + "1"; 
     display.setText (displaystring);` 
    } 

你必須通過鍵盤類的構造函數通過顯示器的參考,並將其分配給一些類的實例變量,這樣就可以過更新Keyboard類的顯示標籤!

+0

爲什麼把行爲監聽器的邏輯代碼放在一個單獨的方法中? – MasterBlaster

相關問題