2013-01-18 2 views
1

다음 코드는 Mac OS X 10.6.8에서는 작동하지 않지만 테스트 한 모든 항목, Mac OS X Lion 및 Windows 7에서 작동합니다. Apple의 차이점은 분명합니다. 자바. 테이블 데이터가 Mac에서 제대로 표시되지 않습니다. Windows에서 전시로 다음 코드 여기JScrollPane의 JTable이 Mac OS X에서 제대로 표시되지 않습니다

package com.dramble.dance; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.AbstractTableModel; 
import java.awt.GridLayout; 
import java.util.ArrayList; 
import java.util.List; 

public class TableDemo extends JPanel { 

    public TableDemo() { 
     super(new GridLayout(1,0)); 

     TableModel tableModel = new TableModel(); 

     JTable table = new JTable(tableModel); 

     JScrollPane scrollPane = new JScrollPane(table); 
     add(scrollPane); 

     for(int i = 0 ; i <= 1900 ; i ++) { 
      DataRow row = new DataRow(i,"Firstname"+i,"Lastname"+i); 
      tableModel.appendRow(row); 
      tableModel.fireTableRowsInserted(i, i); 
     } 
    } 

    private static void createAndShowGUI() { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     TableDemo newContentPane = new TableDemo(); 
     newContentPane.setOpaque(true); 
     frame.setContentPane(newContentPane); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 

    private class DataRow { 
     private String fname, lname; 
     private Integer id; 
     public String getFname() { 
      return fname; 
     } 
     public String getLname() { 
      return lname; 
     } 
     public Integer getId() { 
      return id; 
     } 
     public DataRow(Integer id, String fname, String lname) { 
      super(); 
      this.fname = fname; 
      this.lname = lname; 
      this.id = id; 
     } 
    } 

    private class TableModel extends AbstractTableModel { 
     List<DataRow> data; 
     private String[] columnNames = {"ID #","First Name","Last Name"}; 
     private Class[] columnTypes = {int.class, String.class, String.class}; 


     public TableModel() { 
      this.data = new ArrayList<DataRow>(); 
     } 

     @Override 
     public int getColumnCount() { 
      return columnNames.length; 
     } 

     @Override 
     public String getColumnName(int col) { 
      return columnNames[col]; 
     } 

     @Override 
     public int getRowCount() { 
      return this.data.size(); 
     } 

     @Override 
     public Object getValueAt(int row, int col) { 
      DataRow dataRow = this.data.get(row); 
      Object returnValue = null; 

      switch (col) { 
      case 0: 
       returnValue = dataRow.getId(); 
       break; 
      case 1: 
       returnValue = dataRow.getFname(); 
       break; 
      case 2: 
       returnValue = dataRow.getLname(); 
       break; 
      } 
      return returnValue; 
     } 

     public void appendRow(DataRow row) { 
      this.data.add(row); 
     } 

     @Override 
     public boolean isCellEditable(int rowIndex, int vColIndex) { 
      return false; 
     } 

     @Override 
     public Class getColumnClass(int col) { 
      return columnTypes[col]; 
     } 
    } 
} 

이 예상되는 동작의 이미지입니다 다음 Working table on Windows

는 완전한 맥 OS X 10.6.8 Broken on Mac OS X

답변

2

문제는 AbstractTableModel에 있습니다.이 문제는 나에게 놀랍게도 나왔습니다. EDT와 스레드가 확실하게 관련되어있을 것이라고 생각했습니다. 문제는 내 배열 columnTypes에 있고 int.class을 사용하고 있습니다. 이것을 Integer.class으로 변경하면 내 문제가 해결되었습니다.

+0

+1 흥미 롭습니다 : Mac UI delegate는'int.class'를위한 렌더러를 가정하고,'JTable'은 첫 번째 셀에 NPE를 던집니다. – trashgod

1

결석에 동일한 코드입니다 예를 들어, 추측하기 어렵습니다. 당신이 가지고 확인을 보이지만, 두 가지 눈에 띄는 :

  • 내가 frame.setContentPane(newContentPane) 조심 해요, TableDemo 프레임의 내용 창을 대체한다. TableDemoJPanel이므로 플랫폼에 따라 다른 UI 대리자를 상속합니다. 대신 frame.add(newContentPane)을 고려하십시오. 을 내용 창에 전달합니다.

  • appendRowData() 방법은 DanceTableModel이어야합니다. 발신자가 전화 번호를 잊어 버릴 수 없으므로이 번호는 fireTableRowsInserted()이어야합니다.

+0

내 문제를 재현 한이 예제 코드의 경우 Java의 테이블 데모에서 많은 코드를 복사했습니다. 콘텐츠 프레임을 바꾸는 방법은 그들이 어떻게했는지와 상관없이 Mac에서 동일한 문제가 발생합니다. . – tdramble

+0

나는'SwingWorker'로부터 그 테이블을 채우려 할 것이기 때문에'appendRowData()'의 외부에서'fireTableRowsInserted()'를 호출하기로 결정했다. (너무 커서 데이터가 인터넷에서 나올 것이기 때문에, 그리고'fireTableRowsInserted()'는 EDT에서 정확히 호출해야합니까? 그래서'SwingWorker'의'process' 메소드에서 호출 할 것입니다. – tdramble

+0

설명하는 플랫폼 불일치를 재현 할 수 없습니다. 예,'process()'는 EDT에서 실행됩니다. EDT에서는 이벤트를 발생시키는 효과가 있습니다. – trashgod

관련 문제