2013-01-21 48 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