2014-09-22 7 views
0

프로그램이 실행되는 동안 여러 색상으로 메시지를 표시하도록 JTextArea를 만들었습니다. NetBeans 8.0을 사용하고 코드를 작성하기 전에 "log"라는 jFrame에 JTextArea를 추가했습니다.코드가 JTextArea에서 텍스트 표시를 거부합니다.

/*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의에 나타납니다 : 나는 색상의 텍스트를 표시하는 코드를 작성,

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); 
} 

다음 :

첫째, 나는 apppane라는 클래스를 정의했다. 도와주세요!

살인자 : 내가 아닌 경우 새 JTextPane을 정의합니까?

UPDATE 1 : 여기 넷빈즈에 의해 생성 된 스윙 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>     
+0

예외가 발생 했습니까? –

+0

@SanjayManohar 없음. 문제가 더욱 커집니다. –

+0

@SanjayManohar Netbeans이 "log"라는 JTextPane에 혼란 스럽다고 생각합니까? 내가 그렇지 않을 때 새로운 JTextPane을 정의한다고 생각합니까? –

답변

2

당신의 텍스트는 전체 jButton1ActionPerformed 메소드가 반환 될 때까지 표시되지 않습니다.

코드가 스윙 이벤트 스레드에서 실행 중입니다. 이것은 실제로 구성 요소의 페인팅을 수행하는 동일한 스레드이며 다른 모든 이벤트를 처리합니다. 따라서 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); 
    } 
}} 
+0

나는 멍청 하네. 나는 당신의 대답이 올 때 실을 꿰기에 바빴다. 그러므로 고독한 실 : P –

+0

매력처럼 작동합니다. 고맙습니다! –

1

짧은 답변 : 함께setEditable(false)replaceSelection() 실 거예요 작동합니다.

긴 대답 :replaceSelection() 방법을 JTextPane에서 확인하십시오. 편집 가능한 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을 조작하는 것입니다.

+0

다시 setEditable (true)로 설정하십시오. 멈춤이 실패합니다. –