Java - วิธีป้องกันการเลื่อนอัตโนมัติในแนวนอนใน JTable เมื่อคลิกเซลล์ที่ 2

ฉันมี JTable ที่มี 2 คอลัมน์ คอลัมน์ที่ 2 มีรายการยาวในเซลล์บางเซลล์ ดังนั้นฉันจึงใช้แถบเลื่อนแนวนอนเพื่อให้ผู้ใช้สามารถเลื่อนด้วยตนเองเพื่อดูว่ามีอะไรเขียนในเซลล์ยาวเหล่านั้น

ต่อไปนี้คือลักษณะของ JTable ก่อนที่จะคลิกแถวใดๆ:

ป้อนคำอธิบายรูปภาพที่นี่

ปัญหาคือเมื่อฉันคลิกซ้ายที่เซลล์ใดๆ ในคอลัมน์ที่สองเพื่อไฮไลต์แถวนั้น ตารางจะเลื่อนในแนวนอนโดยอัตโนมัติเหมือนที่นี่:

ป้อนคำอธิบายรูปภาพที่นี่

มีวิธีป้องกันการเลื่อนอัตโนมัตินี้หรือไม่ แต่ในขณะเดียวกัน ให้ผู้ใช้เลื่อนด้วยตนเอง (ในกรณีที่ผู้ใช้ต้องการเลื่อนในแนวนอนเพื่อดูว่ามีอะไรอยู่ภายในเซลล์)


person Brad    schedule 18.01.2016    source แหล่งที่มา
comment
คุณสามารถโพสต์รหัสสำหรับตารางด้านบนได้หรือไม่?   -  person user1803551    schedule 18.01.2016


คำตอบ (5)


หากคุณต้องการปิดการใช้งานการเลื่อนอัตโนมัติโดยสมบูรณ์คุณก็สามารถใช้ได้

table.setAutoscroll(false)

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

public static class TestTable extends JTable {
    static final int THRESHOLD = 10;
    static String[] columns = {"name", "description", "other"};
    static String[][] data = {
            {"name1", "some description 1", "other value we don't care about"},
            {"name2", "some description 2", "other value we don't care about"},
            {"name3", "some description 3", "other value we don't care about"}
    };

    public TestTable() {
        super(data, columns);
        setAutoResizeMode(AUTO_RESIZE_OFF);
        setAutoscrolls(false);

        getColumnModel().getColumn(0).setPreferredWidth(300);
        getColumnModel().getColumn(1).setPreferredWidth(300);
        getColumnModel().getColumn(2).setPreferredWidth(300);
    }

    @Override
    public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
        super.changeSelection(rowIndex, columnIndex, toggle, extend);
        scrollColumnToVisible(rowIndex, columnIndex);
    }

    private void scrollColumnToVisible(int rowIndex, int columnIndex) {
        Rectangle cellRect = getCellRect(rowIndex, columnIndex, false);

        int leftX = cellRect.x;
        int rightX = cellRect.x + cellRect.width;

        //assuming we're in scroll pane
        int width = Math.min(getWidth(), getParent().getWidth());

        int scrolledX = -getX();
        int visibleLeft = scrolledX;
        int visibleRight = visibleLeft + width;

        //bonus, scroll if only a little of a column is visible
        visibleLeft += THRESHOLD;
        visibleRight -= THRESHOLD;

        boolean isCellVisible = leftX < visibleRight // otherwise cell is hidden on the right
                && rightX > visibleLeft // otherwise cell is hidden on the left
                ;
        if (!isCellVisible) {
            scrollRectToVisible(cellRect);
        }
    }
}

เพื่อเป็นโบนัส ฉันได้เพิ่ม THRESHOLD เพื่อพิจารณาเซลล์ที่ซ่อนอยู่ เมื่อมองเห็นได้เพียงส่วนเล็กๆ เท่านั้น :) รหัสเต็มคือ ที่นี่

person Dzmitry Paulenka    schedule 18.01.2016
comment
ฉันสังเกตเห็นว่าเมื่อเลื่อนด้วยลูกศรขึ้นและลงของแป้นพิมพ์ มันจะไม่แสดงแถวที่เรากำลังเลื่อนไป หากแถวเหล่านั้นอยู่นอกสี่เหลี่ยมที่มองเห็นได้ในปัจจุบันใน JTable ดังนั้นฉันจึงเพิ่มโค้ดนี้ใน scrollColumnToVisible(...) เพื่ออนุญาตให้เลื่อนแนวตั้งด้วยปุ่มเหล่านั้น: pastebin.com/JNakxhCX - person Brad; 19.01.2016

พฤติกรรมการเลื่อนอัตโนมัติของ JTable ถูกนำไปใช้ใน changeSelection() วิธีที่ง่ายที่สุดในการป้องกันการเลื่อนอัตโนมัติในแนวนอนคือการผูกมันไว้กับคอลัมน์ 0 เสมอ:

table = new JTable(new MyTableModel()) {
    @Override
    public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
        super.changeSelection(rowIndex, 0, toggle, extend);
    }
};
person perinion    schedule 10.07.2016

บางทีคุณอาจใช้วิธีการจาก ตารางคอลัมน์แบบคงที่

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

person camickr    schedule 18.01.2016

คุณสามารถ @Override วิธีการ scrollRectToVisible ของตารางได้ ในขั้นตอนแรก ฉันจะใช้การนำไปใช้งานที่ว่างเปล่า เมื่อคุณทราบแน่ชัดว่าคุณต้องการเลื่อนอัตโนมัติเมื่อใด และเมื่อใดไม่ต้องการ ให้ใช้วิธีการตามนั้น

person user1803551    schedule 18.01.2016

หากคุณต้องการปิดการใช้งานการเลื่อนอัตโนมัติแนวนอน ให้ลองทำสิ่งนี้

public class MyTable extends JTable {
    @Override
    public void scrollRectToVisible(Rectangle aRect) {
        aRect.x = 0;
        super.scrollRectToVisible(aRect);
    }
}
person simis Sim    schedule 27.12.2020