2016-06-28 13 views
1

JScrollPaneで囲まれたJTextAreaにいくつかのログを出力していますが、出力がtextAreaの下部に達したときに自動スクロール機能が動作しません。私はオンラインで見たいくつかの方法を試みましたが、どれもうまくいきませんでした。以下はこれまでの私のコードの一部です。JScrollPaneとJTextAreaスクロール

JTextArea ouputLogPane = new JTextArea(); 
JScrollPane outputPane = new JScrollPane(ouputLogPane); 
outputPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
outputPane.setBounds(75, 501, 746, 108); 
contentPane.add(outputPane); 

私はもう1つのクラスで、ソースファイルを読み込み、以下のコードを使用してtextAreaにログの詳細を追加しています。

public void readFile(JTextArea outputLog, JScrollPane scrollPane){ 
    count = 0; 
    while(moreLinesToRead){ 
     if(count % 100 == 0){ 
     outputLog.update(outputLog.getGraphics()); 
     outputLog.append("Completed Reading"+ count + " Records "\n"); 
     DefaultCaret caret = (DefaultCaret)outputLog.getCaret(); 
     caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); 
     outputLog.update(outputLog.getGraphics()); 
     //tried the one below but did not work either 
     //outputLog.setCaretPosition(outputLog.getDocument().getLength()); 
    } 
    count++; 
    } 
} 

最後に、以下のようにボタンをクリックしたときにこのメソッドを呼び出します。

JButton btnNewButton = new JButton("Start Reading"); 
    btnNewButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
     migrationUtil.readFile(ouputLogPane,outputPane); 
    } 
}); 

したがって、基本的に完全な出力は、実行が完了した後にのみ印刷されます。私はそれを処理するために別のスレッドを使用する必要があるかもしれないが、進める方法についてはあまりよく分からないかもしれないと読んだ。

EDIT

import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.Font; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.IOException; 
import java.sql.Connection; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.border.LineBorder; 
import javax.swing.border.TitledBorder; 

public class ReadingExample extends JFrame { 

    private JPanel contentPane; 


    private Connection conn; 


    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        ReadingExample frame = new ReadingExample(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    */ 
    public ReadingExample() { 
     //setResizable(false); 
     setFont(new Font("Dialog", Font.BOLD, 13)); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 936, 720); 
     setLocationRelativeTo(null); 
     contentPane = new JPanel(); 
     contentPane.setBorder(new LineBorder(new Color(0, 0, 0), 2)); 
     setContentPane(contentPane); 
     contentPane.setLayout(null); 

     final JTextArea ouputLogPane = new JTextArea(); 
     final JScrollPane outputPane = new JScrollPane(ouputLogPane); 
     //outputPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
     outputPane.setBounds(67, 189, 746, 108); 
     contentPane.add(outputPane); 


     JButton btnNewButton = new JButton("Start Reading"); 
     btnNewButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       File file = new File("file.txt"); 
       FileReader fileReader = null; 
       try { 
        fileReader = new FileReader(file); 
       } catch (FileNotFoundException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 
       BufferedReader bufferedReader = new BufferedReader(fileReader); 

       String line; 
       try { 
        while((line = bufferedReader.readLine()) != null) { 
         ouputLogPane.append(line + "\n"); 
         ouputLogPane.setCaretPosition(ouputLogPane.getDocument().getLength()); 
         try { 
          Thread.sleep(200); 
         } catch (InterruptedException ee) { 
          ee.printStackTrace(); 
         } 
        } 
       } catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 

      } 
     }); 
     btnNewButton.setFont(new Font("Tahoma", Font.BOLD, 14)); 
     btnNewButton.setBounds(358, 620, 167, 29); 
     contentPane.add(btnNewButton); 

     //JPanel panel_3 = new JPanel(); 
     //panel_3.setBorder(new TitledBorder(null, "Process Log", TitledBorder.LEADING, TitledBorder.TOP, null, null)); 
     //panel_3.setBounds(57, 173, 769, 132); 
     //contentPane.add(panel_3); 

    } 
} 

答えて

1

何あなたは、同時にテキストエリアを更新することができ、あなたのスイングのスレッドがそれによってブロックされないように、別のスレッドでファイルを読み込まれやりたいです。

しかし、SwingスレッドのGUIを更新する必要があります。そのためにはSwingUtilities.invokeLater(runnable)を呼び出してください。一番下までスクロールするには、2つの方法があります

import javax.swing.*; 
import java.awt.*; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 

public class ReadingExample { 

    public static void main(String[] args) { 

     JFrame jFrame = new JFrame(); 
     jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     jFrame.setLocationRelativeTo(null); 

     JPanel mainPanel = new JPanel(new BorderLayout()); 

     JTextArea jTextArea = new JTextArea(); 

     JScrollPane scrollPane = new JScrollPane(jTextArea); 
     scrollPane.setPreferredSize(new Dimension(300, 300)); 
     mainPanel.add(scrollPane, BorderLayout.CENTER); 

     JButton btnNewButton = new JButton("Start Reading"); 
     mainPanel.add(btnNewButton, BorderLayout.SOUTH); 

     jFrame.setContentPane(mainPanel); 

     jFrame.pack(); 
     jFrame.setVisible(true); 

     btnNewButton.addActionListener(e -> { 

      new Thread(() -> { 

       File file = new File("file.txt"); 

       try (FileReader fileReader = new FileReader(file); 
        BufferedReader bufferedReader = new BufferedReader(fileReader)) { 

        String line; 
        while((line = bufferedReader.readLine()) != null) { 

         final String fLine = line; 

         SwingUtilities.invokeLater(() -> { 
          jTextArea.append(fLine + "\n"); 
          jTextArea.setCaretPosition(jTextArea.getDocument().getLength()); 
         }); 

         Thread.sleep(200); 
        } 

       } catch (Exception e1) { 
        e1.printStackTrace(); 
       } 

      }).start(); 
     }); 
    } 
} 
+0

をあなたはスクロールバーを操作することができます。なぜそれがうまくいかないのか分かりません。 – fanbondi

+0

@fanbondi私の答えは – explv

+0

ですので、基本的にtextAreaの更新はメインスレッドによってブロックされています。 – fanbondi

0

:ここ

は、実施例(私はあなたがそれが更新されて見ることができますThread.sleep(200)を追加します)です。

JScrollBar scrollBar = scrollPane.getVerticalScrollBar(); 
scrollBar.setValue(scrollBar.getMaximum()); 

それとも、あなたはより信頼性の高いscrollRectToVisible方法を使用することができます:私は、ほぼ同じコードを持っていると私の編集を参照してください

try { 
    textArea.scrollRectToVisible(
     textArea.modelToView(
      textArea.getDocument().getLength())); 
} catch (BadLocationException e) { 
    throw new RuntimeException(e); 
} 
+0

私の編集を確認してもらえますか?私は両方の方法がありますが、動作していないので、完全なソースコードを提供しました。 – fanbondi

+0

あなたの結論は、他の答えに対するあなたの結論は正しいです:イベントディスパッチスレッドをブロックしているため、コンポーネントのペイントができません。 [Swingの同時実行性](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html)を参照してください。 – VGR

関連する問題