0

Well I've tried for a pretty long time now to make this work. My code below is very messy and not working atm, it's mostly to show my previous attempts at this..

Soo what do I need help with? I want to create a Stack object that reads(push) character by character from a textfield and then pop and print the words in reverse. Which should be automaticly considering Stack is Last In First Out(LIFO).

 charStack stack = new charStack();
    String entering = textfield.getText();
    for(int i = 0; i < entering.length(); i++){
        //stack.push(i);
        char ch = entering.charAt(i);
        if(Character.isHighSurrogate(ch)){
          i++;
        if (i < entering.length()){
          stack.push(entering.charAt(i));
        }
        }
        stack.push(ch);
        while(entering.length() != 0){
        label.setText(stack.pop().toString());
    }
}

The controller:

public class FXMLDocumentController implements Initializable {

    @FXML
    private Label label;

    @FXML
    private TextField textfield;

    Stack<Character> stack = new Stack<>();

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        //label.textProperty().bind(textfield.textProperty());



    }    

    @FXML
    private void exeCute(ActionEvent event) {
       // String a = textfield.getText();
        //for (char c: a.toCharArray()){
          //  stack.push(c);

        //}

        //while(!stack.empty()){
          //  label.setText(stack.pop().toString());
        //}

        //char[] stack = textfield.getText().toCharArray();
        //char[] reverse = new char[stack.length];
        //int position = stack.length - 1;
        //for(int i = 0; i<stack.length; i++){
          //  reverse[i] = stack[position--];
        //}
        //System.out.print(reverse);
        //String newone = reverse.toString();
        //label.setText(newone); //Works (sort of) but need to do this with stack-object

        //String entering = textfield.getText();
        //for (int i = 0; i < entering.length(); i++){
          //  char ch = entering.charAt(i);
            //if(Character.isHighSurrogate(ch)){
              //  i++;
                //if (i < entering.length()){
                  //  stack.push(entering.charAt(i));
                //}
            //}
            //stack.push(ch);
            //System.out.print(stack.pop());  

        String e = textfield.getText();
            for (int i = 0; i < e.length(); i++){
            char ch = e.charAt(i);
            if(Character.isHighSurrogate(ch)){
                i++;
                if (i < e.length()){
                    stack.push(e.charAt(i));

                }
            }
            stack.push(ch);
            //stack.pop();
            //printStack(stack);


            }
    }
    private void printStack(Stack<Character> s){
        if (s.isEmpty()){
            System.out.println("Stack is empty!");
        }
        else {
            System.out.printf("%s TOP\n" + s);
        }
    }
}
hotzst
  • 7,238
  • 9
  • 41
  • 64
Robin Svensson
  • 39
  • 1
  • 13
  • 2
    You stated what you want but it is not quite clear where you have a problem. Your code example contains many commented lines that do not help readability. Please take a look at how to create a [minimal, complete and verifiable example](http://stackoverflow.com/help/mcve) and update your question accordingly. – hotzst Mar 14 '16 at 18:04
  • All those commented lines etc.. are just different methods I tried using to obtain the results I want. What I want in simple terms: TextField -> Stack(Last in first out, char for char) -> present it in label. – Robin Svensson Mar 14 '16 at 20:18

2 Answers2

0

Consider this loop:

while(entering.length() != 0){
    label.setText(stack.pop().toString());
}

Let's say your original string was "abcd". Before entering this loop, your stack holds 'd', 'c', 'b', 'a'. In the loop, you set text on label to 'd', then to 'c', then to 'b', then to 'a'. At the end, text on label should be "a". What you want is to use this loop to build a string that in the end will be "dcba" ant then set text on the label to this reversed string. Check out the StringBuilder class if you don't know it yet, it's just what you need to do this: https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html.

EDIT: another problem lies in this piece of code:

if (Character.isHighSurrogate(ch)) {
    i++;
    if (i < entering.length()) {
        stack.push(entering.charAt(i));
    }
}
stack.push(ch);

I'm not sure what you want to achieve here, but if you just want to omit high surrogates, you should just write

if (Character.isHighSurrogate(ch)) {
    continue;
}
stack.push(ch);
rtoip
  • 172
  • 1
  • 10
0

I advise against coding your own character-by-character string reversal logic. Due to the unicode system employed for character encoding Java strings, the logic involved in doing so is slightly tricky as it needs to account for unicode surrogate pairs (and your implementation is likely getting it wrong).

Instead, reuse the existing reversal logic in the JDK library: StringBuilder::reverse. A binding can be used to keep the label text in sync with the reversed string.

label.textProperty().bind(
        Bindings.createStringBinding(
                () -> new StringBuilder(textField.getText()).reverse().toString(),
                textField.textProperty()
        )
);

In this sample the reversed string is built completely every time the text of the text field changes. It is not the most efficient way of coding this. However, given the small length of strings expected in a TextField, it is not expected that the efficiency of the solution would lead to any kind of performance issue.

sample image

Sample App

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class InputReversal extends Application {    
    @Override
    public void start(Stage stage) {
        TextField textField = new TextField();
        Label label = new Label();
        label.textProperty().bind(
                Bindings.createStringBinding(
                        () -> new StringBuilder(textField.getText()).reverse().toString(),
                        textField.textProperty()
                )
        );

        VBox layout = new VBox(10, textField, label);
        layout.setPadding(new Insets(10));
        stage.setScene(new Scene(layout));
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Oh, our teacher want us to try different types of advanced programming such as this.. to understand different data structures and the javafx interface in a better way.

A simplistic stack based solution is:

private String reverse(String text) {
    final Stack<Character> stack = new Stack<>();
    for (int i = 0; i < text.length(); i++) {
        stack.push(text.charAt(i));
    }

    StringBuilder builder = new StringBuilder(text.length());
    for (int i = 0; i < text.length(); i++) {
        builder.append(stack.pop());
    }

    return builder.toString();
}

Which is invoked via:

Bindings.createStringBinding(
        () -> reverse(textField.getText()),
        textField.textProperty()
)

However, that doesn't take into account reversals requiring surrogate pair logic. As this appears to be an assignment, I'll leave that part up to you. For which, consulting how the in-built JavaFX library source handle string reversals may help in determining the correct logic, though it may just confuse you.

Community
  • 1
  • 1
jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • Thank you for some great examples. The only issue in this case is that I need to use a Stack-object in between.. like: Text field -> Stack (Last In First Out) with the push and pop thingies.. -> label. But got no Idea about that stack part. Any tip? – Robin Svensson Mar 14 '16 at 20:16
  • I don't advise coding this yourself with a Stack. Why would you *need* to do that? – jewelsea Mar 14 '16 at 20:18
  • Oh, our teacher want us to try different types of advanced programming such as this.. to understand different data structures and the javafx interface in a better way. That's why. Otherwhise I'm aware there is alot more simple ways to deal with this. And I'd really like to understand it better. – Robin Svensson Mar 14 '16 at 20:35
  • Oh, this isn't an assignment or to be more specific, the seminar. It's more about gaining knowledge about these subjects.. and I don't think the literature book we use is that good. Anyway, thanks a million for all your answers and support :) would upvote you if I could.. but newly regged here. Have a nice day. – Robin Svensson Mar 14 '16 at 21:16
  • Just noticed I get an error from the "textField.textProperty()" part, saying that it cannot find the method "textProperty()"? – Robin Svensson Mar 14 '16 at 22:16
  • If you just copy and paste *all* of the code from the sample application it should work fine. Probably you have just copied part of it, and either not defined the textField or assigned the textField the wrong type (such as having an incorrect import statement). – jewelsea Mar 14 '16 at 22:21