我正在使用计算器GUI,需要编码退格键和清除按钮的帮助。

下面是代码,names[0][3]是退格字符,names[0][4]是清除整个区域。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class CalcGUI extends JFrame
{
    private Container contents;
    private final JPanel entryPanel, buttonPanel;
    private final JTextArea entryTA;
    private final JButton equalJB;
    private JButton [][] buttons;
    private final String [][] names =
    {{"7", "8", "9", "\u2190", "C"},
     {"4", "5", "6", "+", "-"},
     {"1", "2", "3", "*", "/"},
     {"0", ".", "(", ")", "^"}};

    public CalcGUI()
    {
        super("Calculator");

        contents = getContentPane();
        contents.setLayout(new BorderLayout());

        buttons = new JButton [4][5];
        buttonPanel = new JPanel(new GridLayout(4, 5));

        ButtonHandler bh = new ButtonHandler();

        for (int i = 0; i < names.length; i++)
        {
            for (int j = 0; j < names[i].length; j++)
            {
                buttons[i][j] = new JButton(names[i][j]);
                buttons[i][j].addActionListener(bh);
                buttonPanel.add(buttons[i][j]);
            }
        }

        contents.add(buttonPanel, BorderLayout.CENTER);

        entryTA = new JTextArea(3, 1);
        entryTA.setLineWrap(true);
        entryPanel = new JPanel(new GridLayout(1, 1));
        entryPanel.add(entryTA);
        contents.add(entryPanel, BorderLayout.NORTH);

        equalJB = new JButton("=");
        equalJB.addActionListener(bh);
        contents.add(equalJB, BorderLayout.SOUTH);

        setSize(300, 300);
        setVisible(true);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private class ButtonHandler implements ActionListener
    {
        @Override
        public void actionPerformed (ActionEvent ae)
        {
            for (int i = 0; i < names.length; i++)
            {
                for (int j = 0; j < names[i].length; j++)
                {
                    if (ae.getSource() == buttons[i][j])
                    {
                        if (ae.getSource() != buttons[0][3]
                            && ae.getSource() != buttons[0][4])
                        {
                            entryTA.append(names[i][j]);
                        }
                    }
                    //backspace
                    else if (ae.getSource() == buttons[0][3])
                    {
                        try
                        {
                            Document doc = entryTA.getDocument();
                            if (doc.getLength() > 0)
                            {
                                doc.remove(doc.getLength() - 1, 1);
                            }
                        }
                        catch (BadLocationException ble)
                        {
                            ble.printStackTrace();
                        }
                    }
                    //clear - works, as per @Frostsoft's solution
                    else if (ae.getSource() == buttons[0][4])
                    {
                        entryTA.setText("");
                    }
                }
            }
        }
    }

    public static void main(String [] args)
    {
        CalcGUI calc = new CalcGUI();
    }
}


任何帮助或建议表示赞赏。谢谢!

编辑:我认为问题是,它一直退格直到doc.getLength > 0为假。但是,删除条件会导致引发异常。

Document doc = entryTA.getDocument();
if (doc.getLength() > 0)
{
    System.out.println(doc.getLength());
    doc.remove(doc.getLength() - 1, 1);
    System.out.println("removed");
}


对于输入789,仅按一次退格JButton:

3
removed
2
removed
1
removed

最佳答案

Document#remove似乎只为我工作...

在这种情况下,我更喜欢使用Document#remove的原因是因为它不会创建一堆临时的String,虽然效率更高,但(速度稍快);)



import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class Test1 {

    public static void main(String[] args) {
        new Test1();
    }

    public Test1() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                final JTextArea ta = new JTextArea(10, 60);
                ta.setText("Bananas in pajamas are coming down the stairs,"
                                + "\n"
                                + "Bananas in pajamas are coming down in pairs,");

                JButton back = new JButton("Backspace");
                back.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        try {
                            Document doc = ta.getDocument();
                            if (doc.getLength() > 0) {
                                doc.remove(doc.getLength() - 1, 1);
                            }
                        } catch (BadLocationException ex) {
                            ex.printStackTrace();
                        }
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(ta));
                frame.add(back, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}


考虑提供一个runnable example来演示您的问题。这将减少混乱并改善响应

更新

问题出在你的循环中...

for (int i = 0; i < names.length; i++) {
    for (int j = 0; j < names[i].length; j++) {
        //...
        else if (ae.getSource() == buttons[0][3]) {
            try {
                Document doc = entryTA.getDocument();
                if (doc.getLength() > 0) {
                    doc.remove(doc.getLength() - 1, 1);
                }
            } catch (BadLocationException ble) {
                ble.printStackTrace();
            }
        } //clear - works, as per @Frostsoft's solution
        else if (ae.getSource() == buttons[0][4]) {
            entryTA.setText("");
        }
    }
}


在循环的每次迭代中,当按下退格键时,else if (ae.getSource() == buttons[0][3]) {将为真...,当按下清除键时,对于else if (ae.getSource() == buttons[0][4]) {也是如此。

相反,请从循环中删除清除和退格检查...

public void actionPerformed(ActionEvent ae) {
    for (int i = 0; i < names.length; i++) {
        for (int j = 0; j < names[i].length; j++) {
            if (ae.getSource() == buttons[i][j]) {
                if (ae.getSource() != buttons[0][3]
                                && ae.getSource() != buttons[0][4]) {
                    entryTA.append(names[i][j]);
                }
            }
        }
    }

    if (ae.getSource() == buttons[0][3]) {
        try {
            Document doc = entryTA.getDocument();
            if (doc.getLength() > 0) {
                doc.remove(doc.getLength() - 1, 1);
            }
        } catch (BadLocationException ble) {
            ble.printStackTrace();
        }
    } else if (ae.getSource() == buttons[0][4]) {
        entryTA.setText("");
    }

}

10-05 20:58
查看更多