2

ユーザーがデータを JTextArea に入力できるようにするプログラムがあります。その後、データはさらに使用するために解析および処理されます。

代わりにノンブロッキング ファイル ドロップを使用する可能性を十分に認識しており、既に提供していますが、一部のユーザーは大量のデータを貼り付ける場合もあります。約 100MB のテキストを貼り付けると、GUI 全体が約 20 ~ 30 秒間ハングします。

GUI をブロックすることなく、このような膨大な量のデータを受け入れる最善の方法は何でしょうか? JTextArea を維持することは必須ではありません。

GUIのブロックが避けられない場合:貼り付けイベントをキャッチして遅延させて、「貼り付けコマンドを処理しています」というメッセージでGUIを更新し、その後続行する方法はありますか?

コード例:

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import java.awt.BorderLayout;


public class JTextAreaExample {

    private JFrame frame;

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

    /**
     * Create the application.
     */
    public JTextAreaExample() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JTextArea textArea = new JTextArea();
        frame.getContentPane().add(textArea, BorderLayout.CENTER);
    }

}
4

2 に答える 2

1

Progress Monitor APIを使用できるかもしれません

于 2013-09-17T09:25:28.657 に答える
0

私の「解決策」の簡素化された例を共有したいと思いました (ヒントを提供してくれた Andrew Thompson に感謝します)。これが実際には何もしない場合でも、アイデアを得る必要があります。

GUI の応答性を維持することは、ほとんどの場合、期待どおりに機能しています。JTextArea のテキストを実際に更新するときに GUI がハングアップすることは、さらに対策を講じないと回避できません (そのためにはスライディング ウィンドウを使用する必要があります) が、この例の範囲外です。copy-buffer の処理中に GUI はブロックされません。それが問題の内容です。

import java.awt.EventQueue;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;

import java.awt.BorderLayout;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;


public class JTextAreaExample {

    private JFrame frame;
    private static JTextArea textArea;

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

    /**
     * Create the application.
     */
    public JTextAreaExample() {
        JTextAreaExample.textArea = new JTextArea();
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(textArea, BorderLayout.CENTER);
        textArea.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK), "ctrlvpressed");
        textArea.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), "ctrlvpressed");
        CustomPasteAction cpa = new CustomPasteAction("Custom Paste Action", null, "A custom paste action", KeyEvent.VK_V);
        textArea.getActionMap().put("ctrlvpressed", cpa);
    }

    public static final JTextArea getTextArea() {
        return textArea;
    }

}

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;

public class CustomPasteAction extends AbstractAction implements ClipboardOwner {

    /** */
    private static final long serialVersionUID = 1L;

    public CustomPasteAction(String text, ImageIcon icon,
                                             String desc, Integer mnemonic) {
        super(text, icon);
        putValue(SHORT_DESCRIPTION, desc);
        putValue(MNEMONIC_KEY, mnemonic);
    }

    public CustomPasteAction() {
        super("Custom Paste Action", null);
        putValue(SHORT_DESCRIPTION, "My custom paste action");
        putValue(MNEMONIC_KEY, KeyEvent.VK_V);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        new Thread(new Runnable() {
        public void run() {

            String temp = new CustomPasteAction().getClipboardContents();
            System.out.println("Processing: " + temp);
            JTextAreaExample.getTextArea().setText(temp);

        }
    }).start();
    }

    @Override
    public void lostOwnership(Clipboard clipboard, Transferable contents) {
        // do nothing
    }

    /**
      * Get the String residing on the clipboard.
      *
      * @return any text found on the Clipboard; if none found, return an
      * empty String.
      */
      public String getClipboardContents() {
        String result = "";
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        //odd: the Object param of getContents is not currently used
        Transferable contents = null;
        try {
            contents = clipboard.getContents(null);
        } catch(IllegalStateException ise) {
            ise.printStackTrace();
        }
        boolean hasTransferableText =
          (contents != null) &&
          contents.isDataFlavorSupported(DataFlavor.stringFlavor)
        ;
        if ( hasTransferableText ) {
          try {
            result = (String)contents.getTransferData(DataFlavor.stringFlavor);
          }
          catch (UnsupportedFlavorException ex){
            //highly unlikely since we are using a standard DataFlavor
            System.out.println(ex);
            ex.printStackTrace();
          }
          catch (IOException ex) {
            System.out.println(ex);
            ex.printStackTrace();
          }
        }
        return result;
      }

      /**
       * Place a String on the clipboard, and make this class the
       * owner of the Clipboard's contents.
       */
       public void setClipboardContents( String aString ){
         StringSelection stringSelection = new StringSelection( aString );
         Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
         clipboard.setContents( stringSelection, this );
       }

}

于 2013-09-20T14:55:34.410 に答える