2013-01-21 43 views
5

मैं अपने सिस्टम पर JTable का एक और डिज़ाइन/मॉडल जोड़ना चाहता हूं। यह एक साधारण डिजाइन है लेकिन मेरे लिए (नौसिखिया के रूप में) मुझे इस तरह की टेबल स्थापित करने में कठिनाइयां हैं। मैं तालिका को इस तरह दिखाना चाहता हूं: table design with bold last columnजेटीबल का एक अलग मॉडल कैसे बनाएं?

क्या जावा में इस तरह की एक टेबल डिज़ाइन करना संभव है? कृपया साझा करें कि आपको कोई विचार है।

+1

निश्चित रूप से यह है। लेकिन आपने क्या कोशिश की है? – Logan

+0

मैं हमेशा जेटीबल के आम/पारंपरिक मॉडल के साथ समाप्त हुआ। टेबल हेडर, सेल्स और आम सीमा .. –

+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

के माध्यम से पढ़ने के लिए मिल सकती है

यह मेरे लिए हुआ अपडेट किया गया, के बाद कुछ Guillaume कहा, तो आप बस null को JTable रों हैडर सेट कर सकते हैं।फिर, स्क्रॉल फलक में तालिका जोड़ने के बाद, आप जैसे कुछ को हेडर सेट करने के लिए बस उपयोगकर्ता JScrollPane#setColumnHeaderView उपयोगकर्ता को देख सकते हैं।

यह आसान लागू करने के लिए हो रही हैं आप JTableHeader

+0

+1 यह एक बेहतर विकल्प है। उत्तर के लिए –

+0

+1। तो मुझे ** getTableCellRendererComponent ** का उपयोग करना होगा। बहुत बहुत धन्यवाद। – Amarnath

5

तैयार करें ओवरराइड जेटीबल की प्रस्तुत विधि। कॉलम 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); 
} 
} 

अद्यतन:

रूप MadProgrammer और Guillaume Polet सुझाव दिया है। कॉलम छुपा के लिए =>:

table.setTableHeader (शून्य): मैं अपने दृष्टिकोण DefaultTableCellRenderer का उपयोग कर (। संदर्भ के रूप में Guillaume Polet कोड का उपयोग कर)

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

पुनश्च संशोधित उपयोग।

डिफ़ॉल्टTableCellRenderer: => यह डिफ़ॉल्ट तालिका कक्ष प्रस्तुतकर्ता देता है। तो कॉलम -1 फ़ॉन्ट शैली बनाने के लिए इसका इस्तेमाल करें।

table.setShowGrid (झूठा); => यह जेटीबल में लाइनों को के रूप में दिखाई देगा।

+0

उपर्युक्त उदाहरण में कोई टेबल हेडर नहीं है? क्या यह जावा में संभव है? –

+1

यदि आपका मतलब है "ऋण शेष राशि द्वारा शीर्ष 10" लेबल, तो मैं इसे 'JLabel' का उपयोग करके तालिका के ऊपर रखूंगा। –

+0

हाँ यह स्पष्ट है कि यह एक लेबल है। मेरे लिए केवल यही मायने रखता है शीर्ष और निचली सीमा रेखाएं और छिपे हुए शीर्षलेख। 'JTable' में ऐसी चीज करना कितना संभव है। –

3

फिर भी एक और तरीका यह करने के लिए के मालिक हैं। विभिन्न शैलियों को प्राप्त करने और पाठ संरेखण प्रबंधित करने के लिए एक उचित सेल रेंडरर का उपयोग करें। 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 यदि सभी ओपी करना चाहते थे तो हेडर के रूप में 'JLabel' प्रदर्शित किया गया था, वे (JS) को' JScrollPane' में तालिका जोड़ने में सक्षम होना चाहिए और उसके बाद स्क्रॉल फलक के हेडर व्यू को सेट कर सकते हैं, जिसका उपयोग 'JLabel' - शून्य शीर्षलेख के लिए +1! – MadProgrammer