import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.Scanner;

import javax.swing.filechooser.*;
import javax.swing.ScrollPaneConstants;

public class validatiorGUI implements ActionListener
{
    JFrame frame = new JFrame("C0015665");
    JFileChooser chooser = new JFileChooser();
    JPanel aPanel = new JPanel();

    // create text area and buttons
    JTextArea area = new JTextArea();
    JButton openButton = new JButton("Open");
    JButton saveButton = new JButton("Save");
    JButton validateButton = new JButton("Validate");

    Scanner input;
    String a;

    public void validatorGUI()
    {//Default constructor

    }

    public void userInterface()
    {

        FileNameExtensionFilter filterTxt = new FileNameExtensionFilter(  
                "HTML files (.html)", "html");

        FileNameExtensionFilter filterTxt1 = new FileNameExtensionFilter(  
                "XML files (.xml)", "xml");

        //set up frame
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(700,700);
        frame.setContentPane(aPanel); 
        aPanel.setLayout(null);



        openButton.setBounds(5, 5, 100, 60);
        aPanel.add(openButton);

        saveButton.setBounds(150, 5, 100, 60);
        aPanel.add(saveButton);

        validateButton.setBounds(300, 5, 100, 60);
        aPanel.add(validateButton);

        area.setBounds(5, 100, 650, 550);
        aPanel.add(area);

        //add drop down choices 
        chooser.addChoosableFileFilter(filterTxt);
        chooser.addChoosableFileFilter(filterTxt1);

        //add action listener events
        openButton.addActionListener(this);
        validateButton.addActionListener(this);

    }//end function

    public void loadFile()
    {

        try{
            int retValue = chooser.showSaveDialog(frame);

            if(retValue == chooser.APPROVE_OPTION)
            {
                File newFile = chooser.getSelectedFile();

                input = new Scanner(newFile);

                while(input.hasNextLine())
                {
                    String word = input.nextLine() + "\n";
                    a = a + word;
                    area.setText(a);
                }//end while loop

            }//end if
        }//end try

        catch(Exception e)
        {
            e.printStackTrace();
        }//end catch
    }//end function

    public void findTags()
    {

        //function to find character and push onto stack??

    }//end method


    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource() == openButton)
        {
            loadFile();
        }

        if(e.getSource() == validateButton)
        {
            findTags();
        }
    }//end action event function

}

my problem is im taking in a file using JFileChooser - however i do not now how to search through the text area line by line to look for a character (an opening < ) which i can then push on to a stack(which ill implement later). the main is another class which calls the userInterface function.

ehm ... a JTextArea has a certain text, not lines of text. if it's flat text in there, without an indication of where a line ends, you can't just search line by line afaik.

@stultuske you are wrong

@JohnSoftware read official Oracle tutorial for working code example about how to search in JTextComponent with highlighting matches

mKorbel - I presume your comment to stultuske is based on the fact that JTextArea handles \n chars properly?
It's not helpful or polite just to say someone is wrong - please always explain why they are wrong, and at least point them in the direction of a right answer.

@JamesCherrill :-) hmmm right

  1. JTextArea.getLineXxx

  2. some methods (possition for Html v.s. JComponent or Icon added to JTextComponent != NavigationFilter & Bias) are accesible only from Document & javax.swing.text.Utilities

  3. difference is that (helicopter view) JTextArea doesn't support multi decorations for one Document

  4. important is convert view to model, always, for all JTextComponents

  5. can be tested on code from Oracle tutorial (can't found that, maybe lost in big clean_up in february, per one, two months there were lost allmost history, suggestion, good practicies, incl. code examples)

.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.LayeredHighlighter;
import javax.swing.text.Position;
import javax.swing.text.View;

public class HighlightExample {

    public static void main(String[] args) {
        UIManager.put("TextPane.caretForeground", Color.yellow);
        UIManager.put("TextPane.selectionBackground", Color.green);
        UIManager.put("TextPane.selectionForeground", Color.blue);
        /*try {
         UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
         } catch (Exception evt) {
         }*/
        JFrame f = new JFrame("Highlight example");
        final JTextArea textPane = new JTextArea();
        textPane.setHighlighter(highlighter);
        textPane.setText("This text pane contains no html. It supports letter wrapping, "
                + "\nThis text pane contains no html. It supports letter wrapping!, "
                + "\nThis text pane contains no html. It supports letter wrapping!, "
                + "\nThis text pane contains no html. It supports letter wrapping!, "
                + "\nThis text pane contains no html. It supports letter wrapping!, "
                + "\nThis text pane contains no html. It supports letter wrapping!");
        JPanel pane = new JPanel();
        pane.setLayout(new BorderLayout());
        pane.add(new JLabel("Enter word, then press ENTER key: "), "West");
        final JTextField tf = new JTextField("wrapping!");
        pane.add(tf, "Center");
        f.add(pane, "South");
        f.add(new JScrollPane(textPane), "Center");
        /*try {
         textPane.read(new FileReader("links1.html"), null);
         } catch (Exception e) {
         System.out.println("Failed to load file " + args[0]);
         System.out.println(e);
         }*/
        final WordSearcher searcher = new WordSearcher(textPane);
        tf.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                word = tf.getText().trim();
                int offset = searcher.search(word);
                if (offset != -1) {
                    try {
                        textPane.scrollRectToVisible(textPane
                                .modelToView(offset));
                    } catch (BadLocationException e) {
                    }
                }
            }
        });
        textPane.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent evt) {
                searcher.search(word);
            }

            @Override
            public void removeUpdate(DocumentEvent evt) {
                searcher.search(word);
            }

            @Override
            public void changedUpdate(DocumentEvent evt) {
            }
        });
        f.setSize(400, 400);
        f.setVisible(true);
    }
    public static String word;
    public static Highlighter highlighter = new UnderlineHighlighter(null);
}

// A simple class that searches for a word in
// a document and highlights occurrences of that word
class WordSearcher {

    public WordSearcher(JTextComponent comp) {
        this.comp = comp;
        this.painter = new UnderlineHighlighter.UnderlineHighlightPainter(
                Color.red);
    }

    // Search for a word and return the offset of the
    // first occurrence. Highlights are added for all
    // occurrences found.
    public int search(String word) {
        int firstOffset = -1;
        Highlighter highlighter = comp.getHighlighter();
        // Remove any existing highlights for last word
        Highlighter.Highlight[] highlights = highlighter.getHighlights();
        for (int i = 0; i < highlights.length; i++) {
            Highlighter.Highlight h = highlights[i];
            if (h.getPainter() instanceof UnderlineHighlighter.UnderlineHighlightPainter) {
                highlighter.removeHighlight(h);
            }
        }
        if (word == null || word.equals("")) {
            return -1;
        }
        // Look for the word we are given - insensitive search
        String content = null;
        try {
            Document d = comp.getDocument();
            content = d.getText(0, d.getLength()).toLowerCase();
        } catch (BadLocationException e) {
            // Cannot happen
            return -1;
        }
        word = word.toLowerCase();
        int lastIndex = 0;
        int wordSize = word.length();
        while ((lastIndex = content.indexOf(word, lastIndex)) != -1) {
            int endIndex = lastIndex + wordSize;
            try {
                highlighter.addHighlight(lastIndex, endIndex, painter);
            } catch (BadLocationException e) {
                // Nothing to do
            }
            if (firstOffset == -1) {
                firstOffset = lastIndex;
            }
            lastIndex = endIndex;
        }
        return firstOffset;
    }
    protected JTextComponent comp;
    protected Highlighter.HighlightPainter painter;
}

class UnderlineHighlighter extends DefaultHighlighter {

    public UnderlineHighlighter(Color c) {
        painter = (c == null ? sharedPainter : new UnderlineHighlightPainter(c));
    }

    // Convenience method to add a highlight with
    // the default painter.
    public Object addHighlight(int p0, int p1) throws BadLocationException {
        return addHighlight(p0, p1, painter);
    }

    @Override
    public void setDrawsLayeredHighlights(boolean newValue) {
        // Illegal if false - we only support layered highlights
        if (newValue == false) {
            throw new IllegalArgumentException(
                    "UnderlineHighlighter only draws layered highlights");
        }
        super.setDrawsLayeredHighlights(true);
    }

    // Painter for underlined highlights
    public static class UnderlineHighlightPainter extends LayeredHighlighter.LayerPainter {

        public UnderlineHighlightPainter(Color c) {
            color = c;
        }

        @Override
        public void paint(Graphics g, int offs0, int offs1, Shape bounds,
                JTextComponent c) {
            // Do nothing: this method will never be called
        }

        @Override
        public Shape paintLayer(Graphics g, int offs0, int offs1, Shape bounds,
                JTextComponent c, View view) {
            g.setColor(color == null ? c.getSelectionColor() : color);
            Rectangle alloc = null;
            if (offs0 == view.getStartOffset() && offs1 == view.getEndOffset()) {
                if (bounds instanceof Rectangle) {
                    alloc = (Rectangle) bounds;
                } else {
                    alloc = bounds.getBounds();
                }
            } else {
                try {
                    Shape shape = view.modelToView(offs0,
                            Position.Bias.Forward, offs1,
                            Position.Bias.Backward, bounds);
                    alloc = (shape instanceof Rectangle) ? (Rectangle) shape
                            : shape.getBounds();
                } catch (BadLocationException e) {
                    return null;
                }
            }
            FontMetrics fm = c.getFontMetrics(c.getFont());
            int baseline = alloc.y + alloc.height - fm.getDescent() + 1;
            g.drawLine(alloc.x, baseline, alloc.x + alloc.width, baseline);
            g.drawLine(alloc.x, baseline + 1, alloc.x + alloc.width, baseline + 1);
            return alloc;
        }
        protected Color color; // The color for the underline
    }
    // Shared painter used for default highlighting
    protected static final Highlighter.HighlightPainter sharedPainter = new UnderlineHighlightPainter(
            null);
    // Painter used for this highlighter
    protected Highlighter.HighlightPainter painter;
}

Edited 3 Years Ago by mKorbel

mKorbel: finding the number of lines, or a lines' offset, is not exactly the same as getting a separate line from the area. how do you do that?
I admit I rarely (not to say never) use the JTextArea, but I am curious in how it would be done.

@JamesCherrill

  • (background) reason why is there JTextComponent.read/write, is Locale and charset issensitive, accepting Tabs and NewLine by default

  • everything is done in View, is managed by methods accesible from Document, JTextComponents or Utilitiesthere are bugs, see bugs in next point

  • one line can occupied one or more lines in JTextArea view, settable by line & word wrap (wordwrap has bug in Java7 for some of standard LookAndFeels)

  • nothing better as Text Component Line Number by Rob Camickr, there is everything

  • feel free to ask any question,

@stultuske I'm sorry no idea how notifiers to @JamesCherrill is ???, stays in clipboard??? or fast hands sorry

convertViewToModel and back modelToView, in some cases is easiest to overridere View as separate paramaters, to avoids casting between API or methods

Edited 3 Years Ago by mKorbel

This article has been dead for over six months. Start a new discussion instead.