Question

I hope this is not too specific, but I am having trouble understanding the logical flow of my recursive method.

The goal: create a book type gui that will display texts, keeping line breaks, using word wrap and page wrap between 2 JTextAreas. I did not want to do this via scroll panes and want to have a book effect with buttons for flipping pages left/right.

The [pseudo]code: pull and manipulate the text into (monospace fitted) lines, put X lines into a page. Enable left/right buttons if previous/next pages exist. Show x page on left, x+1 page on right. use of (leftPageCursor) to hold current left page.

In order to do this, my idea was to have a recursive display method that 'shows/hides' left/right buttons, puts text onto JTextAreas, and adds button listener code. It works on the first click right, but then gets really messy and (leftPageCursor) goes out of control. I created the following SSCCEE for anyone to see what I mean/logic.

I would really appreciate any help on this, I'm out of ideas. I tried many things the last of which (e.consume) with no luck.

SSCCEE: (please excuse the length - I wanted it to run while keeping it nicely commented)

public class ReadJIntLauncher extends JFrame {
    private static final long serialVersionUID = 1L;
    static JTextArea textAreaLeft, textAreaRight;
    static JButton btnPageLeft, btnPageRight;
    static int leftPageCursor = 0, readMessageId = 1;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ReadJIntLauncher frame = new ReadJIntLauncher();
                    frame.setVisible(true);
                    HashMap<String, String> messages = new HashMap<String, String>();

                    messages.put("read_paragraph_1_0", "PAGE 1: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor");
                    messages.put("read_paragraph_1_1", "incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis nostrud");
                    messages.put("read_paragraph_1_2", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute");
                    messages.put("read_paragraph_1_3", "irure dolor in reprehenderit in voluptate velit esseees");

                    messages.put("read_paragraph_1_4", "PAGE 2: cillum dolore deserunt anim id est laborum anim id est laborum incididunt ut");
                    messages.put("read_paragraph_1_5", "labore incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis");
                    messages.put("read_paragraph_1_6", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute");
                    messages.put("read_paragraph_1_7", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");

                    messages.put("read_paragraph_1_8", "PAGE 3: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor");
                    messages.put("read_paragraph_1_9", "incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis nostrud");
                    messages.put("read_paragraph_1_10", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute");
                    messages.put("read_paragraph_1_11", "irure dolor in reprehenderit in voluptate velit esseees");

                    messages.put("read_paragraph_1_12", "PAGE 4: cillum dolore deserunt anim id est laborum anim id est laborum incididunt ut");
                    messages.put("read_paragraph_1_13", "labore incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis");
                    messages.put("read_paragraph_1_14", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute");
                    messages.put("read_paragraph_1_15", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");

                    messages.put("read_paragraph_1_16", "PAGE 5: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor");
                    messages.put("read_paragraph_1_17", "incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis nostrud");
                    messages.put("read_paragraph_1_18", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");

                    final HashMap<Integer, String> readLines = new HashMap<Integer, String>();
                    int lineCount = 0;
                    String entireText = "";

                    //grab all of the messages into entireText
                    for (int i = 0; i < Integer.MAX_VALUE; i++){
                        if (messages.containsKey("read_paragraph_" + readMessageId + "_" + i)){
                            String read = messages.get("read_paragraph_" + readMessageId + "_" + i);
                            entireText += read + " |";
                        } else {
                            break;
                        }
                    }

                    //split the entire text by spaces
                    String[] readSplitSpaces = entireText.split("\\s");

                    //put words into readLines
                    String singleLine = "";
                    for (String s : readSplitSpaces){
                        s = s + " ";
                        int wordLength = s.length();
                        if (s.contains("|")){
                            String[] sSplitStrings = s.split("\\|");
                            singleLine += sSplitStrings[0];
                            readLines.put(lineCount, singleLine);
                            lineCount++;
                            singleLine = sSplitStrings[1];
                        } else {
                            if ((singleLine.length() + wordLength) <= 26){
                                singleLine += s;
                            } else {
                                readLines.put(lineCount, singleLine);
                                lineCount++;
                                singleLine = s;
                            }
                        }
                    }

                    //print out readLines
                    for (int i = 0; i < Integer.MAX_VALUE; i++){
                        if (readLines.containsKey(i)){
                            System.out.println("[" + i + "] : " + readLines.get(i));
                        } else { break; }
                    }

                    //put readLines into readPages
                    final HashMap<Integer, String> readPages = new HashMap<Integer, String>();
                    int totalPageCount = lineCount / 15;
                    if (lineCount % 15 != 0){ //round up for partial pages
                        totalPageCount++;
                    }
                    for (int i = 0; i < totalPageCount; i++){
                        String tmpPage = "";
                        for (int k = 0; k < 15; k++){
                            if (readLines.containsKey(k + (i * 15))){
                                tmpPage += readLines.get(k + (i * 15)) + "\r\n";
                            }
                        }
                        readPages.put(i, tmpPage); //i is pageCount
                    }

                    //print out readPages
                    for (int i = 0; i < Integer.MAX_VALUE; i++){
                        if (readPages.containsKey(i)){
                            System.out.println("[" + i + "] : " + readPages.get(i));
                        } else { break; }
                    }   

                    displayReadPages(readPages);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public ReadJIntLauncher() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 600, 430);
        JPanel jint = new JPanel();

        jint.setBounds(100, 100, 534, 428);
        jint.setLayout(null);

        textAreaLeft = new JTextArea();
        textAreaLeft.setFont(new Font("Monospaced", Font.PLAIN, 14));
        textAreaLeft.setBounds(25, 37, 213, 297);
        jint.add(textAreaLeft);

        textAreaRight = new JTextArea();
        textAreaRight.setFont(new Font("Monospaced", Font.PLAIN, 14));
        textAreaRight.setBounds(261, 37, 213, 297);
        jint.add(textAreaRight);

        btnPageLeft = new JButton("left");
        btnPageLeft.setBounds(10, 345, 89, 23);
        jint.add(btnPageLeft);

        btnPageRight = new JButton("right");
        btnPageRight.setBounds(385, 345, 89, 23);
        jint.add(btnPageRight);

        getContentPane().add(jint);
    }

    public static void displayReadPages(final HashMap<Integer, String> readConvo){
        System.out.println("\nonLeftPage: " + leftPageCursor);
        //enable buttons if necessary
        if (leftPageCursor != 0){
            btnPageLeft.setEnabled(true);
        } else {
            btnPageLeft.setEnabled(false);
        }
        if (readConvo.containsKey(leftPageCursor + 2)){
            btnPageRight.setEnabled(true);
        } else {
            btnPageRight.setEnabled(false);
        }

        //set left and right page(possibly)
        textAreaLeft.setText(readConvo.get(leftPageCursor));            System.out.println("  left page: " + leftPageCursor);
        if (readConvo.containsKey(leftPageCursor + 1)) {
            textAreaRight.setText(readConvo.get(leftPageCursor + 1));   System.out.println("  right page: " + (leftPageCursor + 1));
        } else {
            textAreaRight.setText("");
        }

        btnPageLeft.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {}
            public void mouseEntered(MouseEvent e) {}
            public void mouseExited(MouseEvent e) {}
            public void mousePressed(MouseEvent e) {}

            public void mouseReleased(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1){
                    leftPageCursor -= 2;
                    displayReadPages(readConvo);
                }
            }
        });

        btnPageRight.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {}
            public void mouseEntered(MouseEvent e) {}
            public void mouseExited(MouseEvent e) {}
            public void mousePressed(MouseEvent e) {}

            public void mouseReleased(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1){
                    leftPageCursor += 2;
                    displayReadPages(readConvo);
                }
            }
        });
    }
}
Was it helpful?

Solution

So I figured out the answer and want to leave this here in case anyone stumbles across this and wants to learn from my mistake. I moved the .addMouseListener code into the constructor and it fixes the problem. I guess it was registering each click another Listener rather than 'overwriting' so to speak.

The only issue I am having now is I am still able to click the 'disabled' buttons.

And here is the solution to that...

source: CodeRanch

The ActionListener is a higher level semantic event, and as such does the right thing when your button is disabled, ie, it can't be triggered. The MouseListener is a lower event. It's also working as designed. Just because you have disabled the button doesn't prevent people from trying to click on it, and the MouseListener is just obediently informing you that a click has occured. The fact that it's disabled is part of the state of the button, but doesn't affect the event the MouseListener is trapping.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top