Foro de elhacker.net

Programación => Java => Mensaje iniciado por: leogtz en 10 Octubre 2010, 18:02 pm



Título: JTextArea Número de línea e Ir a línea específica
Publicado por: leogtz en 10 Octubre 2010, 18:02 pm
Hola, estoy haciendo un visor de documentos de texto(sí lo sé, es una estupidez, pero quiero practicar un poco de componentes en Java, aparte que tengo cientos de libros en .txt y me sería útil).

Bueno, lo que hago para volcar todo al JTextArea es leer el archivo con un Scanner y en cada línea hacer un append al JTextArea, así:
Código
  1. File file = fc.getSelectedFile();
  2.                        filename = file.getAbsolutePath();
  3.                        lblNameFile.setText(filename);
  4.                        // Leer archivo:
  5.                        File archivo = new File(filename);
  6.                        Scanner sc = new Scanner(archivo);
  7.                        sc.useDelimiter("\n");
  8.                        String linea;
  9.                        while (sc.hasNext())
  10.                        {
  11.                            linea = sc.next();
  12.                            texto.append((linea.isEmpty() ? " " : ++lineNumber) + "\t" + linea + "\n");
  13.                        }
  14.                        lineNumber = 0;
  15.                        sc.close();

Funciona bien, el problema es que el scroll se va hasta abajo(estamos hablando de unas 3000 líneas por archivo de texto), así que quisiera que aunque todo fuese volcado al JTextArea, el scroll quedará en la primera línea, ¿podrían decirme cómo?

Otra cosa, quisiera un método Ir a, ¿hay algo que me permita ir a cierta línea en el JTextArea?

Usé este método para obtener el número de línea(algo rústico, pero funciona):

Código
  1. while (sc.hasNext())
  2.                        {
  3.                            linea = sc.next();
  4.                            texto.append((linea.isEmpty() ? " " : ++lineNumber) + "\t" + linea + "\n");
  5.                        }

Les dejo todo el código para que lo prueben, de antemano gracias.

http://rapidshare.com/files/424244300/TextViewer.java (http://rapidshare.com/files/424244300/TextViewer.java)

http://www.megaupload.com/?d=M5EZAF8X (http://www.megaupload.com/?d=M5EZAF8X)

EDITO:

He solucionado lo de poner el cursor en la primera línea así:

Código:
texto.setCaretPosition(0);

Ahora me queda otra duda, estoy teniendo problemas al abrir archivos con espacios con el Scanner, ¿alguien sabe como resolverlo?


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: Leyer en 10 Octubre 2010, 23:03 pm
Es raro no debería darte problemas ya que estas seteando el delimitador a \n mm de todas formas usas el nextLine().

El condicional ternario hace poco hay, si no haces linea.isEmpty() te contaría la linea en blanco.

Hice este método que permite ir a una especifica.

Código
  1. void ir(int line,JTextArea area){
  2.        String []t = area.getText().split("\n");
  3. int position=0;
  4. for(int index=0;index<t.length;index++){
  5. if(index == line-1)break;
  6. if(t[index].length()!=0)
  7.        position+=t[index].length();
  8. }
  9. area.setCaretPosition(position+line-1);
  10. }

Un saludo.


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: leogtz en 10 Octubre 2010, 23:48 pm
Gracias, el único problema es que me pone la línea que quiero al final del JTextArea, tengo que corregir eso.

También me queda corregir que reciba nombres de archivos con espacios.


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: Leyer en 10 Octubre 2010, 23:58 pm
No la coloca al final, la coloca al inicio


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: leogtz en 11 Octubre 2010, 00:06 am
Qué raro, he especificado que vaya a la línea 50 en un archivo que tiene miles de líneas y deja la línea al final del JTextArea.

Código
  1. import java.io.*;
  2. import java.util.*;
  3. import java.util.logging.Level;
  4. import java.util.logging.Logger;
  5. import javax.swing.*;
  6. import java.awt.*;
  7. import java.awt.event.*;
  8. import java.lang.*;
  9. import java.awt.event.*;
  10. import java.io.File;
  11. import javax.swing.JFileChooser;
  12. import javax.swing.*;
  13.  
  14. public class TextViewer extends javax.swing.JFrame {
  15.  
  16.    void Ir(int line, JTextArea area)
  17.    {
  18.        String []t = area.getText().split("\n");
  19. int position = 0;
  20. for(int index = 0; index < t.length; index++)
  21.        {
  22. if(index == line - 1)
  23.                    break;
  24. if(t[index].length() != 0)
  25.        position += t[index].length();
  26. }
  27.        area.setCaretPosition(position + line - 1);
  28.    }
  29.  
  30.   int JTextLength(String fileName) throws FileNotFoundException
  31.   {
  32.       int longitud = 0;
  33.       File archivo = new File(fileName);
  34.       Scanner sc = new Scanner(archivo);
  35.       sc.useDelimiter("\n");
  36.       String linea;
  37.  
  38.       while (sc.hasNext())
  39.       {
  40.           linea = sc.next();
  41.           longitud++;
  42.       }
  43.  
  44.       return longitud;
  45.   }
  46.  
  47.    public TextViewer()
  48.    {
  49.  
  50.        this.setLayout(new GridBagLayout());
  51.        GridBagConstraints gbc = new GridBagConstraints();
  52.        JScrollPane scroll = new JScrollPane(texto);
  53.        gbc.fill = GridBagConstraints.BOTH;
  54.        add(scroll, gbc);  
  55.  
  56.        JMenu file = new JMenu("File");
  57.        JMenu help = new JMenu("Help");
  58.  
  59.        help.setMnemonic('H');
  60.        file.setMnemonic('F');
  61.  
  62.        // Elemento del menú "Ayuda".
  63.        JMenuItem aboutItem = new JMenuItem("Acerca de ...");
  64.        aboutItem.setMnemonic('T');
  65.  
  66.        help.add(aboutItem);
  67.        JMenuItem openItem = new JMenuItem("Abrir");
  68.        openItem.setMnemonic('A');
  69.        file.add(openItem);
  70.        JMenuItem exitItem = new JMenuItem("Salir");
  71.        exitItem.setMnemonic('S');
  72.        file.add(exitItem);
  73.  
  74.        openItem.addActionListener(
  75.        {
  76.            public void actionPerformed(ActionEvent e)
  77.            {
  78.                texto.setEditable(false);
  79.                texto.setText("");
  80.                int lineNumber = 0;
  81. String wd = System.getProperty("user.home");
  82. JFileChooser fc = new JFileChooser(wd);
  83.                Filtro filtro = new Filtro();
  84.                filtro.addExtension("txt");
  85.                filtro.setDescription("Archivos de texto plano : ");
  86.                fc.setAcceptAllFileFilterUsed(false);
  87.                fc.setFileFilter(filtro);
  88.  
  89.                fc.setDialogTitle("Seleccione el archivo de texto a abrir");
  90. String filename = "";
  91. int rc = fc.showDialog(null, "Seleccionar archivo");
  92. if (rc == JFileChooser.APPROVE_OPTION)
  93. {
  94.                    try {
  95.                        File file = fc.getSelectedFile();
  96.                        filename = file.getAbsolutePath();
  97.                        lblNameFile.setText(filename);
  98.                        // Leer archivo:
  99.                        File archivo = new File(filename);
  100.                        Scanner sc = new Scanner(archivo);
  101.                        sc.useDelimiter("\n");
  102.                        String linea;
  103.                        while (sc.hasNext())
  104.                        {
  105.                            linea = sc.next();
  106.                            texto.append(++lineNumber + "\t" + linea + "\n");
  107.                        }
  108.                        //texto.setCaretPosition(0);
  109.                        lineNumber = 0;
  110.                        Ir(50, texto);
  111.                        sc.close();
  112.                    } catch (FileNotFoundException ex) {
  113.                        Logger.getLogger(TextViewer.class.getName()).log(Level.SEVERE, null, ex);
  114.                        JOptionPane.showMessageDialog(null, "Error abriendo la ***** : " + filename);
  115.                    }
  116. }
  117.            }
  118. }
  119.        );
  120.  

Saludos.

EDITO:

Al final queda así:

(http://img87.imageshack.us/img87/3761/pantallazotextviewer.png)

No quiero que los números de línea salgan en el texto, ¿alguna idea de qué componente usar para esto o cómo?


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: Leyer en 11 Octubre 2010, 22:07 pm
Eso es mas complicado de lo que parece  :xD , no sabria decirte la forma correcta de hacerlo...habria que chekear el src de jedit :P


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: leogtz en 12 Octubre 2010, 01:35 am
He encontrado esto, parece que funciona, voy a ver como lo adhiero al proyecto.


Código
  1. import java.awt.BorderLayout;
  2. import java.awt.Dimension;
  3. import java.awt.Graphics;
  4. import java.awt.Point;
  5.  
  6. import javax.swing.JFrame;
  7. import javax.swing.JPanel;
  8. import javax.swing.JScrollPane;
  9. import javax.swing.JTextPane;
  10. import javax.swing.text.Document;
  11.  
  12. public class LineNr extends JPanel
  13. {
  14.  JTextPane pane;
  15.  JScrollPane scrollPane;
  16.  
  17.  public LineNr ()
  18.  {
  19.    super ();
  20.    setMinimumSize (new Dimension (30, 30));
  21.    setPreferredSize (new Dimension (30, 30));
  22.    setMinimumSize (new Dimension (30, 30));
  23.    pane = new JTextPane () // we need to override paint so that thelinenumbers stay in sync
  24.    {
  25.      public void paint (Graphics g)
  26.      {
  27. super.paint (g);
  28. LineNr.this.repaint ();
  29.      }
  30.    };
  31.    scrollPane = new JScrollPane (pane);
  32.  }
  33.  
  34.  public void paint (Graphics g)
  35.  {
  36.    super.paint (g);
  37.    int start =
  38.      pane.viewToModel (scrollPane.getViewport ().getViewPosition ());
  39.    int end =
  40.      pane.
  41.      viewToModel (new
  42.   Point (scrollPane.getViewport ().getViewPosition ().x +
  43.  pane.getWidth (),
  44.  scrollPane.getViewport ().getViewPosition ().y +
  45.  pane.getHeight ()));
  46.    Document doc = pane.getDocument ();
  47.    int startline = doc.getDefaultRootElement ().getElementIndex (start);
  48.    int endline = doc.getDefaultRootElement ().getElementIndex (end);
  49.    int fontHeight = g.getFontMetrics (pane.getFont ()).getHeight (); // font
  50.    for (int line = startline, y = 0; line <= endline;
  51. line++, y += fontHeight)
  52.      {
  53. g.drawString (Integer.toString (line), 0, y);
  54.      }
  55.  
  56.  }
  57.  
  58.  public static void main (String[]args)
  59.  {
  60.    JFrame frame = new JFrame ();
  61.    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
  62.    frame.getContentPane ().setLayout (new BorderLayout ());
  63.    final LineNr nr = new LineNr ();
  64.    frame.getContentPane ().add (nr, BorderLayout.WEST);
  65.    frame.getContentPane ().add (nr.scrollPane, BorderLayout.CENTER);
  66.    frame.pack ();
  67.    frame.setSize (new Dimension (400, 400));
  68. //frame.show();
  69.    frame.setVisible (true);
  70.  }
  71.  


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: Leyer en 12 Octubre 2010, 01:52 am
 :D :D excelente, así que era dibujando a mi también me servirá ese ejemplo ;)


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: leogtz en 12 Octubre 2010, 02:19 am
Hola, LEYER, estoy teniendo muchos problemas para adaptar el código a mi proyecto, ¿podrías echarme una mano?

Te subo el proyecto entero por si deseas echarle un vistazo, yo mientras sigo intentando.

http://www.megaupload.com/?d=1W8QBWFV (http://www.megaupload.com/?d=1W8QBWFV)

EDITO:

Encontré esto, pero no lo logro adaptar a mi código :(


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: Leyer en 12 Octubre 2010, 08:12 am
No puedo editar ese code en netbeans :-\ por que hay que modificar ciertas cosas de la GUI. ahora bien te dire lo que tienes que hacer.

Donde vas a colocar el area de texto, hay vas a hacer un panel sin ningún componente agregado.

Luego en el constructor harás lo siguiente.
Le quitas el main a  LineNr

  
Código
  1. public NewJFrame1() {
  2.        setTitle("Test");
  3.        initComponents();
  4.        jPanel1.setLayout(new BorderLayout()); //seteas el layaut del panel creado
  5.  
  6.        LineNr s=new LineNr();
  7.        jPanel1.add(s,BorderLayout.WEST); //contador
  8.        jPanel1.add(s.scrollPane,BorderLayout.CENTER); //area de texto
  9.  
  10.        pack();
  11.    }

Y ya con eso  bastaría.



Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: leogtz en 13 Octubre 2010, 02:06 am
Gracias, no he podido echarlo a andar.


Mira, tengo lo siguiente.

(http://img580.imageshack.us/img580/7779/pantallazoou.png)

En el área libre debajo de donde dice "Archivo" agregué el panel vacio que me indicaste. Pero no te entiendo en cuál constructor hay que poner eso, porque solo tengo el constructor de la clase "TextViewer", ¿sería así?:

Código
  1. public TextViewer()
  2.    {
  3.  
  4.  
  5.        setTitle("Test");
  6.        initComponents();
  7.        jPanel1.setLayout(new BorderLayout()); //seteas el layaut del panel creado
  8.  
  9.        LineNr s=new LineNr();
  10.        jPanel1.add(s,BorderLayout.WEST); //contador
  11.        jPanel1.add(s.scrollPane,BorderLayout.CENTER); //area de texto
  12.        ...

Ejecutando eso me queda:
(http://img89.imageshack.us/img89/3963/pantallazo1zm.png)

Ojalá puedas ayudarme, gracias.


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: Leyer en 13 Octubre 2010, 03:48 am
 :( Que raro yo lo probé asi y si funciona, ha de ser que no eliminaste el area de texto anterior que tenias, tienes que eliminarlo, y creas el panel hay, recuerda el pack(); si sigue sin funcionar sube el code de la ventana principal en pastebin para verla.


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: leogtz en 13 Octubre 2010, 05:24 am
No, definitivamente no. Será el acomodo de los componentes, o no sé, simplemente no he podido.

Código:
http://pastebin.com/j4Rvnn62
Código:
http://pastebin.com/yUjDnyQi
Código:
http://pastebin.com/eNMEaR3b

Gracias, por todo.


Título: Re: JTextArea Número de línea e Ir a línea específica
Publicado por: 1mpuls0 en 25 Octubre 2010, 18:35 pm
Hola Leo, disculpa por contestar hasta ahora.

Citar
Qué raro, he especificado que vaya a la línea 50 en un archivo que tiene miles de líneas y deja la línea al final del JTextArea.

Despues de abrir y cargar el texto haces

Código
  1. texto.setCaretPosition(0);

pero si quitas esa línea de código funciona bien xD, la línea que buscas aparece al inicio.
Algo le falta al método ir.

Citar
No, definitivamente no. Será el acomodo de los componentes, o no sé, simplemente no he podido.

Lo que hice fue crear 2 JPanel para organizarlo un poco.
En el método paint, lo unico que hice fue cambiar el nombre de las variables el ejemplo que encontraste por las de tú programa, y además cambiar la posición en la que dibuja los numeros.

http://www.4shared.com/file/1vbI6NV4/respaldo_visor_2.html

Hay muchas cosas que se pueden mejorar.  ;)

Sigue así.

Un saludo.