Java - Bagaimana cara mencegah pengguliran otomatis horizontal di JTable saat mengklik sel ke-2?

Saya memiliki JTable dengan 2 kolom. Kolom ke-2 memiliki item panjang di beberapa selnya, jadi saya menggunakan bilah gulir horizontal sehingga pengguna dapat menggulirnya secara manual untuk melihat apa yang tertulis di sel panjang tersebut.

Berikut tampilan JTable sebelum mengklik salah satu barisnya:

masukkan deskripsi gambar di sini

Masalahnya adalah ketika saya mengklik kiri sel mana pun di kolom kedua untuk menyorot baris itu, tabel secara otomatis bergulir secara horizontal seperti di sini:

masukkan deskripsi gambar di sini

Apakah ada cara untuk mencegah pengguliran otomatis ini, namun pada saat yang sama tetap mempertahankan pengguliran pengguna manual (Jika pengguna ingin menggulir secara horizontal untuk melihat apa yang ada di dalam sel)?


person Brad    schedule 18.01.2016    source sumber
comment
Bisakah Anda memposting kode untuk tabel di atas?   -  person user1803551    schedule 18.01.2016


Jawaban (5)


Jika Anda ingin menonaktifkan autoscroll sepenuhnya, Anda bisa menggunakan saja

table.setAutoscroll(false)

Tapi sungguh, itu tidak terlalu berguna, karena navigasi keyboard tidak berfungsi. Saya menyarankan Anda untuk tetap melakukan autoscroll, jika sel benar-benar tersembunyi dari pandangan. Untuk melakukannya, saya telah menonaktifkan autoscroll dan mengganti changeSelection untuk menangani scrolling, ketika sel disembunyikan.

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

Sebagai bonus, saya telah menambahkan THRESHOLD untuk mempertimbangkan sel yang disembunyikan, ketika hanya sebagian kecil yang benar-benar terlihat :) Kode lengkapnya adalah di sini.

person Dzmitry Paulenka    schedule 18.01.2016
comment
Saya perhatikan bahwa ketika menggulir dengan panah atas dan bawah pada keyboard, baris yang kita gulir tidak akan ditampilkan jika baris tersebut berada di luar persegi panjang yang terlihat saat ini di JTable, jadi saya telah menambahkan kode ini ke scrollColumnToVisible(...) untuk memungkinkan pengguliran vertikal dengan tombol tersebut: pastebin.com/JNakxhCX - person Brad; 19.01.2016

Perilaku gulir otomatis JTable diimplementasikan di changeSelection(). Jadi cara paling sederhana untuk mencegah autoscroll horizontal adalah dengan mengikatnya selalu ke kolom 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

Mungkin Anda bisa menggunakan pendekatan dari Tabel Kolom Tetap.

Ini memungkinkan Anda membuat "tajuk baris" untuk panel gulir. Header baris tidak pernah di-scroll, sehingga kolom pertama akan selalu terlihat. Namun, Anda masih dapat menelusuri kolom yang tersisa.

person camickr    schedule 18.01.2016

Anda dapat @Override metode scrollRectToVisible tabel. Sebagai langkah pertama, saya akan menggunakan implementasi kosong. Saat Anda mengetahui secara pasti kapan Anda menginginkan pengguliran otomatis dan kapan tidak, terapkan metode yang sesuai.

person user1803551    schedule 18.01.2016

Jika Anda ingin menonaktifkan gulir otomatis horizontal, coba ini.

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