繁体   English   中英

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

[英]How do i remove and add components from jPanel? Java

好吧,我只是一个初学者程序员,所以我很难弄清楚这一点。 基本上我正在尝试创建一个一位数的计算器(意味着计算只发生在一位数的数字上)。 我已经创建了按钮,为它们分配了动作监听器和它们的类,以及所有这些东西。 然后我尝试将这些数字显示到标签上。 现在我遇到的问题是,我有一个按钮,单击该按钮时将使用一个类。 从该课程中,我想要做的是从面板中删除所有按钮,并添加新按钮。 但是当我尝试删除按钮时,发生了一些奇怪的事情。 如果我单击该按钮,按钮不会被移除/消失,而是留在那里,但我无法与它们交互。 任何帮助解决这个问题? 我想从面板上完全删除它们。 然后我想在它们的位置添加新按钮。

这是主类的代码

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);
    }

}

请帮忙。

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

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

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

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


但我想说,仅仅为了输入第二个值而删除旧按钮来创建新按钮似乎是一个坏主意。 此外,为每个按钮设置单独的 ActionListener 似乎也有点浪费。

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

static boolean isFirst = true;

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

对于数字按钮的 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
        }
    }
}

您将按如下方式分配 ActionListener:

two.addActionListener(new MyListener(2));
three.addActionListener(new MyListener(3));

我希望这是有帮助和可以理解的。 可能有更好的方法来做到这一点,但这将是我的建议。 我愿意就此提供反馈。

最简单的解决方案是创建一个新的 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; 
        }
    }
}

在您的代码类中,您应该在构造函数中使用 null 初始化 a 和 b,以及您之前在 main 中初始化的所有内容,并使用 ButtonListener 类作为新的动作侦听器。

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

每当您向可见的 Swing 组件添加或删除元素时,都应该使用revalidate() (在子项已更改后重新计算其布局)和repaint() (重新绘制组件本身),如Custos 的回答所建议的那样。

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

自从引入 lambdas(内联、匿名函数)以来,为 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);                                
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM