Код отказывается отображать текст в JTextArea
Я создал JTextArea, чтобы показывать сообщения в нескольких цветах во время работы программы. Я использую NetBeans 8.0, и я добавил JTextArea в jFrame с именем "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: Вот код Swing GUI, сгенерированный NetBeans:
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>
2 ответа
Ваш текст не будет отображаться, пока весь jButton1ActionPerformed
метод возвращает.
Ваш код работает в потоке событий Swing. Это тот же поток, который на самом деле будет рисовать ваш компонент... и обрабатывать все остальные события. Таким образом, ваш графический интерфейс будет по существу заморожен во время работы FTP.
Если вы выполняете операцию, которая занимает некоторое время, вы должны запустить ее в новом потоке. Вы не должны выполнять операцию 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()
не будет работать вместе.
Длинный ответ: Проверьте 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
,