2015-03-19 5 views
0
package javaapplication2; 

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 



public class Calc extends JFrame implements ActionListener { 

private JButton b1, b2, b3, b4,b5,b6,b7,b8,b9,b0; 
JButton[] label = {b1, b2, b3, b4, b5,b6,b7,b8,b9,b0}; 
String[] numKeys = {"1","2","3","4","5","6","7","8","9","0"}; 
JPanel numPad; 
JPanel opPad; 
JTextField displayPanel; 

public Calc() { 
super("Calculator"); 
setSize(250,200); 
    setDefaultCloseOperation(EXIT_ON_CLOSE);  
    setVisible(true); 

    displayPanel = new JTextField(20); 
    numPad = new JPanel(); 
    numPad.setLayout(new GridLayout(4, 3)); 
    opPad = new JPanel(); 
    opPad.setLayout(new GridLayout(4, 1)); 
    getContentPane().setLayout(new BorderLayout()); 
    getContentPane().add(numPad,BorderLayout.LINE_START); 
    getContentPane().add(displayPanel, BorderLayout.PAGE_START); 

    for (int i = 0; i <label.length;i++) { 
     label[i] = new JButton(numKeys[i]); 
     numPad.add(label[i]); 
     label[i].addActionListener(this); 


    } 


    b2.addActionListener(this); 

} 
public void actionPerformed(ActionEvent a) { 
    if (a.getSource() == b1)      
      displayPanel.setText("1"); 
} 


    public static void main(String args[]) { 
Calc c = new Calc(); 






} 
} 

Привет, Я пытался добавить пронумерованные JButtons и добавить слушателя действий в рамках одного цикла в моей попытке сделать калькулятор, кнопки создаются и добавляются к панели, однако, нажав «1» не имеет никакого эффекта, когда он должен отображать 1 на текстовом полеДобавление ActionListener с петлей

ответ

1
private JButton b1, b2, b3, b4,b5,b6,b7,b8,b9,b0; 
JButton[] label = {b1, b2, b3, b4, b5,b6,b7,b8,b9,b0}; 

b1-b0 являются null по умолчанию. В этом коде:

for (int i = 0; i <label.length;i++) { 
    label[i] = new JButton(numKeys[i]); 
    numPad.add(label[i]); 
    label[i].addActionListener(this); 
} 

назначать кнопки к label массива, но не к переменным b1-b0. Поэтому вы на самом деле проверки == null здесь

if (a.getSource() == b1) 

Решение: удалить эти b1-b0 переменные (вы получили массив в любом случае) и проверить, как это:

if (a.getSource() == label[0]) 
+0

Не используйте ActionListener с вложенными операторами if, чтобы определить, какая кнопка была нажата. Вместо этого напишите общее действие. Я привел пример. – camickr

0

Сначала вы инициализацию кнопки обнулить и заполнить массив меток теми нулевыми ссылками.

Во время цикла вы создаете новые объекты и заменяете их в массиве меток. Исходные ссылки все еще указывают на null.

В случае действия вы сравниваете исходный = новые кнопки со старыми ссылками, которые указывают на нуль. Это ошибка.

Просто инициализируйте кнопки, прежде чем добавлять их в массив меток, и не создавайте новые кнопки в своем цикле. Исправлена!

0

Я бы рекомендовал использовать actioncommand в течение цикла, а затем проверять то же самое в действии слушателя, label[i].setActionCommand(numKeys[i]);, а затем в действие слушающего что-то вроде этого if (a.getActionCommand().equals("1"))

Проверьте этот SO вопрос, Java Button Action Command, объясняет использование ActionCommand

Надеюсь, что это поможет !!!

0

Я не думаю, что это хорошая идея, чтобы сохранить кнопки в массиве , но если вы все еще хотите, то лучше использовать Arrais.asList()

import java.awt.*; 
    import java.awt.event.*; 
    import java.util.Arrays; 
    import java.util.Collection; 
    import javax.swing.*; 

    class Calc extends JFrame { 
     Collection<JButton> buttons = Arrays.asList(
     new JButton("1"), 
     new JButton("2"), 
     new JButton("3"), 
     new JButton("4"), 
     new JButton("5"), 
     new JButton("6"), 
     new JButton("7"), 
     new JButton("8"), 
     new JButton("9"), 
     new JButton("0")); 
     JPanel numPad; 
     JPanel opPad; 
     JTextField displayPanel; 

     public Calc() { 
     super("Calculator"); 
     setSize(250, 200); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setVisible(true);  

     displayPanel = new JTextField(20); 
     numPad = new JPanel(); 
     numPad.setLayout(new GridLayout(4, 3)); 
     opPad = new JPanel(); 
     opPad.setLayout(new GridLayout(4, 1)); 
     getContentPane().setLayout(new BorderLayout()); 
     getContentPane().add(numPad, BorderLayout.LINE_START); 
     getContentPane().add(displayPanel, BorderLayout.PAGE_START);  

     for (final JButton button : buttons) { 
      button.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       displayPanel.setText(displayPanel.getText() + button.getText()); 
      } 
      }); 
      numPad.add(button); 
     } 
     } 

    public static void main(String args[]) { 
    Calc c = new Calc(); 
    } 
} 
+0

* «Я не думаю, что это хорошая идея хранить кнопки в массиве» * - Почему? Если у вас есть только фиксированное количество элементов, массивы, как правило, более простые (IMHO) – MadProgrammer

+0

Да, конечно, но я не уверен, что действительно нужен доступ по индексу, так как достаточно прослушивать коллекцию для регистрации слушателей. Извините за мой плохой английский. –

+0

И чтобы сохранить фиксированное количество элементов в коллекции, я обычно использую _Collections.unmodifiableList_, потому что _UnmodifiableList_ ограничивает не только добавление, но и замену элементов Collection. –

0

Написать родовое Action, чтобы вы не должны использовать вложенные если заявления:

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.border.*; 

public class CalculatorPanel extends JPanel 
{ 
    private JTextField display; 

    public CalculatorPanel() 
    { 
     Action numberAction = new AbstractAction() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       display.replaceSelection(e.getActionCommand()); 
      } 
     }; 

     setLayout(new BorderLayout()); 

     display = new JTextField(); 
     display.setEditable(false); 
     display.setHorizontalAlignment(JTextField.RIGHT); 
     add(display, BorderLayout.NORTH); 

     JPanel buttonPanel = new JPanel(); 
     buttonPanel.setLayout(new GridLayout(0, 5)); 
     add(buttonPanel, BorderLayout.CENTER); 

     for (int i = 0; i < 10; i++) 
     { 
      String text = String.valueOf(i); 
      JButton button = new JButton(text); 
      button.addActionListener(numberAction); 
      button.setBorder(new LineBorder(Color.BLACK)); 
      button.setPreferredSize(new Dimension(50, 50)); 
      buttonPanel.add(button); 

      InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 
      inputMap.put(KeyStroke.getKeyStroke(text), text); 
      inputMap.put(KeyStroke.getKeyStroke("NUMPAD" + text), text); 
      button.getActionMap().put(text, numberAction); 
     } 
    } 

    private static void createAndShowUI() 
    { 
//  UIManager.put("Button.margin", new Insets(10, 10, 10, 10)); 

     JFrame frame = new JFrame("Calculator Panel"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new CalculatorPanel()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

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

Этот пример также использует Key Bindings, так что вы можете нажать кнопку «1» на клавиатуре или нажмите на кнопку «1».

Смежные вопросы