2012-09-29 89 views
0

我無法調整JTable中的列的大小(Timeline lookalike)。我複製了時間線課程。我自己寫了timelineUI。這感覺就像我已經嘗試了所有調整列的大小,但似乎不可能。無法調整JTable列的大小

這裏是TimelineUI類,重要的部分是在那裏我試圖調整列0

package group4; 

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.util.ArrayList; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.UIManager; 
import javax.swing.table.TableColumn; 

public class TimelineUI extends JFrame { 

    TimeLine timeline; 
    JScrollPane scrollpane; 
    public TimelineUI() { 
     initTimeline(); 
    } 

    public final void initTimeline() { 
      try {          
       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());    
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      this.setLayout(new BorderLayout()); 
      this.setTitle("Timeline"); 

      timeline = new TimeLine(5,3); 
      scrollpane = new JScrollPane(); 
      scrollpane.setViewportView(timeline); 
      this.add(scrollpane,BorderLayout.CENTER); 

      addData(); 

      this.pack(); 
      this.setSize(1200,200); 
      this.setVisible(true); 
    } 
    public JTable getTable() { 
     return timeline; 
    } 
    private void addData(){ 
     ArrayList<String> columndata = new ArrayList<String>(); 
     columndata.add("Blig (1)"); 
     columndata.add("Workbench (2)"); 
     timeline.addColumn("", columndata); 

     columndata = new ArrayList<String>(); 
     columndata.add("Making spunks"); 
     columndata.add("Service bligs"); 
     timeline.addColumn(0, columndata); 

     columndata = new ArrayList<String>(); 
     columndata.add("Finding plonks"); 
     columndata.add("Finding plonks"); 
     timeline.addColumn(60, columndata); 

     columndata = new ArrayList<String>(); 
     columndata.add("Finding plonks"); 
     columndata.add("Finding plonks"); 
     timeline.addColumn(90, columndata); 

     columndata = new ArrayList<String>(); 
     columndata.add("Finding plonks"); 
     columndata.add("Finding plonks"); 
     timeline.addColumn(120, columndata); 


     columndata = new ArrayList<String>(); 
     columndata.add("Finding plonks"); 
     columndata.add("Finding plonks"); 
     timeline.addColumn(150, columndata); 

     columndata = new ArrayList<String>(); 
     columndata.add("Finding plonks"); 
     columndata.add("Finding plonks"); 
     timeline.addColumn(180, columndata); 


     timeline.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
     timeline.getColumnModel().getColumn(1).setMinWidth(200); 
     timeline.getColumnModel().getColumn(1).setMaxWidth(200); 
     timeline.getColumnModel().getColumn(1).setPreferredWidth(200); 

    } 
} 

底部,然後我們有,我從一個好人就得到了Timeline.class網:

package group4; 

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.util.ArrayList; 
import javax.swing.JTable; 
import javax.swing.ListSelectionModel; 
import javax.swing.SwingUtilities; 
import javax.swing.table.AbstractTableModel; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableColumn; 


public class TimeLine extends JTable{ 
    private final int ROW_DISTANCE = 5; 
    private final int TIME_ROW_HEIGHT = 20; 
    private ImageTableModel itm; 
    private int maxRowHeight = 20; 

    /** 
    * Generates a new TimeLine object 
    * @param rows - number of rows of the default grid 
    * @param columns - number of columns of the default grid 
    */ 
    public TimeLine(int rows, int columns){ 
     setTimeLineLookAndFeel(); 
     itm = initModel(); 
     itm.initGrid(rows, columns); 
     setModel(itm); // set the table model 
     System.out.println(itm.getValueAt(2, 1)); 

    } 

    /** 
    * @return ImageTableModel - a new ImageTableModel 
    */ 
    private ImageTableModel initModel(){ 
     return new ImageTableModel(); 
    } 

    /** 
    * Adds a new column to the table 
    * @param date - The column name as java.util.Date 
    * @param columndata - The row values for this column. 
    */ 
    public void addColumn(int time, ArrayList<String> columndata){ 
     itm.addColumn(time+"", columndata); 
    } 

    /** 
    * Adds a new column to the table 
    * @param columnName - The column name 
    * @param columndata - The row values for this column. 
    */ 
    public void addColumn(String columnName, ArrayList<String> columndata){ 
     itm.addColumn(columnName, columndata); 
    } 

    /** 
    * Utility function to set the scroll pane 
    */ 
    public int getRowCount(){ 
     return itm.getRowCount(); 
    } 

    /** 
    * Utility function to set the scroll pane 
    */ 
    public int getColumnCount(){ 
     return itm.getColumnCount(); 
    } 

    /** 
    * Set some JTable properties to make it 
    * look more like a timeline 
    */ 
    private void setTimeLineLookAndFeel(){ 
     this.getTableHeader().setReorderingAllowed(false); 
     this.setCellSelectionEnabled(true); 
     this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
     this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     this.setIntercellSpacing(new Dimension(0,0)); 
     this.setShowGrid(false);   
     this.setTableHeader(null); 
    } 

    @Override 
    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     g.setColor(Color.BLACK); 
     int y = getRowHeight(0) * (itm.getRowCount() - 1) - 1;  
     g.drawLine(0, y, getSize().width, y); 
    } 

    @Override 
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column){ 
     Component c = super.prepareRenderer(renderer, row, column); 

     if(row == itm.getRowCount()-1){ 
      c.setBackground(java.awt.SystemColor.control); 
     } 
     else if(!this.isCellSelected(row, column)) { 
      c.setBackground(column % 2 != 0 ? new Color(241, 245, 250) : null); 
     }  
     return c; 
    } 


    @Override 
    /** 
    * makes the date column look like a table header 
    */ 
    public void changeSelection(int row, int column, boolean toggle, boolean extend){ 
     Object o = getValueAt(row, column); 
     if (o != null && row != itm.getRowCount()-1){ 
      super.changeSelection(row, column, toggle, extend); 
     } 
    } 


    /** 
    * The table model for this timeline  * 
    */ 
    class ImageTableModel extends AbstractTableModel { 
     private ArrayList<String> columnnames; // holds the column names 
     private ArrayList<ArrayList<String>> data; // holds the table data 
     private int maxRowCount;  
     private int columnCursor; // points on the current column 

     public ImageTableModel(){ 
      columnnames = new ArrayList<String>(); 
      data = new ArrayList<ArrayList<String>>(); 
      maxRowCount = 0; 
      columnCursor = 0; 
     } 

     public Object getValueAt(int row, int column) { 
      if (data.get(column).size()-1<row) { 
       return null; 
      } 
      else{ 
       return data.get(column).get(row); 
      }   
     } 

     public int getRowCount(){ 
      return maxRowCount; 
     } 

     public int getColumnCount(){ 
      return columnnames.size(); 
     } 

     public String getColumnName(int columnIndex){ 
      return columnnames.get(columnIndex); 
     } 

     /** 
     * Adds a new column to the table 
     * @param columnName - The column name 
     * @param columndata - The row values for this column. 
     */ 
     public void addColumn(String columnName, ArrayList<String> columndata) { 
      if(columnCursor >= columnnames.size()){ 
       columnnames.add(columnName); 
       data.add(rotateFillList(columnName,columndata)); 

      } 
      else{ 
       columnnames.set(columnCursor, columnName); 
       data.set(columnCursor, rotateFillList(columnName,columndata)); 
      } 
      SwingUtilities.invokeLater (new Runnable(){  // fixes a nasty java vector bug 
       public void run() { 
        fireTableStructureChanged(); 
        fireTableDataChanged(); 
       } 
      }); 
      columnCursor++; 
     } 

     public void initGrid(int rows, int columns){ 
      for(int i = 0; i < columns+100; i++){ 
       ArrayList<String> newdata = new ArrayList<String>(); 
       for(int j = 0; j < rows; j++){ 
        newdata.add(null); 
       } 
       columnnames.add(String.valueOf(i)); 
       data.add(newdata); 
       maxRowCount = rows; 
      } 
      SwingUtilities.invokeLater (new Runnable(){  // fixes a nasty java vector bug 
       public void run() { 
        fireTableStructureChanged(); 
        fireTableDataChanged(); 
       } 
      }); 
     } 

     /** 
     * Rotates the list. If list.size() is smaller than 
     * maxRowCount the list if filled with null values 
     * This generates the bottom up effect 
     * @param columnName - The column name 
     * @param list 
     * @return list 
     */ 
     private ArrayList<String> rotateFillList(String columnName, ArrayList<String> list){ 
      list.add(0,columnName); // set column name to be on the bottom 

      if(maxRowCount < list.size()){ 
       // adjust all rows to the new maxRowCount 
       maxRowCount = list.size(); 
       for(int i = 0; i < data.size(); i++){ 
        int diff = maxRowCount - data.get(i).size(); 
        for(int j = 0; j < diff; j++){ 
         data.get(i).add(0,null); 
        } 
       }    
      } 
      else { // fill with null values 
       int diff = maxRowCount - list.size(); 
       for(int i = 0; i < diff; i++){ 
        list.add(null); 
       } 
      } 

      ArrayList<String> rotatedList = new ArrayList<String>(); 
      for(int i= list.size()-1;i>=0;i--){  // rotate list 
       rotatedList.add(list.get(i)); 
      } 

      return rotatedList; 
     } 
    } 
} 

這似乎是一個非常簡單的問題,但我無法弄清楚。我需要自己定義一個ColumnModel嗎?我以爲我可以使用默認的。我可以添加列,更改背景顏色等,但不能調整大小。我正在添加一張圖片,顯示它現在的樣子。我想要顯示整個文本。

Image of the timeline

任何幫助將非常感激。我現在花了很多時間。

回答

4

TimeLine.addColumn()表結構通知使用SwingUtilities.invokeLater觸發。一旦所有其他未決事件處理完畢,通知將在EDT上異步執行。

訣竅是fireTableStructureChanged()可能會觸發重建表的列。你可以在這answer找到更多關於fireTableStructureChanged的詳細信息。因此,可能發生的是,您設置了首選尺寸,然後執行fireTableStructureChanged()並將尺寸重置爲默認尺寸。

不知道什麼是該方法中的預期邏輯存在(即評論「修正一個討厭的Java向量錯誤」),但如果執行fireTableStructureChanged()fireTableDataChanged()沒有SwingUtilities.invokeLater你應該看到調整列。

當然,您必須使用EDT,因此如果無法修復,您可以使用SwingUtilities.invokeLater()執行列寬設置。

另請注意,列從0開始。您提到您調整列0的大小,但事實上在您訪問第1列的代碼中。

+0

WOW!你說得對,那是問題所在。我稍後在TimeLine.addColumn和TimeLine.initGrid中刪除了這個調用,現在它就像一個魅力一樣(沒有看到任何令人討厭的bug jet ..)。 不確定你對EDT的意思。最早的截止日期....? 而我的第一列可見似乎實際上是第0列。 感謝一羣幫助,這讓我瘋狂:-) – nilsi

+1

EDT =事件調度線程(Java Swing中的UI線程) – Robin

+0

@nilsi很高興它解決了! :)查看[Event Dispatch Thread](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html)瞭解有關EDT的更多詳細信息。 – tenorsax