简体   繁体   中英

javafx Text Fields that update each other

I'm writing a basic GUI app that involves a pane of TextFields, representing 5 ways to enter a byte into the buffer of the program. The idea is that when you edit one of the text fields, the other 4 will update with the translated value of the one you're editing. For example, changing the Hex field to "FF" will make the decimal field change to "255" immediately, and so on.

The issue is that i cant figure out how to avoid an infinite loop of updating when one is changed: the hex field is changed, which modifies the decimal field, which then tries to update the hex field again, and so on, creating a Stack Overflow error.

Here is the code defining the Fields and their listeners:

    TextField Inputchar = new TextField();
    Inputchar.setPromptText("Enter " + Program.BYTES_OF_BUFFER + " character(s)...");
    Inputchar.setMinWidth(250);

    TextField Inputhex = new TextField();
    Inputhex.setPromptText("Enter a value between 0 and " + Program.BUFFER_SIZE.toString(16) + "...");

    TextField Inputdec = new TextField();
    Inputdec.setPromptText("Enter a value between 0 and " + Program.BUFFER_SIZE.toString(10) + "...");

    TextField Inputoct = new TextField();
    Inputoct.setPromptText("Enter a value between 0 and " + Program.BUFFER_SIZE.toString(8) + "...");

    TextField Inputbin = new TextField();
    Inputbin.setPromptText("Enter a value between 0 and " + Program.BUFFER_SIZE.toString(2) + "...");

    Inputchar.textProperty().addListener(c -> {
        char[] cs = Inputchar.getText().toCharArray();
        byte[] b = new byte[cs.length];
        for (int i = 0; i < cs.length; i++) {
            b[i] = (byte) cs[i];
        }
        BigInteger B = new BigInteger(b);
        Inputhex.setText(B.toString(16));
        Inputdec.setText(B.toString(10));
        Inputoct.setText(B.toString(8));
        Inputbin.setText(B.toString(2));
    });

    Inputhex.textProperty().addListener(c -> {
        BigInteger B = BigInteger.valueOf(Integer.parseInt(Inputhex.getText(), 16));
        Inputchar.setText(BF_Program.bytestochars(B.toByteArray()));
        Inputdec.setText(B.toString(10));
        Inputoct.setText(B.toString(8));
        Inputbin.setText(B.toString(2));
    });

    Inputdec.textProperty().addListener(c -> {
        BigInteger B = BigInteger.valueOf(Integer.parseInt(Inputdec.getText(), 10));
        Inputchar.setText(BF_Program.bytestochars(B.toByteArray()));
        Inputhex.setText(B.toString(16));
        Inputoct.setText(B.toString(8));
        Inputbin.setText(B.toString(2));
    });

    Inputoct.textProperty().addListener(c -> {
        BigInteger B = BigInteger.valueOf(Integer.parseInt(Inputoct.getText(), 8));
        Inputchar.setText(BF_Program.bytestochars(B.toByteArray()));
        Inputhex.setText(B.toString(16));
        Inputdec.setText(B.toString(10));
        Inputbin.setText(B.toString(2));
    });

    Inputbin.textProperty().addListener(c -> {
        BigInteger B = BigInteger.valueOf(Integer.parseInt(Inputbin.getText(), 2));
        Inputchar.setText(BF_Program.bytestochars(B.toByteArray()));
        Inputhex.setText(B.toString(16));
        Inputdec.setText(B.toString(10));
        Inputoct.setText(B.toString(8));
    });

How can i change this so that editing one field will update the other fields once and not loop? Thanks.

Turns out the way i had my lamba expression was implementing the wrong class: InvalidationListener, when it should have been using ChangeListener:

    Inputchar.textProperty().addListener((observable, oldValue, newValue) -> {
        char[] cs = Inputchar.getText().toCharArray();
        byte[] b = new byte[cs.length];
        for (int i = 0; i < cs.length; i++) {
            b[i] = (byte) cs[i];
        }
        BigInteger B = new BigInteger(b);
        Inputhex.setText(B.toString(16));
        Inputdec.setText(B.toString(10));
        Inputoct.setText(B.toString(8));
        Inputbin.setText(B.toString(2));
    });

    Inputhex.textProperty().addListener((observable, oldValue, newValue) -> {
        BigInteger B = BigInteger.valueOf(Integer.parseInt(Inputhex.getText(), 16));
        Inputchar.setText(BF_Program.bytestochars(B.toByteArray()));
        Inputdec.setText(B.toString(10));
        Inputoct.setText(B.toString(8));
        Inputbin.setText(B.toString(2));
    });

    Inputdec.textProperty().addListener((observable, oldValue, newValue) -> {
        BigInteger B = BigInteger.valueOf(Integer.parseInt(Inputdec.getText(), 10));
        Inputchar.setText(BF_Program.bytestochars(B.toByteArray()));
        Inputhex.setText(B.toString(16));
        Inputoct.setText(B.toString(8));
        Inputbin.setText(B.toString(2));
    });

    Inputoct.textProperty().addListener((observable, oldValue, newValue) -> {
        BigInteger B = BigInteger.valueOf(Integer.parseInt(Inputoct.getText(), 8));
        Inputchar.setText(BF_Program.bytestochars(B.toByteArray()));
        Inputhex.setText(B.toString(16));
        Inputdec.setText(B.toString(10));
        Inputbin.setText(B.toString(2));
    });

    Inputbin.textProperty().addListener((observable, oldValue, newValue) -> {
        BigInteger B = BigInteger.valueOf(Integer.parseInt(Inputbin.getText(), 2));
        Inputchar.setText(BF_Program.bytestochars(B.toByteArray()));
        Inputhex.setText(B.toString(16));
        Inputdec.setText(B.toString(10));
        Inputoct.setText(B.toString(8));
    });

This one actually works. Keeping up for future reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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