2015-10-03 4 views
0

Существует просто странное поведение, а затем добавление элементов в модель JList. При вызове метода addElement() список становится пустым, вместо этого добавляет огромный пустой элемент или переносит новый элемент на несколько строк вниз. Другой вызов методов возвращает его со всеми элементами до и после проблемы, включая элемент, добавленный «нестабильным» вызовом. Сначала это казалось проблемой рисования, просто перерисовать вызов не помогает, только добавление нового элемента исправляет проблему.Java JList Model addElement() разбивает визуальное представление списка

Возникла проблема с добавлением части элементов, одинаковых индексов, участвующих в различных запусках. Никогда не видел, чтобы в первый раз это не получилось.

package r; 

import java.io.IOException; 
import java.net.InetAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 
import javax.swing.DefaultListModel; 
import javax.swing.JOptionPane; 


public class R extends javax.swing.JFrame { 

    ServerSocket serverport; 

    /** 
    * Creates new form R 
    */ 
    public R() { 
     initComponents(); 
    } 

    /** 
    * This method is called from within the constructor to initialize the form. 
    * WARNING: Do NOT modify this code. The content of this method is always 
    * regenerated by the Form Editor. 
    */ 
    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code">       
    private void initComponents() { 

     scrollDebug = new javax.swing.JScrollPane(); 
     debugList = new javax.swing.JList(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     setTitle("Debug"); 
     addWindowListener(new java.awt.event.WindowAdapter() { 
      public void windowOpened(java.awt.event.WindowEvent evt) { 
       formWindowOpened(evt); 
      } 
     }); 

     scrollDebug.setAutoscrolls(true); 

     debugList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); 
     scrollDebug.setViewportView(debugList); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addComponent(scrollDebug, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 682, Short.MAX_VALUE) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addComponent(scrollDebug, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE) 
     ); 

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

    private void formWindowOpened(java.awt.event.WindowEvent evt) {         
     new Thread() { 

      @Override 
      public void run() { 

       try { 
        serverport = new ServerSocket(33002, 0, InetAddress.getLoopbackAddress()); 

        debugList.setModel(new DefaultListModel()); 

        while (R.this.isVisible()) { 
         new ClientConnection(serverport.accept()).start(); 

        } 

       } catch (IOException ex) { 
        JOptionPane.showMessageDialog(null, "Error opening server port", "Debug", JOptionPane.ERROR_MESSAGE); 
       } 
      } 

     }.start(); 


    }         

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String args[]) { 
     /* Set the Nimbus look and feel */ 
     //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
     /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */ 
     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (ClassNotFoundException ex) { 
      java.util.logging.Logger.getLogger(R.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (InstantiationException ex) { 
      java.util.logging.Logger.getLogger(R.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (IllegalAccessException ex) { 
      java.util.logging.Logger.getLogger(R.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
      java.util.logging.Logger.getLogger(R.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } 
     //</editor-fold> 

     /* Create and display the form */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new R().setVisible(true); 
      } 
     }); 
    } 

    class ClientConnection extends Thread { 
     Socket connection; 
     public ClientConnection(Socket connection){ 
      this.connection=connection; 
     } 


     @Override 
     public void run() { 
      try { 


       connection.getOutputStream().write(String.format("debug>").getBytes()); 
       connection.getOutputStream().flush(); 

       String response = ""; 
       do { 
        response += (char) connection.getInputStream().read(); 
       } while (!response.endsWith(System.lineSeparator())); 
       response = response.replace(System.lineSeparator(), ""); 

       ((DefaultListModel) debugList.getModel()).addElement(response); 

       if (((DefaultListModel) debugList.getModel()).getSize() > 0) { 
        //debugList.ensureIndexIsVisible(((DefaultListModel) debugList.getModel()).getSize() - 1); 
        debugList.setSelectedIndex(((DefaultListModel) debugList.getModel()).getSize() - 1); 
        scrollDebug.getVerticalScrollBar().setValue(scrollDebug.getVerticalScrollBar().getMaximum()); 

       } 

       connection.close(); 
      } catch (IOException ex) { 
       JOptionPane.showMessageDialog(null, "Error receiving connection", "Debug", JOptionPane.ERROR_MESSAGE); 
      } 
     } 

    } 
    // Variables declaration - do not modify      
    private javax.swing.JList debugList; 
    private javax.swing.JScrollPane scrollDebug; 
    // End of variables declaration     
} 

Полный образец кода добавлен сейчас. Извините за неудобства!

+0

Серьезно? Как вы ожидаете от нас помощи, когда у нас нет информации для работы? Мы не знаем, какой элемент вы добавляете в ListModel или какие-либо другие детали. Отправьте надлежащий [SSCCE] (http://sscce.org/), который демонстрирует проблему. – camickr

+0

Это не SSCCE! Пожалуйста, объясните, как мы можем скомпилировать и выполнить этот код? – camickr

ответ

1

Этот внутренний класс кадра используется для создания новых потоков, получающих данные, и добавления строки в JList.

Компоненты Swing необходимо обновить в разделе «Диспетчер событий», чтобы вы не смогли обновить компонент непосредственно в своей теме.

Таким образом, вы можете обернуть код обновления модели в SwingUtilities.invokeLater(...)

Или вместо того, чтобы использовать отдельную тему вы можете использовать SwingWorker и «публиковать» результаты, как только они становятся доступными.

Для получения дополнительной информации об этих концепциях и рабочих примерах прочитайте раздел из учебника Swing по телефону Concurrency.

+0

Странная вещь, такая проблема с Swing должна быть постоянной, но здесь это происходит в части вызовов. Кроме того, я перепроверяю, но я очень уверен, что мне пришлось пробовать этот путь в прошлом, и это подвело меня. – LifeOnNet

+0

Если обновления не выполняются на EDT, у вас могут быть «случайные» проблемы. – camickr

+0

Ну, надо попробовать. Просто замените invokeAndWait(), чтобы убедиться, что строки отсортированы в порядке приема. invokeLater (...) иногда добавлял строки в неправильном порядке из-за латентности многопоточности! – LifeOnNet

Смежные вопросы