2017-12-16 3 views
0

Ich bin ein Anfänger in Java Swing. Ich habe versucht, einen einfachen Rechner zu erstellen, der nur + und - hat. Ich benutzte JButtons für "+" und "-" und fügte actionListener hinzu, um auf jede Schaltfläche zu reagieren. Allerdings kann ich nicht wirklich verstehen, warum die e.getSource() nicht funktioniert. Ist es ein dynamisches Versandproblem? Ich würde wirklich eine Hilfe schätzen !!JAVA Swing JButton ActionPerformed Methodenimplementierung .getSource-Methode

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

import javax.swing.*; 

class MenuExample implements ActionListener { 
    // JMenu menu1, menu2, menu3; 
    // JMenuItem i1, i2, i3, i4, i5; 
    JTextArea t1, t2; 
    JTextField t3; 
    JButton b1, b2; 

    MenuExample() { 
     JFrame f = new JFrame("Menu and MenuItem EX"); 
     final JButton b1 = new JButton("+"); 
     final JButton b2 = new JButton("-"); 
     t3 = new JTextField();t3.setBounds(50, 350, 200, 30); t3.setEditable(false); 
     t1 = new JTextArea(); t1.setBounds(50,100,200,30); 
     t2 = new JTextArea(); t2.setBounds(50,250,200,30); 
     b1.addActionListener(this); 
     b2.addActionListener(this); 
     b1.setBounds(50, 450, 30, 30); b2.setBounds(100, 450, 30, 30); 
     f.add(b1); f.add(b2);f.add(t1); f.add(t2); f.add(t3); 

     f.setSize(800, 800); 
     f.setLayout(null); 
     f.setVisible(true); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     JButton button; 
     int answer=0; 
     String s1 = t1.getText(); 
     String s2 = t2.getText(); 
     int a = Integer.parseInt(s1); 
     int b = Integer.parseInt(s2); 

     Object source = e.getSource(); 
     if (source instanceof JButton) { 
      button = (JButton) source; 
      System.out.println("called here at least?"); 
      System.out.println(button.getClass()); 
      if (button == b1) { 
       answer = a + b; 
      } 
      else if (button == b2) { 
       answer = a - b; 
      } 
     } 
     String result = String.valueOf(answer); 
     t3.setText(result); 
    } 
} 

public class JMenuPractice { 
    public static void main (String[] args) { 
     new MenuExample(); 
    } 
} 

Antwort

3

Sie Shadowing Ihre b1 und b2 JButton Felder, die von ihnen im Konstruktor erneut erklärt:

class MenuExample implements ActionListener { 
    JTextArea t1, t2; 
    JTextField t3; 
    JButton b1, b2; // these stay null!!! 

    MenuExample() { 
     JFrame f = new JFrame("Menu and MenuItem EX"); 

     // Don't re-declare the variables here! 
     final JButton b1 = new JButton("+"); 
     final JButton b2 = new JButton("-"); 

Dies läßt die Felder null und Ihr Gleichheitstest im Hörer wird nicht funktionieren. Die Lösung: Schatten nicht! Verwenden Sie stattdessen die Felder, die Sie bereits haben:

class MenuExample implements ActionListener { 
    JTextArea t1, t2; 
    JTextField t3; 
    JButton b1, b2; // these are no longer null 

    MenuExample() { 
     JFrame f = new JFrame("Menu and MenuItem EX"); 

     // final JButton b1 = new JButton("+"); 
     // final JButton b2 = new JButton("-"); 
     b1 = new JButton("+"); 
     b2 = new JButton("-"); 

Beachten Sie den großen Unterschied?

Weitere Themen:

  • nicht null Layouts und setBounds anwenden. Während Null-Layouts und setBounds() Swing-Neulinge wie die einfachste und beste Möglichkeit erscheinen, komplexe GUI's zu erstellen, erzeugen Sie mit der Swing GUI'S die ernsteren Schwierigkeiten, denen Sie begegnen werden, wenn Sie sie benutzen. Sie werden die Größe Ihrer Komponenten nicht ändern, wenn die GUI die Größe ändert, sie sind eine royale Hexe, die verbessert oder beibehalten wird, sie scheitern komplett, wenn sie in Scrollpanels platziert werden. Sie sehen auf allen Plattformen oder Bildschirmauflösungen, die sich vom Original unterscheiden, grässlich aus .
  • Verwenden Sie anonyme innere Klassen für Ihre Listener. Dann werden Sie nicht einmal .getSource()

Durch die Nutzung von null Layouts und setBounds verwenden müssen, ist das, was Ihre GUI aussieht, wenn ich es laufen:

enter image description here

Wenn Sie verwendet Layouts und anonyme Listener könnte der Code wie die folgende GUI aussehen. Beachten Sie, dass Ich mag JSpinners verwenden und nicht JTextFields für die Eingabe, da dies die Eingabe in Zahlen beschränkt:

import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.GridLayout; 
import java.awt.Insets; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class SimpleCalc extends JPanel { 
    private static final int GAP = 4; 
    private JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0, -1000, 1000, 1)); 
    private JSpinner spinner2 = new JSpinner(new SpinnerNumberModel(0, -1000, 1000, 1)); 
    private JTextField resultField = new JTextField(10); 
    private JButton addButton = new JButton("+"); 
    private JButton subtractButton = new JButton("-"); 

    public SimpleCalc() { 
     // add anonymous listeners to each JButton 
     addButton.addActionListener(e -> add()); 
     subtractButton.addActionListener(e -> subtract()); 

     // put both buttons within a JPanel that uses grid layout 
     // 1 row, variable number of columns, gap between components 
     JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, GAP)); 
     buttonPanel.add(addButton); 
     buttonPanel.add(subtractButton); 

     resultField.setFocusable(false); 
     resultField.setEditable(false); 

     setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP)); 
     // use GridBagLayout 
     setLayout(new GridBagLayout()); 
     GridBagConstraints gbc = new GridBagConstraints(); 
     // start at x position is 0, and stay there 
     gbc.gridx = 0; 
     // y position increments each time 
     gbc.gridy = GridBagConstraints.RELATIVE; 
     // stretch components horizontally not vertically 
     gbc.fill = GridBagConstraints.HORIZONTAL; 
     gbc.weightx = 1.0; 
     gbc.weighty = 1.0; 
     // gap between componentns 
     gbc.insets = new Insets(GAP, GAP, GAP, GAP); 

     add(spinner1, gbc); 
     add(spinner2, gbc); 
     add(resultField, gbc); 
     add(buttonPanel, gbc); 
    } 

    public void add() { 
     int value1 = (int) spinner1.getValue(); 
     int value2 = (int) spinner2.getValue(); 
     int result = value1 + value2; 
     resultField.setText(String.valueOf(result)); 
    } 

    public void subtract() { 
     int value1 = (int) spinner1.getValue(); 
     int value2 = (int) spinner2.getValue(); 
     int result = value1 - value2; 
     resultField.setText(String.valueOf(result)); 
    } 

    private static void createAndShowGui() { 
     SimpleCalc mainPanel = new SimpleCalc(); 

     JFrame frame = new JFrame("SimpleCalc"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 

, die als angezeigt:

enter image description here

+0

Vielen Dank für diese hilfreiche Antwort !! Möchten Sie als Alternative zur Verwendung von setBounds und null Layout einfach die Layout-Manager verwenden?wie flowLayout und BorderLayout? – ChatSev

+0

@ChatSev: Ja, Sie könnten BorderLayout und FlowLayout verwenden. Ich neste oft JPanels, die jeweils ihr eigenes Layout verwenden. Im obigen Beispiel werden sowohl GridLayout als auch GridBagLayout verwendet. Lesen Sie das [Layout Manager Tutorial] (http://docs.oracle.com/javase/tutorial/uiswing/layout/index.html) für weitere Informationen. –

0

In der actionPerformed Funktion, die Sie mit den JButtonsb1 und b2 als Class members deklariert und das ist kein Problem, aber Sie sollten feststellen, dass Sie JButton s b1 und b2 in Ihremdeklariert:

final JButton b1 = new JButton("+"); 
final JButton b2 = new JButton("-"); 

Die ActionListener an diesen beiden angebracht ist, nicht die als Class members erklärt diejenigen, die Sie in actionPerformed() verwenden sind.

Also anstatt sie zu beschatten gerade dies zu tun:

b1 = new JButton("+"); 
b2 = new JButton("-");