การตั้งค่า Java JTable ความกว้างของคอลัมน์


95

ฉันมี JTable ซึ่งฉันกำหนดขนาดคอลัมน์ดังนี้:

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);

วิธีนี้ใช้ได้ดี แต่เมื่อขยายตารางให้ใหญ่สุดฉันจะได้พื้นที่ว่างทางด้านขวาของคอลัมน์สุดท้าย เป็นไปได้หรือไม่ที่จะปรับขนาดคอลัมน์สุดท้ายที่ส่วนท้ายของหน้าต่างเมื่อปรับขนาดแล้ว

ฉันพบAUTO_RESIZE_LAST_COLUMNคุณสมบัติในเอกสาร แต่ใช้ไม่ได้

แก้ไข: JTableอยู่ในJScrollPaneขนาดที่ต้องการถูกกำหนด

คำตอบ:


45

จะเกิดอะไรขึ้นถ้าคุณโทรsetMinWidth(400)ในคอลัมน์สุดท้ายแทนของsetPreferredWidth(400)?

ใน JavaDoc สำหรับJTableโปรดอ่านเอกสารdoLayout()อย่างละเอียด นี่คือบิตทางเลือกบางส่วน:

เมื่อเรียกเมธอดอันเป็นผลมาจากการปรับขนาดของหน้าต่างที่ปิดล้อม resizingColumn จะเป็นโมฆะ ซึ่งหมายความว่าการปรับขนาดได้เกิดขึ้น "นอก" JTable และควรกระจายการเปลี่ยนแปลงหรือ "เดลต้า" ไปยังคอลัมน์ทั้งหมดโดยไม่คำนึงถึงโหมดปรับขนาดอัตโนมัติของ JTable นี้

นี่อาจเป็นสาเหตุที่AUTO_RESIZE_LAST_COLUMNไม่ช่วยคุณ

หมายเหตุ: เมื่อ JTable ทำการปรับความกว้างของคอลัมน์มันจะยึดตามค่าต่ำสุดและสูงสุดอย่างแน่นอน

สิ่งนี้บอกว่าคุณอาจต้องการตั้งค่า Min == Max สำหรับทุกคอลัมน์ยกเว้นคอลัมน์สุดท้ายจากนั้นตั้งค่า Min = Preferred ในคอลัมน์สุดท้ายและไม่ต้องตั้งค่า Max หรือกำหนดค่าที่ใหญ่มากสำหรับ Max


1
setMinWidth (400) ยังคงทำให้ทางขวาของตารางว่างเปล่า
Hamza Yerlikaya

2
ลองเพิ่ม setMaxWidth (10000) เพื่อดูว่าสร้างความแตกต่างหรือไม่
Eddie

1
ลบบรรทัด table.setAutoResizeMode (JTable.AUTO_RESIZE_OFF); ซึ่งอาจป้องกันการปรับขนาดที่คุณต้องการ
Eddie

คุณอาจต้องการตั้งค่าขนาดต่ำสุดและสูงสุดใน JTable ด้วยหากคุณยังไม่ได้ทำ
Eddie

4
ตรวจสอบให้แน่ใจว่าคุณทำการโทร setMinWidth หลังจากใช้แบบจำลองตาราง ... นั่นทำให้ฉันสะดุดสักครั้ง
Brian Knoblauch

23

ด้วยJTable.AUTO_RESIZE_OFFตารางจะไม่เปลี่ยนขนาดของคอลัมน์ใด ๆ ให้คุณดังนั้นจึงใช้การตั้งค่าที่คุณต้องการ หากคุณมีเป้าหมายที่จะให้คอลัมน์เป็นค่าเริ่มต้นตามขนาดที่คุณต้องการยกเว้นเพื่อให้คอลัมน์สุดท้ายเติมเต็มส่วนที่เหลือของบานหน้าต่างคุณมีตัวเลือกในการใช้JTable.AUTO_RESIZE_LAST_COLUMNautoResizeMode แต่อาจมีประสิทธิภาพมากที่สุดเมื่อใช้TableColumn.setMaxWidth()แทน TableColumn setPreferredWidth () สำหรับทุกคอลัมน์ยกเว้นคอลัมน์สุดท้าย

เมื่อคุณพอใจแล้วว่าได้AUTO_RESIZE_LAST_COLUMNผลจริงคุณสามารถทดลองใช้ชุดค่าผสมTableColumn.setMaxWidth()และTableColumn.setMinWidth()


1
เมื่อใช้ AUTO_RESIZE_LAST_COLUMN ตารางจะถูกปรับขนาดให้พอดีกับบานหน้าต่างเลื่อนเป้าหมายของฉันคือให้ตารางมีขนาดต่ำสุดที่แน่นอน แต่ทำให้มันโตขึ้นถ้ามันใหญ่กว่าขนาดขั้นต่ำของฉัน
Hamza Yerlikaya

คุณสามารถมีพฤติกรรมนี้ได้หากคุณใช้ TableColumn.setMinWidth () แทน TableColumn.setMaxWidth ()
akf

เพื่อเพิ่มความคิดเห็นล่าสุดของฉัน: ใช้ TableColumn.setMinWidth () สำหรับแต่ละคอลัมน์ในตารางของคุณรวมถึงคอลัมน์สุดท้าย
akf

การตั้งค่าทั้งความกว้างต่ำสุดและสูงสุดช่วยแก้ปัญหาได้ แต่ตอนนี้แถบเลื่อนเป็น missin
Hamza Yerlikaya

16

JTable.AUTO_RESIZE_LAST_COLUMNถูกกำหนดให้เป็น"ในระหว่างการดำเนินการปรับขนาดทั้งหมดให้ใช้การปรับปรุงกับคอลัมน์สุดท้ายเท่านั้น"ซึ่งหมายความว่าคุณต้องตั้งค่าไฟล์ที่ส่วนท้ายของโค้ดของคุณมิฉะนั้น setPreferredWidth () จะไม่ส่งผลใด ๆ !

ดังนั้นในกรณีของคุณนี่เป็นวิธีที่ถูกต้อง:

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);

5

ใช้วิธีนี้

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;
    }
}

หรือขยายJTableชั้นเรียน:

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;
        }
    }
}

แล้ว

table.setColumnWidths(30, 150, 100, 100);

4

อ่านคำพูดของคลีโอพัตรา (ครั้งที่ 2 เธอแนะนำให้ดูjavax.swing.JXTableและตอนนี้ฉันขอโทษที่ไม่ได้ดูครั้งแรก :)) ฉันขอแนะนำให้คุณไปที่ลิงค์

ฉันมีวิธีแก้ปัญหาเดียวกันนี้: (แต่ฉันขอแนะนำให้คุณทำตามลิงค์ด้านบน) ในการปรับขนาดตารางให้ปรับขนาดความกว้างของคอลัมน์ตารางเป็นความกว้างทั้งหมดของตารางปัจจุบัน ในการทำสิ่งนี้ฉันใช้อาร์เรย์ส่วนกลางสำหรับความกว้างของคอลัมน์ (สัมพัทธ์)):

private int[] columnWidths=null;

ฉันใช้ฟังก์ชันนี้เพื่อตั้งค่าความกว้างของคอลัมน์ตาราง:

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);
    }

}

เมื่อตั้งค่าข้อมูลที่ฉันเรียก:

    setColumnWidths(this.columnWidths);

และในการเปลี่ยนฉันเรียก ComponentListener ที่ตั้งค่าเป็นพาเรนต์ของตาราง (ในกรณีของฉันคือ JScrollPane ที่เป็นคอนเทนเนอร์ของตารางของฉัน):

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

โปรดทราบว่าตาราง JTable เป็นแบบโกลบอล:

private JTable table;

และที่นี่ฉันตั้งผู้ฟัง:

    scrollPane=new JScrollPane(table);
    scrollPane.addComponentListener(this);

1
เท่าที่ฉันเห็นนี่เป็นการแฮ็ก (เปราะมาก): ไม่อัปเดตเมื่อผู้ใช้เปลี่ยนความกว้างของคอลัมน์ อีกครั้งฉันขอแนะนำให้คุณดูซอร์สโค้ดของ JXTable - มีคุณสมบัติเพิ่มเติม horizontalScroll ซึ่งทริกเกอร์การเติมความกว้างที่มีอยู่หากผลรวมของคอลัมน์ prefs น้อยกว่าความกว้างปัจจุบันและแสดงแถบเลื่อนแนวนอนเป็นอย่างอื่น
kleopatra

ฉันรู้ว่ามันไม่ตอบสนองต่อผู้ใช้ที่เปลี่ยนความกว้างของตารางด้วยตนเองซึ่งเป็นการแฮ็ก ... แต่อีกครั้ง: ดีกว่าที่แนะนำข้างต้น แต่คุณทำให้ฉันอยากรู้ JXTable .... ฉันจะไปดูที่นั่น! (และยินดีที่ได้เดินเข้ามาหาคุณอีกครั้งในเรื่องโต๊ะ :))
michel.iamit

คุณพูดถูกดูคำพูดของฉันที่อยู่ด้านบนของคำตอบของฉันฉันยกระดับคำพูดของคุณ!
michel.iamit

อย่างน้อยสิ่งนี้ก็มีประโยชน์สำหรับฉันฉันใช้วิธีนี้กับกรณีของฉันด้วยหลักการน้ำหนักคอลัมน์
Solostaran14

2
fireTableStructureChanged();

จะเริ่มต้นพฤติกรรมการปรับขนาด ! หากมีการเรียกวิธีนี้ในรหัสของคุณหลังจากที่คุณตั้งค่าคุณสมบัติการปรับขนาดคอลัมน์การตั้งค่าทั้งหมดของคุณจะถูกรีเซ็ต ผลข้างเคียงนี้สามารถเกิดขึ้นได้โดยทางอ้อม Fe อันเป็นผลมาจากการเปลี่ยนแปลงรูปแบบข้อมูลที่เชื่อมโยงในลักษณะที่เรียกวิธีนี้หลังจากตั้งค่าคุณสมบัติแล้ว


1

ไม่จำเป็นต้องใช้ตัวเลือกเพียงแค่ทำให้ความกว้างที่ต้องการของคอลัมน์สุดท้ายเป็นค่าสูงสุดและจะใช้พื้นที่เพิ่มเติมทั้งหมด

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);

0

รหัสนี้ใช้ได้สำหรับฉันโดยไม่ต้อง 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);

-2

ใช้รหัสนี้ มันได้ผลสำหรับฉัน ฉันพิจารณาสำหรับ 3 คอลัมน์ เปลี่ยนค่าลูปสำหรับรหัสของคุณ

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);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.