如何从jPanel删除和添加组件?爪哇

时间:2020-10-07 03:46:31

标签: java swing

好吧,我只是一个初学者,所以在弄清楚这一点上我遇到了很多困难。基本上,我试图创建一个一位数字的计算器(这意味着计算仅使用一位数字进行)。我已经创建了按钮,为它们分配了动作监听器,它们的类以及所有这些东西。然后,我尝试将这些数字显示在标签上。现在我遇到的问题是,我有一个按钮,单击该按钮将使用一个类。从该类中,我想做的是,删除面板上的所有按钮,然后添加新按钮。但是,当我尝试删除按钮时,发生了一些奇怪的事情。如果我单击该按钮,则按钮不会停留在其中,而是停留在该按钮上,但我无法与它们进行交互。有什么解决的办法吗?我想将它们从面板中完全删除。然后我想在它们的位置添加新按钮。

这是主类的代码

package onecalculator;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
public class code {
static JLabel see = new JLabel("Int a");
static JLabel no = new JLabel("Int b");
static JLabel lol = new JLabel("Answer");
static JPanel area = new JPanel();
static JButton secn = new JButton("next");
static JButton one = new JButton("1");      
static JButton two = new JButton("2");
static JButton three = new JButton("3");
static JButton four = new JButton("4");
static JButton five = new JButton("5");
static JButton six = new JButton("6");
static JButton seven = new JButton("7");
static JButton eight = new JButton("8");
static JButton nine = new JButton("9");

static JButton bone = new JButton("1");     
static JButton btwo = new JButton("2");
static JButton bthree = new JButton("3");
static JButton bfour = new JButton("4");
static JButton bfive = new JButton("5");
static JButton bsix = new JButton("6");
static JButton bseven = new JButton("7");
static JButton beight = new JButton("8");
static JButton bnine = new JButton("9");
static JButton div = new JButton("div");
static JButton mul = new JButton("mul");
static JButton add = new JButton("add");
public int a;
public int b;
    public static void main(String[] args) {
        JFrame screen = new JFrame("One Digit Calculator");
        screen.setSize(400,600);
        screen.setResizable(false);
        screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        screen.add(area);
        area.add(see);
        area.add(no);
        area.add(lol);
        area.add(secn);
        area.add(one);
        area.add(two);
        area.add(three);
        area.add(add);
        area.add(four);
        area.add(five);
        area.add(six);
        area.add(mul);
        area.add(seven);
        area.add(eight);
        area.add(nine);
        area.add(div);
        
        secn.addActionListener(new secn());
        two.addActionListener(new Twoc());
        three.addActionListener(new Threec());
        four.addActionListener(new Fourc());
        five.addActionListener(new Fivec());
        six.addActionListener(new Sixc());
        seven.addActionListener(new Sevenc());
        eight.addActionListener(new Eightc());
        nine.addActionListener(new Ninec());
        one.addActionListener(new Onec());
        area.setLayout(new GridLayout(4,4));
        screen.setVisible(true);
        
        
        }

}

然后这是删除面板中按钮的类的代码


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class secn implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent arg0) {
        
        code.area.remove(code.one);
        code.area.remove(code.two);
        code.area.remove(code.three);
        code.area.remove(code.four);
        code.area.remove(code.five);
        code.area.remove(code.six);
        code.area.remove(code.seven);
        code.area.remove(code.eight);
        code.area.remove(code.nine);
        
        code.area.add(code.bone);
        code.area.add(code.btwo);
        code.area.add(code.bthree);
        code.area.add(code.bfour);
        code.area.add(code.bfive);
        code.area.add(code.bsix);
        code.area.add(code.bseven);
        code.area.add(code.beight);
        code.area.add(code.bnine);
    }

}

请帮助。

3 个答案:

答案 0 :(得分:2)

您要做的是在容器(即“ JPanel区域”)上调用 repaint() revalidate()可以容纳您的按钮。如果您想确切地知道重绘和重新验证的操作,请查看this答案。

在代码下方的 actionPerformed 方法中添加新按钮的位置,添加以下内容以更新容器:

         col1  col2  col3
    0     1     2      1
    1     2     4      2
    2     3     6      3
    3     4     4      4     <-----
    4     5    nan    nan
    5     6    12     nan

请记住,这将导致将新元素添加到未删除元素的末尾,并按照添加顺序进行添加。您可以使用GridBagConstraints选择放置按钮的位置。


但是我要说,仅为了输入第二个值而删除旧按钮只是为了创建新按钮似乎是一个坏主意。此外,为每个按钮使用单独的ActionListeners似乎也很浪费。

我建议使用一个全局变量(例如布尔值)来指示您使用的是第一个值还是第二个值。

code.area.repaint();
code.area.revalidate();

当按下“下一个按钮”时,您可以将此变量更改为“ false”,而不删除任何按钮。在您的ActionListener中,您只需查看此变量即可知道是将按下的数字分配给值a还是值b。

对于您的ActionListener中的数字按钮,我建议像这样对所有按钮重用一个:

static boolean isFirst = true;

您将按以下方式分配ActionListener:

class MyListener implements ActionListener{
    int value;

    //when creating new instances of MyListener, you give each listener 
    //an int equivalent to the buttons value
    MyListener(int value){
        this.value = value;
    }

    @Override
    public void actionPerformed(ActionEvent arg0){
        if(isFirst){  //first value
            a = value; //add value to your first number in any way you like
        } else {      //second value
            b = value; //add value to your second number in any way you like
        }
    }
}

我希望这会有所帮助并且可以理解。可能有更好的方法,但这是我的建议。我愿意就此提供反馈。

答案 1 :(得分:0)

最简单的解决方案是创建一个新的JPanel而不是删除旧按钮。

JPanel newArea= new JPanel();

//Add new buttons

code.area = newArea;

但是我认为您应该考虑重新设计代码。首先,您不应在代码类中使用静态变量。而是将它们设为私有并禁止您的代码类。

public class code{
    private JLabel see = new JLabel("Int a");
    private JLabel no = new JLabel("Int b");
    //...

    public static void main(String[] args){
    code mainClass = new code();
}

这允许您使用代码类的多个实例,而不仅仅是一个。其次,您不应该为每个Actionlistener开设新的课程。特别是因为我认为他们都在做相同的事情。我也不认为你甚至不需要重新制作所有的按钮。如果您只想保存2个值,则可以检查是否已设置第一个值:

class ButtonListener implements ActionListener{
    int buttonValue;
    code callingClass;

    //Save the buttonn number and the calling class
    MyListener(int buttonValue, code callingClass){
        this.buttonValue = buttonValue;
        this.callingClass = callingClass;
    }

    //If a is null set a, otherwise set b
    public void actionPerformed(ActionEvent arg0){
        if(callingClass.a == null){  
            callingClass.a = buttonValue; 
        } else {      
            callingClass.b = buttonValue; 
        }
    }
}

然后,在代码类中,应在构造函数中用空值初始化a和b,以及在主对象中先前初始化的所有内容,然后将ButtonListener类用作新的动作侦听器。

public code(){
    a = null;
    b = null;
    //Initialize all the other stuff
    secn.addActionListener(new ButtonListener(2, this));
}

答案 2 :(得分:0)

每当您向可见的Swing组件中添加或删除元素时,都应按照建议使用revalidate()(在子代已更改后重新计算其布局)和repaint()(重新绘制组件本身)。由Custos' answer

但是,这里有一个问题,为什么您需要这样做。 您有两组视觉上相同的数字按钮,只是它们处理点击的方式不同。无需替换按钮-只需保留一些额外的状态(下面的代码中的hasAhasB变量)即可解决这些差异。

自从引入lambda(内联,匿名函数)以来,为Java UI编写处理程序代码变得更具可读性,也不再那么冗长:请注意下面的代码如何使用1行处理程序将接口与实际逻辑绑定,以及如何例如,在下面的代码中添加一个新的运算符将很容易。

还要注意,您不需要将类的所有图形元素都公开为字段-在这里,数字和运算符仅用于调用digitPressedoperatorPressed,并导致较小的字段集在Calc类中。

此外,通过将Calc设为JPanel的子类,并避免任何和所有static字段,我可以轻松创建多个相互独立且并行运行的计算器

package one;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;

public class Calc extends JPanel {
    private JLabel labelA = new JLabel();
    private JLabel labelB = new JLabel();
    private JLabel labelAnswer = new JLabel();
    
    private int a;
    private int b;
    private boolean hasA = false;
    private boolean hasB = false;

    
    public Calc() {
        setLayout(new GridLayout(0, 4));

        add(labelA);
        add(labelB);
        add(labelAnswer);
        reset(); // rewrites labels, resets state

        JButton reset = new JButton("reset");
        add(reset);
        reset.addActionListener((e) -> reset());

        for (int i=1; i<10; i++) {
            JButton b = new JButton("" + i);
            add(b);
            final int index = i; // for use in lambda
            b.addActionListener((e) -> digitPressed(index));
        }

        for (String op : new String[] {"add", "mul", "div"}) {
            JButton b = new JButton(op);
            add(b);
            final String index = op; // for use in lambda
            b.addActionListener((e) -> operatorPressed(index));
        }
    }

    private void reset() {
        labelA.setText("value A: ?");
        labelB.setText("value B: ?");
        labelAnswer.setText("no operator");
        hasA = hasB = false;
    }

    private void digitPressed(int i) {
        if ( ! hasA) {
            hasA = true; 
            a = i; 
            labelA.setText("value A:" + a);
        } else if ( ! hasB) {
            hasB = true; 
            b = i; 
            labelB.setText("value B:" + b);
        }
    }

    private void operatorPressed(String operator) {
        String answer = "???";
        if (operator.equals("mul")) {
            answer = "= " + (a * b);
        } else if (operator.equals("div")) {
            answer = "= " + (a / b);
        } else if (operator.equals("add")) {
            answer = "= " + (a + b);
        }
        labelAnswer.setText(answer);
    }

    public static void main(String[] args) {        
        JFrame screen = new JFrame("One Digit Calculator");
        screen.setSize(400,600);
        screen.setResizable(false);
        screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        screen.add(new Calc());
        screen.setVisible(true);                                
    }
}
相关问题