如何从jPanel中移除和添加组件? Java

huangapple go评论74阅读模式
英文:

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

用于移除按钮并添加新按钮的类的代码:

package onecalculator;

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

如果你有关于这些代码的问题或需要进一步的帮助,请随时提问。

英文:

Ok, i am just a beginner programmer, so i am having a lot of difficulty in figuring this out. Basically i am trying to create a one digit calculator(meaning that calculations only occur with single digits of numbers). I have created the buttons, assigned them action listener and their classes, and all those stuff. And then i try to display those numbers to a label. Now the problem i have is, that, i have a button, which when clicked, will use a class. From that class, what i want to do is, remove all the buttons form the panel, and add new buttons. But when i try to remove the buttons, something weird happens. If i click that button, the buttons instead of getting removed/disappering, they stay there, but i cant interact with them. Any help to fix that? I want to completely remove them from the panel. Then i want to add new buttons in their place.

Here is the code of the main class

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

Then here is the code of the class that removes the buttons in the panel


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

Please help.

答案1

得分: 2

你需要做的是在包含按钮的容器(例如 'JPanel area')上调用 repaint()revalidate()。如果你想了解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;
//在创建MyListener的新实例时,为每个监听器提供与按钮值等效的整数
MyListener(int value){
this.value = value;
}
@Override
public void actionPerformed(ActionEvent arg0){
if(isFirst){  //第一个值
a = value; //以任何你喜欢的方式将值添加到第一个数字
} else {      //第二个值
b = value; //以任何你喜欢的方式将值添加到第二个数字
}
}
}

你可以像这样分配你的ActionListener:

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

我希望这对你有帮助并且易于理解。可能有更好的方法,但这是我的建议。欢迎对此提供反馈。

英文:

What you would want to do is to call repaint() and revalidate() on the container (i.e. 'JPanel area') that holds you buttons. If you want to know exactly what repaint and revalidate do, have a look at this answer.

Below your code where you add your new buttons inside of the actionPerformed method, add the following to update the container:

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

Keep in mind that this will cause your new elements to be added to the end of the elements that weren't deleted and in the order that you add them. You can use GridBagConstraints to select where which button is placed.


But I would say that removing the old buttons just to create new ones only for the purpose of entering the second value seems like a bad idea. Additionally, having separate ActionListeners for each button also seems a little wasteful.

I would propose having a global variable (boolean for example) to indicate whether you're using the first or second value.

static boolean isFirst = true;

When the 'next button' is pressed, you could then change this variable to 'false' and not remove any of the buttons. In your ActionListener you would just look at this variable to know whether to assign the pressed number to value a or value b.

For your ActionListener for the number buttons, I would propose to reuse one for all of them like this:

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

You would assign your ActionListener as follows:

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

I hope this is helpful and understandable. There are probably better ways to do it, but this would be my suggestion. I'm open to feedback on this.

答案2

得分: 0

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

JPanel newArea = new JPanel();

//添加新的按钮

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创建一个新类,特别是因为我认为它们都在做同样的事情。此外,我认为你甚至不需要重新创建所有的按钮。如果你只想保存两个值,你可以检查第一个值是否已经被设置:

class ButtonListener implements ActionListener{
    int buttonValue;
    code callingClass;

    //保存按钮编号和调用类
    ButtonListener(int buttonValue, code callingClass){
        this.buttonValue = buttonValue;
        this.callingClass = callingClass;
    }

    //如果a为空,则设置a,否则设置b
    public void actionPerformed(ActionEvent arg0){
        if(callingClass.a == null){  
            callingClass.a = buttonValue; 
        } else {      
            callingClass.b = buttonValue; 
        }
    }
}

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

public code(){
    a = null;
    b = null;
    //初始化所有其他内容
    secn.addActionListener(new ButtonListener(2, this));
}
英文:

The easiest solution would be to create a new JPanel instead of deleting the old buttons.

JPanel newArea= new JPanel();
//Add new buttons
code.area = newArea;

However i think you should consider redesigning your code. First of all you should not use static variables for your code class. Instead make them private and make a objekt of your code class.

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

This allows you to use multiple instances of your code class instead of just one. Secondly you should not make a new class for every Actionlistener. Ecspecially since i think they are all doing the same. Also i dont think you even need to remake all the buttons. If you just want to save 2 values you can check if the first one has been set already:

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

In your code class you should then initialize a and b with null in your constructor, alongside all the stuff you preivously initialized in your main and use the ButtonListener class as your new actionlistener.

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

答案3

得分: 0

每当您向可见的Swing组件添加或移除元素时,应使用revalidate()(重新计算其布局,因为子元素已更改)和repaint()(重绘组件本身),如Custos的答案中所建议的。

但是,问题是为什么需要这样做。您有两组在外观上相同的数字按钮,它们之间的唯一区别是它们如何处理点击。没有必要替换这些按钮 - 只需通过保留一些额外的状态(我的下面的代码中的hasAhasB变量)来处理这些差异。

自从引入了lambda表达式(内联的匿名函数)之后,编写Java UI的处理代码变得更加可读且不那么冗长:请注意,我下面的代码中具有一行处理程序,将界面与实际逻辑绑定在一起,以及如何轻松地向下面的代码中添加新的运算符。

还要注意,您无需将类的所有图形元素都公开为字段 - 在这里,数字和运算符仅用于调用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 {
    // ... 省略其余代码 ...
}
英文:

Whenever you add or remove elements to a visible Swing component, you should use revalidate() (to recalculate its layout now that children have changed) and repaint() (to repaint the component itself), as suggested by Custos' answer.

However, there is the question of why you need to do this. You have two visually identical sets of digit-buttons, that only differ in how they handle clicks. There is no need to replace the buttons - just handle those differences by keeping a little bit of extra state (hasA and hasB varibales in my code below).

Since the introduction of lambdas (inline, anonymous functions), writing handler code for Java UIs has become much more readable and less verbose: note how my code below has 1-line handlers to bind the interface with actual logic, and how easy it would be to, say, add a new operator to the code below.

Note also that you do not need expose all graphical elements of a class as fields - here, digits and operators are only used to call digitPressed and operatorPressed, and lead to a smaller set of fields in the Calc class.

Also, by making Calc a subclass of JPanel, and avoiding any and all static fields, I can easily create multiple calculators operating side-by-side, independent of each other.

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

huangapple
  • 本文由 发表于 2020年10月7日 11:46:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/64236884.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定