2013-01-21 37 views
5

Tôi muốn thêm vào hệ thống của tôi một thiết kế/mô hình khác là JTable. Nó là một thiết kế đơn giản nhưng đối với tôi (như một người mới), tôi gặp khó khăn trong việc thiết lập loại bàn này. Tôi muốn bàn trông như thế này: table design with bold last columnLàm thế nào để tạo ra một mô hình khác nhau của JTable?

Có thể thiết kế một bảng như thế này trong Java không? Xin vui lòng chia sẻ bạn có bất kỳ ý tưởng.

+1

Chắc chắn vậy. Nhưng bạn đã thử cái gì? – Logan

+0

Tôi luôn luôn kết thúc với mô hình phổ biến/truyền thống của jTable. tiêu đề bảng, ô và đường viền chung .. –

+0

Ồ, bạn đang nói về giao diện của nó. Theo mô hình, tôi nghĩ bạn đang nói về 'JTableModel' cho các tên cột và kiểu ô tùy chỉnh và như vậy. – Logan

Trả lời

9

Có rất nhiều cách khác nhau mà bạn có thể đạt được kết quả này ...

enter image description here

Ở đây, tôi đã thay thế các tiêu đề với thực hiện của riêng tôi, thiết lập các renderer di động mặc định cho loại Double để TableCellRenderer và điều chỉnh một số thuộc tính sẵn có của bảng.

public class FancyTable { 

    public static void main(String[] args) { 
     new FancyTable(); 
    } 

    public FancyTable() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JTable table = new JTable(new LoanModel()); 
       table.setTableHeader(new SingleColumnTableHeader()); 
       table.setFillsViewportHeight(true); 
       table.setShowHorizontalLines(true); 
       table.setShowVerticalLines(false); 
       table.setGridColor(Color.LIGHT_GRAY); 
       table.setDefaultRenderer(Double.class, new CurrencyRenderer()); 

       JScrollPane scrollPane = new JScrollPane(table); 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(scrollPane); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 

     }); 
    } 

    public class LoanModel extends AbstractTableModel { 

     private List<Loan> loans; 

     public LoanModel() { 
      loans = new ArrayList<Loan>(25); 
      loans.add(new Loan("Davies S.J", 2500000)); 
      loans.add(new Loan("Lucas M.M", 1700000)); 
      loans.add(new Loan("Smith R.B", 600000)); 
      loans.add(new Loan("Jones T.T", 435000)); 
      loans.add(new Loan("Brown R.B", 600000)); 
      loans.add(new Loan("Walls T.T", 435000)); 
      loans.add(new Loan("Healy R.B", 600000)); 
      loans.add(new Loan("Taylor T.T", 435000)); 
      loans.add(new Loan("Ginns R.B", 600000)); 
      loans.add(new Loan("Murphy H", 435000)); 
     } 

     @Override 
     public int getRowCount() { 
      return loans.size(); 
     } 

     @Override 
     public int getColumnCount() { 
      return 2; 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      Class clazz = String.class; 
      switch (columnIndex) { 
       case 1: 
        clazz = Double.class; 
        break; 
      } 
      return clazz; 
     } 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      Object value = null; 
      Loan loan = loans.get(rowIndex); 
      switch (columnIndex) { 
       case 0: 
        value = loan.getName(); 
        break; 
       case 1: 
        value= loan.getAmount(); 
        break; 
      } 
      return value; 
     } 

    } 

    public class Loan { 

     private String name; 
     private double amount; 

     public Loan(String name, double amount) { 
      this.name = name; 
      this.amount = amount; 
     } 

     public String getName() { 
      return name; 
     } 

     public double getAmount() { 
      return amount; 
     } 

    } 

    public class CurrencyRenderer extends DefaultTableCellRenderer { 

     private Font boldFont; 

     public CurrencyRenderer() { 
      setHorizontalAlignment(JLabel.RIGHT); 
      boldFont = getFont().deriveFont(Font.BOLD); 
     } 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 

      if (value instanceof Double) { 
       value = NumberFormat.getCurrencyInstance().format(value); 
      } 

      super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
      setFont(boldFont); 

      return this; 
     } 

    } 

    public class SingleColumnTableHeader extends JTableHeader { 

     private JLabel renderer; 

     public SingleColumnTableHeader() { 
      setBackground(Color.WHITE); 
      renderer = new JLabel("Top Ten Loan Balances"); 
      renderer.setBorder(new EmptyBorder(4, 0, 4, 0)); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return renderer.getPreferredSize(); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      FontMetrics fm = g2d.getFontMetrics(); 

      Insets insets = getInsets(); 
      int width = getWidth() - (insets.left + insets.right); 
      int height = getHeight() - (insets.top + insets.bottom); 

      renderer.setBounds(insets.left, insets.top, width, height); 
      renderer.paint(g2d); 

      g2d.setColor(Color.LIGHT_GRAY); 
      g2d.setStroke(new BasicStroke(2f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 
      g2d.drawLine(insets.left, insets.top + height - 1, insets.left + width, insets.top + height - 1); 

      g2d.dispose(); 
     } 

    } 

} 

Bạn cũng giống như dễ dàng tạo tùy chỉnh riêng của bạn JTable và ghi đè configureEnclosingScrollPane để thiết lập thành phần của riêng bạn cho tiêu đề bảng, nhưng cá nhân tôi, tôi nghĩ đó là trên giết.

Có khả năng cung cấp kết xuất đồ họa của riêng tôi là một cách tiếp cận linh hoạt hơn và thúc đẩy tái sử dụng các yếu tố thành phần, với ra sản xuất mã vài chặt ...

Bạn có thể tìm thấy nó tiện dụng để đọc qua How to use Tables

Cập nhật

Nó xảy ra với tôi, sau khi một cái gì đó Guillaume nói, bạn chỉ có thể thiết lập các JTable s tiêu đề để null.Sau đó, khi bạn đã thêm bảng vào ngăn cuộn, bạn có thể chỉ cần sử dụng JScrollPane#setColumnHeaderView để đặt tiêu đề thành một mục như số JLabel.

Sẽ dễ dàng hơn khi thực hiện bạn sở hữu JTableHeader

+0

+1 Đây là lựa chọn tốt hơn nhiều. –

+0

+1 cho câu trả lời. Vì vậy, tôi phải sử dụng ** getTableCellRendererComponent **. Cảm ơn bạn rất nhiều. – Amarnath

5

Ghi đè chuẩn bị phương thức Rendere của JTable. Đối với cột 1 chứa văn bản sử dụng một phông chữ và cột 2 sử dụng phông chữ khác.

enter image description here

import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Font; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.TableCellRenderer; 

public class JTableExample { 
public static void main(String[] args) { 

    Object[] column = {"Column One", "Column Two"}; 
    Object[][] data = {{"One", "Two"}, {"Three", "Four"}, {"Five", "Five"}}; 

    JTable toDoTable = new JTable(data, column) { 
     @Override 
     public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, 
       int columnIndex) { 
      if(columnIndex == 1) { 
       setFont(new Font("Arial", Font.BOLD, 12)); 
      } else { 
       setFont(new Font("Arial", Font.ITALIC, 12)); 
      } 

      return super.prepareRenderer(renderer, rowIndex, columnIndex); 
     } 
    }; 
    JScrollPane jpane = new JScrollPane(toDoTable); 
    JPanel panel = new JPanel(); 
    JFrame frame = new JFrame(); 
    frame.setSize(new Dimension(400, 100)); 
    frame.setTitle("JTable Font Setting Example"); 
    panel.add(jpane); 
    frame.add(new JScrollPane(panel)); 
    frame.setVisible(true); 
} 
} 

UPDATE:

Như MadProgrammerGuillaume Polet đã gợi ý. Tôi đã sửa đổi cách tiếp cận của tôi sử dụng DefaultTableCellRenderer (sử dụng mã Guillaume Polet như tài liệu tham khảo.)

enter image description here

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Font; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.DefaultTableCellRenderer; 

public class JTableExample { 
public static void main(String[] args) { 

    Object[] column = {"Column One", "Column Two"}; 
    Object[][] data = {{"One", "Two"}, {"Three", "Four"}, {"Five", "Five"}}; 

    JTable table = new JTable(data, column); 

    table.getColumnModel().getColumn(1).setCellRenderer(new CustomTableCellRenderer()); 
    table.setShowGrid(false); 
    table.setTableHeader(null); 
    JLabel label = new JLabel("Top 10 by Loan Balance"); 
    label.setFont(label.getFont().deriveFont(15.0f)); 
    JScrollPane scroll = new JScrollPane(table); 
    JFrame frame = new JFrame(); 
    frame.setSize(new Dimension(400, 100)); 
    frame.setTitle("JTable Font Setting Example"); 
    frame.add(label, BorderLayout.NORTH); 
    frame.add(scroll, BorderLayout.CENTER); 
    frame.setVisible(true); 
} 
} 

class CustomTableCellRenderer extends DefaultTableCellRenderer { 
    @Override 
    public Component getTableCellRendererComponent(JTable table, Object aValue, 
      boolean isSelected, boolean hasFocus, int rowIndex, int columnIndex) { 
     Component component = super.getTableCellRendererComponent(table, aValue, isSelected, hasFocus, rowIndex, columnIndex); 
     component.setFont(component.getFont().deriveFont(Font.BOLD)); 
     return component; 
    } 
} 

PS:

table.setTableHeader (null): => Đối với ẩn các cột sử dụng.

DefaultTableCellRenderer: => Trả về ô bảng mặc định trình kết xuất đồ họa. Vì vậy, hãy sử dụng tính năng này để tạo kiểu phông chữ cột-1.

table.setShowGrid (sai); => Điều này sẽ làm cho các dòng trong JTable là không hiển thị.

+0

ví dụ trên không có tiêu đề bảng phải không? là nó có thể trong java? –

+1

Nếu bạn có nghĩa là nhãn "Top 10 bởi số dư nợ", tôi sẽ đặt nó ở trên bảng bằng cách sử dụng một 'JLabel'. –

+0

vâng, rõ ràng đó là một nhãn hiệu. Điều gì chỉ quan trọng đối với tôi là các đường biên trên và dưới cùng và các tiêu đề ẩn. Làm thế nào có thể làm điều đó trong 'jTable'. –

3

Một cách khác để thực hiện điều đó. Sử dụng một CellRenderer thích hợp để đạt được các phong cách khác nhau và quản lý sắp xếp văn bản. Để làm cho TableHeader biến mất, chỉ cần đặt nó thành null trên JTable.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Font; 
import java.util.Random; 
import java.util.Vector; 

import javax.swing.BorderFactory; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.table.DefaultTableCellRenderer; 

public class TestTableHeader { 

    public static class BoldTableCellRenderer extends DefaultTableCellRenderer { 

     public BoldTableCellRenderer() { 
      setHorizontalAlignment(RIGHT); 
     } 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
      Component renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
      renderer.setFont(renderer.getFont().deriveFont(Font.BOLD)); 
      return renderer; 
     } 
    } 

    protected void initUI() { 
     Vector<Vector<Object>> datas = new Vector<Vector<Object>>(); 
     Vector<String> colNames = new Vector<String>(); 
     for (int i = 0; i < 2; i++) { 
      colNames.add("Col-" + (i + 1)); 
     } 
     for (int i = 0; i < 15; i++) { 
      Vector<Object> data = new Vector<Object>(); 
      data.add("John Smith (" + (i + 1) + ")"); 
      data.add(new Random().nextInt(4000)); 
      datas.add(data); 
     } 

     table = new JTable(datas, colNames); 
     table.setShowGrid(false); 
     table.getColumnModel().getColumn(1).setCellRenderer(new BoldTableCellRenderer()); 
     table.setFillsViewportHeight(false); 
     table.setTableHeader(null); 
     table.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, Color.GRAY)); 
     JLabel label = new JLabel("Top 10 by Loan Balance"); 
     label.setFont(label.getFont().deriveFont(15.0f)); 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     scrollpane = new JScrollPane(table); 
     scrollpane.setRowHeaderView(null); 
     frame.add(label, BorderLayout.NORTH); 
     frame.add(scrollpane, BorderLayout.CENTER); 
     frame.setSize(300, 200); 
     frame.setVisible(true); 
    } 

    private JTable table; 
    private JScrollPane scrollpane; 

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, 
      UnsupportedLookAndFeelException { 
     UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new TestTableHeader().initUI(); 
      } 
     }); 
    } 

} 
+0

+1 Nếu tất cả OP muốn làm là hiển thị một 'JLabel' làm tiêu đề, họ (nên) có thể thêm bảng vào' JScrollPane' và sau đó đặt chế độ xem tiêu đề của khung cuộn, sử dụng riêng 'JLabel' - 1 cho tiêu đề null! – MadProgrammer

Các vấn đề liên quan