2013-01-21 50 views
5

我想在我的系統上添加其他設計/模型JTable。這是一個簡單的設計,但對於我來說(作爲新手),我很難設置這種桌子。我希望桌子看起來像這樣: table design with bold last column如何創建不同的JTable模型?

是否可以在Java中設計這樣的表格?請分享你有任何想法。

+1

當然可以。但你有什麼嘗試? – Logan

+0

我總是以jTable的通用/傳統模式結束。表頭,單元格和共同邊框。 –

+0

哦,你說的是它的外觀。按照模型,我認爲你在討論'JTableModel'的自定義列名和單元格類型等。 – Logan

回答

9

有很多不同的方式,你可以達到這個效果......

enter image description here

在這裏,我把它換成頭有我自己的實現,爲Double類型的默認單元格渲染器設置爲我自己TableCellRenderer並調整表的一些內置屬性。

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

    } 

} 

您很容易地創建自己的自定義JTable,並覆蓋configureEnclosingScrollPane設置自己的組件的表頭,但是,我個人認爲這是超必殺。

如果能夠提供自己的渲染器是一種更爲靈活的方式,促進再利用的構成要素,具有了生產緊密結合的代碼...

你可能會發現它很方便的通過How to use Tables

閱讀

更新

我突然想到,之後的東西紀堯姆說,你可以簡單地將JTable頭球設置爲null。然後,一旦將表格添加到滾動窗格中,您可以簡單地使用JScrollPane#setColumnHeaderView將標題設置爲JLabel

它會更容易爲實現你自己的JTableHeader

+0

+1這是一個更好的選擇。 –

+0

+1爲答案。所以我必須使用** getTableCellRendererComponent **。非常感謝。 – Amarnath

5

覆蓋JTable的prepareRendere方法。對於包含文本的列1,使用一種字體,列2使用另一種字體。

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:

由於MadProgrammer紀堯姆波萊已建議。我修改使用DefaultTableCellRenderer我的方法(使用紀堯姆波萊特代碼作爲參考。)

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(空):=>對於隱藏的列使用。

DefaultTableCellRenderer:=>這將返回默認表格單元格 渲染器。所以用這個來製作第1列字體樣式。

table.setShowGrid(false); =>這將使得JTable中的行不可見爲 。

+0

上面的例子沒有表頭,不是嗎?在java中可能嗎? –

+1

如果您的意思是「貸款餘額前十名」標籤,我會使用「JLabel」將其放在表格的上方。 –

+0

是的,這顯然是一個標籤。對我來說唯一重要的是頂部和底部邊框線和隱藏的標題。 'jTable'中怎麼可能做這樣的事情。 –

3

另一種方式來做到這一點。使用適當的CellRenderer來實現各種樣式並管理文本對齊。至於使TableHeader消失,只需在JTable上將其設置爲null即可。

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如果所有OP想要做的是顯示一個'JLabel'作爲頭文件,它們(應該)能夠將該表格添加到'JScrollPane'中,然後使用它自己的'JLabel'來設置滾動窗格的標題視圖 - 空頭的+1! – MadProgrammer