Pengaturan Java JTable Column Width

95

Saya memiliki JTable di mana saya mengatur ukuran kolom sebagai berikut:

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(400);

Ini berfungsi dengan baik, tetapi ketika tabel dimaksimalkan, saya mendapatkan ruang kosong di sebelah kanan kolom terakhir. Apakah mungkin untuk mengubah ukuran kolom terakhir ke akhir jendela saat ukurannya diubah?

Saya menemukan AUTO_RESIZE_LAST_COLUMNproperti di dokumen tetapi tidak berhasil.

Edit: JTabledalam JScrollPaneset ukuran yang diinginkan.

Hamza Yerlikaya
sumber

Jawaban:

45

Apa yang terjadi jika Anda menelepon setMinWidth(400)pada kolom terakhir bukan dari setPreferredWidth(400)?

Di JavaDoc untuk JTable, baca dokumen untuk doLayout()dengan sangat hati-hati. Berikut beberapa pilihan bit:

Jika metode ini dipanggil sebagai hasil dari pengubahan ukuran jendela tertutup, resizingColumn adalah null. Ini berarti bahwa pengubahan ukuran telah terjadi "di luar" JTable dan perubahan - atau "delta" - harus didistribusikan ke semua kolom terlepas dari mode pengubahan ukuran otomatis JTable ini.

Ini mungkin mengapa AUTO_RESIZE_LAST_COLUMNtidak membantu Anda.

Catatan: Saat JTable melakukan penyesuaian pada lebar kolom, JTable menghormati nilai minimum dan maksimumnya secara mutlak.

Ini mengatakan bahwa Anda mungkin ingin mengatur Min == Max untuk semua kecuali kolom terakhir, lalu mengatur Min = Lebih disukai pada kolom terakhir dan tidak mengatur Max atau menetapkan nilai yang sangat besar untuk Max.

Eddie
sumber
1
setMinWidth (400) masih menyebabkan bagian kanan meja menjadi kosong
Hamza Yerlikaya
2
Coba tambahkan setMaxWidth (10000) untuk melihat apakah itu membuat perbedaan.
Eddie
1
Hapus baris table.setAutoResizeMode (JTable.AUTO_RESIZE_OFF); Ini dapat mencegah pengubahan ukuran yang Anda inginkan.
Eddie
Anda mungkin juga ingin mengatur ukuran min dan maks pada JTable itu sendiri, jika Anda belum melakukannya,
Eddie
3
Pastikan Anda melakukan panggilan setMinWidth setelah menerapkan model tabel ... Itu membuat saya tersandung sekali untuk sementara.
Brian Knoblauch
23

Dengan JTable.AUTO_RESIZE_OFF, tabel tidak akan mengubah ukuran kolom mana pun untuk Anda, jadi ini akan mengambil pengaturan yang Anda sukai. Jika itu adalah tujuan Anda untuk memiliki kolom default ke ukuran pilihan Anda, kecuali untuk memiliki kolom terakhir mengisi sisa panel, Anda memiliki pilihan untuk menggunakan JTable.AUTO_RESIZE_LAST_COLUMNautoResizeMode, tapi mungkin paling efektif bila digunakan dengan TableColumn.setMaxWidth()bukannya TableColumn. setPreferredWidth () untuk semua kecuali kolom terakhir.

Setelah Anda puas bahwa AUTO_RESIZE_LAST_COLUMNternyata berfungsi, Anda dapat bereksperimen dengan kombinasi TableColumn.setMaxWidth()danTableColumn.setMinWidth()

akf
sumber
1
Ketika AUTO_RESIZE_LAST_COLUMN digunakan, tabel diubah ukurannya agar sesuai dengan panel gulir, tujuan saya adalah memiliki tabel pada ukuran min tertentu tetapi membuatnya bertambah jika lebih besar dari ukuran mininum saya.
Hamza Yerlikaya
Anda bisa memiliki perilaku ini jika Anda menggunakan TableColumn.setMinWidth () sebagai ganti TableColumn.setMaxWidth ().
akf
untuk menambahkan ke komentar terakhir saya: gunakan TableColumn.setMinWidth () untuk setiap kolom di tabel Anda, termasuk kolom terakhir.
akf
pengaturan lebar min dan maks memecahkan masalah tetapi sekarang bilah gulir hilang.
Hamza Yerlikaya
15

JTable.AUTO_RESIZE_LAST_COLUMNdidefinisikan sebagai "Selama semua operasi pengubahan ukuran, terapkan penyesuaian hanya ke kolom terakhir" yang berarti Anda harus menyetel autoresizemode di akhir kode , jika tidak, setPreferredWidth () tidak akan memengaruhi apa pun!

Jadi dalam kasus Anda ini adalah cara yang benar:

table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(400);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
Rico Ocepek
sumber
5

Gunakan metode ini

public static void setColumnWidths(JTable table, int... widths) {
    TableColumnModel columnModel = table.getColumnModel();
    for (int i = 0; i < widths.length; i++) {
        if (i < columnModel.getColumnCount()) {
            columnModel.getColumn(i).setMaxWidth(widths[i]);
        }
        else break;
    }
}

Atau tingkatkan JTablekelas:

public class Table extends JTable {
    public void setColumnWidths(int... widths) {
        for (int i = 0; i < widths.length; i++) {
            if (i < columnModel.getColumnCount()) {
                columnModel.getColumn(i).setMaxWidth(widths[i]);
            }
            else break;
        }
    }
}

Lalu

table.setColumnWidths(30, 150, 100, 100);
Oleg Mikhailov
sumber
4

Membaca ucapan Kleopatra (kali kedua dia menyarankan untuk melihat javax.swing.JXTable , dan sekarang saya minta maaf saya tidak melihat pertama kali :)) Saya sarankan Anda mengikuti tautan

Saya punya solusi ini untuk masalah yang sama: (tapi saya sarankan Anda mengikuti tautan di atas) Saat mengubah ukuran tabel, skala lebar kolom tabel ke lebar total tabel saat ini. untuk melakukan ini saya menggunakan array int global untuk lebar kolom (relatif)):

private int[] columnWidths=null;

Saya menggunakan fungsi ini untuk mengatur lebar kolom tabel:

public void setColumnWidths(int[] widths){
    int nrCols=table.getModel().getColumnCount();
    if(nrCols==0||widths==null){
        return;
    }
    this.columnWidths=widths.clone();

    //current width of the table:
    int totalWidth=table.getWidth();

    int totalWidthRequested=0;
    int nrRequestedWidths=columnWidths.length;
    int defaultWidth=(int)Math.floor((double)totalWidth/(double)nrCols);

    for(int col=0;col<nrCols;col++){
        int width = 0;
        if(columnWidths.length>col){
            width=columnWidths[col];
        }
        totalWidthRequested+=width;
    }
    //Note: for the not defined columns: use the defaultWidth
    if(nrRequestedWidths<nrCols){
        log.fine("Setting column widths: nr of columns do not match column widths requested");
        totalWidthRequested+=((nrCols-nrRequestedWidths)*defaultWidth);
    }
    //calculate the scale for the column width
    double factor=(double)totalWidth/(double)totalWidthRequested;

    for(int col=0;col<nrCols;col++){
        int width = defaultWidth;
        if(columnWidths.length>col){
            //scale the requested width to the current table width
            width=(int)Math.floor(factor*(double)columnWidths[col]);
        }
        table.getColumnModel().getColumn(col).setPreferredWidth(width);
        table.getColumnModel().getColumn(col).setWidth(width);
    }

}

Saat mengatur data yang saya panggil:

    setColumnWidths(this.columnWidths);

dan saat mengubah saya memanggil ComponentListener yang disetel ke induk tabel (dalam kasus saya, JScrollPane yang merupakan wadah dari tabel saya):

public void componentResized(ComponentEvent componentEvent) {
    this.setColumnWidths(this.columnWidths);
}

perhatikan bahwa tabel JTable juga global:

private JTable table;

Dan di sini saya mengatur pendengar:

    scrollPane=new JScrollPane(table);
    scrollPane.addComponentListener(this);
michel.iamit
sumber
1
Sejauh yang saya bisa lihat, ini adalah peretasan (sangat rapuh): ia tidak memperbarui pengguna yang mengubah lebar kolom. Sekali lagi, saya sarankan Anda melihat kode sumber JXTable - ia memiliki properti tambahan horizontalScroll yang memicu pengisian lebar yang tersedia jika jumlah prefs kolom kurang dari lebar saat ini dan sebaliknya menunjukkan scrollbar horizontal
kleopatra
Saya Tahu itu tidak bereaksi terhadap pengguna yang mengubah lebar tabel secara manual, dengan cara itu ini adalah retasan ... tetapi sekali lagi: itu lebih baik daripada yang disarankan di atas. Tapi Anda membuat saya penasaran dengan JXTable .... Saya akan melihat-lihat di sana! (dan senang
bertemu
Anda benar, lihat komentar saya di atas jawaban saya, saya memuji komentar Anda!
michel.iamit
Setidaknya ini berguna bagi saya, saya menggunakan pendekatan ini untuk kasus saya dengan prinsip bobot kolom.
Solostaran14
2
fireTableStructureChanged();

akan default perilaku pengubahan ukuran ! Jika metode ini dipanggil di suatu tempat dalam kode Anda SETELAH Anda mengatur properti ubah ukuran kolom, semua pengaturan Anda akan disetel ulang. Efek samping ini bisa terjadi secara tidak langsung. Fe sebagai konsekuensi dari model data yang ditautkan diubah dengan cara yang disebut metode ini, setelah properti ditetapkan.

hitung0
sumber
1

Tidak perlu opsi, cukup buat lebar yang diinginkan dari kolom terakhir maksimum dan itu akan mengambil semua ruang ekstra.

table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(Integer.MAX_INT);
David Newcomb
sumber
0

Kode ini berfungsi untuk saya tanpa setAutoResizeModes.

        TableColumnModel columnModel = jTable1.getColumnModel();
        columnModel.getColumn(1).setPreferredWidth(170);
        columnModel.getColumn(1).setMaxWidth(170);
        columnModel.getColumn(2).setPreferredWidth(150);
        columnModel.getColumn(2).setMaxWidth(150);
        columnModel.getColumn(3).setPreferredWidth(40);
        columnModel.getColumn(3).setMaxWidth(40);
Harsha Sampath
sumber
-1

Gunakan kode ini. Itu berhasil untuk saya. Saya mempertimbangkan untuk 3 kolom. Ubah nilai loop untuk kode Anda.

TableColumn column = null;
for (int i = 0; i < 3; i++) {
    column = table.getColumnModel().getColumn(i);
    if (i == 0) 
        column.setMaxWidth(10);
    if (i == 2)
        column.setMaxWidth(50);
}
Arijit
sumber