0

JTable (Timeline lookalike) の列のサイズを変更できません。タイムライン クラスをコピーしました。そして、timelineUI を自分で書きました。列のサイズを変更するためにあらゆることを試みたように感じますが、不可能のようです。

ここに 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 を定義する必要がありますか? デフォルトのものを使用できると思いました。列を追加したり、背景色を変更したりできますが、サイズを変更することはできません。現在の様子がわかる写真を追加します。全文を表示したい。

タイムラインのイメージ

どんな助けでも本当にありがたいです。私は今これに多くの時間を費やしました。

4

1 に答える 1

4

テーブル構造ではTimeLine.addColumn()、通知は を使用して起動されSwingUtilities.invokeLaterます。保留中の他のすべてのイベントが処理されると、通知は EDT で非同期に実行されます。

秘訣はfireTableStructureChanged()、テーブルの列の再構築を引き起こす可能性があることです。fireTableStructureChangedこの回答で詳細を確認できます。そのため、優先サイズを設定してfireTableStructureChanged()実行すると、サイズがデフォルトにリセットされる可能性があります。

そのメソッドに意図されたロジックが何であるかはわかりません(つまり、コメント「厄介な Java ベクトルのバグを修正します」) 。fireTableStructureChanged()fireTableDataChanged()SwingUtilities.invokeLater

もちろん、EDT である必要があるため、その修正が不可能な場合は、 を使用して列幅の設定を実行できますSwingUtilities.invokeLater()

また、列は0から始まることに注意してください。列0のサイズを変更すると述べていますが、実際にはコードでは列1にアクセスします。

于 2012-09-29T23:01:34.310 に答える