簡體   English   中英

代碼拒絕在JTextArea中顯示文本

[英]Code refuses to display text in JTextArea

我創建了一個JTextArea,以在程序運行時以多種顏色顯示消息。 我使用NetBeans 8.0,並在編寫代碼之前向jFrame添加了一個JTextArea,稱為“ log”。

首先,我定義了一個名為apppane的類:

private void apppane(JTextPane log, String msg, Color c)
{
    /*This allows multi-colour inside the logging pane*/
    StyleContext sc = StyleContext.getDefaultStyleContext();
    AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);

    aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
    aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);

    int len = log.getDocument().getLength();
    log.setCaretPosition(len);
    log.setCharacterAttributes(aset, false);
    log.replaceSelection(msg);
}

接下來,我編寫了代碼以彩色顯示文本:

/*time1 gets the current system time and it works perfectly, no errors there*/
 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // TODO add your handling code here:
    Thread t1;
    FTPClient cli=new FTPClient();
    FTPClientConfig conf=new FTPClientConfig();
    boolean err=false;

    try{
        String ServAddress="195.191.24.202";
        int reply;
       TimeNow time1=new TimeNow();
        apppane(log,time1.whatsthetime()+": Connecting to "+ServAddress+"\n",Color.RED);
        System.out.println(time1.whatsthetime()+": Connecting to "+ServAddress+"\n");
        cli.connect(ServAddress);
        cli.configure(conf);
        TimeNow time2=new TimeNow();
        apppane(log,time2.whatsthetime()+": Connected to "+ServAddress,Color.BLUE);
        System.out.println(time2.whatsthetime()+": Connected to "+ServAddress+"\n");
        System.out.println(time2.whatsthetime()+": "+cli.getReplyString());
        reply=cli.getReplyCode();
        if(!FTPReply.isPositiveCompletion(reply)){
            cli.disconnect();
           TimeNow time3=new TimeNow();
            apppane(log,time3.whatsthetime()+": Connection rejected. \n", Color.RED);
           System.out.println(time3.whatsthetime()+": Connectiion failed \n");
        }
        log.setText(ServAddress);
    }
    catch (Exception e){
        e.printStackTrace();
    }
}                              

但是,沒有文本出現在JTextPane中。 請幫助!

懷疑:我不是要定義新的JTextPane嗎?

更新1:這是NetBeans生成的Swing GUI代碼:

private void initComponents() {

    dochello = new javax.swing.JLabel();
    jButton1 = new javax.swing.JButton();
    jScrollPane2 = new javax.swing.JScrollPane();
    log = new javax.swing.JTextPane();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("MayvilFTP");
    getContentPane().setLayout(null);

    dochello.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N
    dochello.setText("Welcome, Dr. ");
    getContentPane().add(dochello);
    dochello.setBounds(10, 30, 350, 30);

    jButton1.setText("Connect");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });
    getContentPane().add(jButton1);
    jButton1.setBounds(370, 30, 110, 23);

    log.setEditable(false);
    log.setOpaque(false);
    jScrollPane2.setViewportView(log);

    getContentPane().add(jScrollPane2);
    jScrollPane2.setBounds(10, 230, 480, 110);

    pack();
}// </editor-fold>                

在返回整個jButton1ActionPerformed方法之前,您的文本將不會顯示。

您的代碼正在Swing事件線程中運行。 該線程實際上將完成組件的繪制……並處理所有其他事件。 因此,在進行FTP時,您的GUI實際上將被凍結。

如果執行的操作需要一些時間,則應在新線程中啟動該操作。 您不應在按鈕按下事件內執行FTP操作。

您創建一個變量Thread t1但從不使用它。 為什么不在此線程中執行FTP,並在適當的時候使用java.awt.EventQueue.invokeLater來調用apppane

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
  Thread t1 = new Thread(new Runnable() { public void run(){
    apppane_threadsafe( ... );
    // do your ftp stuff
    apppane_threadsafe( ... );
  }});
  t1.start();
}

private void apppane_threadsafe(JTextPane log, String msg, Color c){
  EventQueue.invokeLater(new Runnable() { public void run() {  
    apppane(log, msg, c);
  }
}}

簡短的答案: setEditable(false)replaceSelection()一起工作。

長答案:檢查JTextPane replaceSelection()方法。 它僅適用於可編輯的JTextPane。

@Override
public void replaceSelection(String content) {
    replaceSelection(content, true);
}

private void replaceSelection(String content, boolean checkEditable) {
    if (checkEditable && !isEditable()) {
        UIManager.getLookAndFeel().provideErrorFeedback(JTextPane.this);
        return;
    }
    ...
}

最簡單的解決方案是將窗格設置為可編輯,進行更改,然后重新設置為不可編輯。 但這是丑陋的。
更好的解決方案是操縱基礎Document

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM