簡體   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