Tag Archives: Swing

Flags

[Swing] Hiển thị ảnh trong bảng

Khi sử dụng JTable, có rất nhiều tình huống mà trong đó bạn muốn tùy chỉnh cách trình bày của dữ liệu, đối với những lúc như vậy thì CellRenderer là sự lựa chọn đầu tiên của chúng ta. Trong bài viết “Trang trí bảng với hiệu ứng highlight” mà tôi đã có dịp giới thiệu với các bạn thì chúng ta cũng đã được làm quen với cách sử dụng CellRenderer để tùy biến các ô trong bảng. Tiếp nối bài viết đó, hôm nay tôi sẽ trình bày với các bạn cách để hiển thị ảnh ở trong một bảng.

Dữ liệu mẫu mà chúng ta sử dụng ở trong bài viết này cũng được tôi trích ra từ ví dụ lần trước, chúng ta sẽ dùng JTable để hiển thị danh sách một số quốc gia với các cột: Flag, Name, Capital, Area, Population, Currency.

Các lớp mà tôi sẽ tạo ra để thực hiện ví dụ này bao gồm: Country, CountryData, CountryTableModel, CountryCellRenderer, TableCellRendererExample. Lớp Country có các trường tương ứng với các chi tiết của từng quốc gia, bao gồm: code, name, capital, area, population, currency; Trong đó trường code sẽ được tôi sử dụng để làm căn cứ xác định các ảnh cờ (flag) cho mỗi quốc gia, ví dụ Việt Nam có mã là vn thì sẽ có file ảnh cờ là vn.png, Brazil có mã là br thì sẽ có file ảnh cờ là br.png.

Lớp CountryData chứa phương thức getCountries() trả về cho chúng ta danh sách dữ liệu mẫu, đây là một phương thức mang tính chất mô phỏng, trong thực tế thì ta có thể thay thế bằng dữ liệu lấy về từ các nguồn khác như là cơ sở dữ liệu hoặc file.

Lớp CountryTableModel chính là lớp mà chúng ta sẽ sử dụng để tạo model cho bảng của chúng ta sau này. Đáng chú ý nhất trong ví dụ này đó chính là lớp CountryCellRenderer, đây chính là lớp sẽ giúp tạo ra sự khác biệt giữa bảng của chúng ta và những bảng bình thường khác, chúng ta sẽ phân tích kỹ hơn về lớp này ngay sau đây. Lớp TableCellRendererExample có chứa hàm main()nơi bắt nguồn của sự sống, là nơi mà chúng ta sẽ lấy dữ liệu về, tạo bảng và hiển thị chúng.

Chúng ta sẽ xem xét phương thức duy nhất của lớp CountryCellRenderer  getTableCellRendererComponent():

   public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {        
        JLabel cell = new JLabel();
        
        if(column == 0){
            URL flagUrl = CountryCellRenderer.class.getResource("flags/" + value.toString() + ".png");
            ImageIcon flagIcon = new ImageIcon(flagUrl);
            cell.setIcon(flagIcon);
        }else{            
            cell.setText(value.toString());            
        }
        return cell;
    } 

Ở trong phương thức này các bạn có thể dễ dàng nhận thấy rằng tôi sử dụng một JLabel làm đối tượng được trả về, đây chính là đối tượng đảm nhận nhiệm vụ hiển thị dữ liệu cho từng ô. Đối với những ô nằm trong cột đầu tiên (column == 0) thì tôi lấy về ảnh cờ tương ứng với mã quốc gia rồi dùng nó làm icon cho JLable, còn đối với những ô ở các cột khác (column != 0) thì tôi hiển thị dữ liệu dưới dạng text bình thường.

Thành quả mà chúng ta đạt được là đây:

Với cách làm này, chúng ta có thể điều khiển được hoàn toàn cách mà dữ liệu của chúng ta được hiển thị trong từng ô, điểm mấu chốt ở đây chính là việc chúng ta tạo ra được một lớp trình bày cho ô (Cell Renderer) phù hợp với nhu cầu của mình. Bạn hãy thử phát triển thêm ví dụ này bằng cách thêm vào những cột tùy chỉnh khác nhé, ví dụ như là một cột chứa checkbox chẳng hạn.

Để tải về mã nguồn của ví dụ trong bài viết thì hãy click vào link sau đây và nhấn Ctrl + S nhé:

Link tải mã nguồn