2012-10-22 42 views
11

मैं उत्तर https://stackoverflow.com/a/5820366 और http://tips4java.wordpress.com/2008/11/10/table-column-adjuster/ का उपयोग कर रहा हूं और यह काम करता है, लेकिन अक्सर कॉलम के आकार बहुत व्यापक या बहुत संकीर्ण होते हैं।स्तंभ कक्षों में सबसे लंबी सामग्री फिट करने के लिए जेटीबल कॉलम को कैसे समायोजित करें

कोई फर्क नहीं पड़ता कि मेरी तालिका HTML या टेक्स्ट के साथ भर रही है।

ओरेकल दस्तावेज़ीकरण से मानक TableModel का उपयोग करना।

FormLayout currentEventLayout = new FormLayout(
      "fill:p", 
      "pref, pref"); 
PanelBuilder currentEventBuilder = new PanelBuilder(currentEventLayout); 
currentEventBuilder.add(mainQuotesTable.getTableHeader(), constraints.xy(1, 1)); 
currentEventBuilder.add(mainQuotesTable, constraints.xy(1, 2)); 

एचटीएमएल उदाहरण:

"<html><pre><font size=+1 face='Arial'>" + firstValue + "\n" + secondValue + "</font></pre></html>" 

सरल पंक्ति:

firstValue + " - " + secondValue 

यहाँ है

आकार मोड = JTable.AUTO_RESIZE_OFF

मेरी तालिका के कंटेनर jGoodies है टी वह उदाहरण:

public class TableAdjustExample { 
private static JTable mainTable; 
private static Random random = new Random(); 

private static List<Data> data; 

private static class Data { 
    String name; 
    String surname; 

    private Data(String name, String surname) { 
     this.name = name; 
     this.surname = surname; 
    } 
} 

public static void main(String[] args) { 
    data = stubProvider(); 

    final JFrame frame = new JFrame("table adjust example"); 
    frame.add(createUI()); 
    frame.pack(); 
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    frame.setLocationRelativeTo(null); 
    frame.setSize(350, 400); 
    frame.setVisible(true); 

    update(); 
    java.util.Timer timer = new java.util.Timer(); 
    timer.schedule(new TimerTask() { 
     @Override 
     public void run() { 
      update(); 
     } 
    }, 3000, 3000); 
} 

private static JPanel createUI() { 
    JPanel jPanel = new JPanel(); 
    mainTable = new JTable(2, 3); 
    mainTable.setModel(new AbstractTableModel() { 
     @Override 
     public int getRowCount() { 
      return data.size(); 
     } 

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

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      Data dataItem = data.get(rowIndex); 
      if (columnIndex == 0) { 
       return dataItem.name; 
      } 
      if (columnIndex == 1) { 
       return dataItem.surname; 
      } 
      throw new IllegalStateException(); 
     } 
    }); 
    mainTable.setGridColor(Color.black); 
    mainTable.setShowHorizontalLines(false); 
    mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 

    final TableCellRenderer defaultRenderer = mainTable.getTableHeader().getDefaultRenderer(); 
    mainTable.getTableHeader().setDefaultRenderer(new TableCellRenderer() { 
     @Override 
     public Component getTableCellRendererComponent(JTable jTable, Object o, boolean b, boolean b1, int row, int column) { 
      JLabel parent = (JLabel) defaultRenderer.getTableCellRendererComponent(jTable, o, b, b1, row, column); 
      if (column == 0) { 
       parent.setText("name"); 
      } else { 
       parent.setText("surname"); 
      } 
      return parent; 
     } 
    }); 

    jPanel.add(mainTable.getTableHeader()); 
    jPanel.add(mainTable); 

    return jPanel; 
} 

private static void update() { 
    System.out.println("updating"); 
    data = stubProvider(); 

    adjustJTableRowSizes(mainTable); 
    for (int i = 0; i < mainTable.getColumnCount(); i++) { 
     adjustColumnSizes(mainTable, i, 2); 
    } 
} 

private static void adjustJTableRowSizes(JTable jTable) { 
    for (int row = 0; row < jTable.getRowCount(); row++) { 
     int maxHeight = 0; 
     for (int column = 0; column < jTable.getColumnCount(); column++) { 
      TableCellRenderer cellRenderer = jTable.getCellRenderer(row, column); 
      Object valueAt = jTable.getValueAt(row, column); 
      Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(jTable, valueAt, false, false, row, column); 
      int heightPreferable = tableCellRendererComponent.getPreferredSize().height; 
      maxHeight = Math.max(heightPreferable, maxHeight); 
     } 
     jTable.setRowHeight(row, maxHeight); 
    } 

} 

public static void adjustColumnSizes(JTable table, int column, int margin) { 
    DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel(); 
    TableColumn col = colModel.getColumn(column); 
    int width; 

    TableCellRenderer renderer = col.getHeaderRenderer(); 
    if (renderer == null) { 
     renderer = table.getTableHeader().getDefaultRenderer(); 
    } 
    JLabel comp = (JLabel) renderer.getTableCellRendererComponent(
      table, col.getHeaderValue(), false, false, 0, 0); 
    width = comp.getPreferredSize().width; 

    for (int r = 0; r < table.getRowCount(); r++) { 
     renderer = table.getCellRenderer(r, column); 
     comp = (JLabel) renderer.getTableCellRendererComponent(
       table, table.getValueAt(r, column), false, false, r, column); 
     int currentWidth = comp.getPreferredSize().width; 
     width = Math.max(width, currentWidth); 
    } 

    width += 2 * margin; 

    col.setPreferredWidth(width); 
} 

private static List<Data> stubProvider() { 
    List<Data> data = new ArrayList<Data>(); 
    for (int i = 0; i < 4; i++) { 
     data.add(new Data(
       "<html>" + 
         "<div style='font-size: 15px'>Jason</div>" + 
         "<div style='font-size: 15px'>" + random.nextInt() + "</div>" + 
         "</html>", 
       "Statham " + random.nextInt())); 
    } 
    return data; 
} 
} 

मैं पंक्ति की ऊँचाई समायोजन के साथ इस तरह के समस्या है। <br> निश्चित पंक्ति समायोजन के बजाय <pre>\n</pre> का उपयोग करना।

+0

का रीड होता मैं भी jxtable की packAll का उपयोग कर की कोशिश की है, लेकिन यह JTable तरह बर्ताव करता है कभी-कभी कटौती पाठ से बाहर और कभी-कभी बहुत पैडिंग – trickster77777

+0

छोड़ देता है आपको कॉलम ग्रिड (जैसे 1 अतिरिक्त पिक्सेल) में जोड़ना पड़ सकता है और/या कुछ अतिरिक्त पैडिंग में जोड़ना पड़ सकता है। इसके लिए अच्छी तरह से काम करने के लिए, सुनिश्चित करें कि आप एक निश्चित चौड़ाई फ़ॉन्ट का उपयोग कर रहे हैं। – MadProgrammer

+0

आप निश्चित चौड़ाई फ़ॉन्ट का क्या मतलब है? मैं तालिका को गतिशील रूप से भर रहा हूं और मुझे अगली सामग्री की चौड़ाई नहीं पता है। अगर मैं setRowHeight का उपयोग करता हूं, तो गलत कॉलम चौड़ाई अधिक बार प्रकट होती है और मैं समझ नहीं पा रहा हूं कि इससे संबंधित कैसे है। – trickster77777

उत्तर

15

मेरे लिए ठीक से काम कर रहा ...

enter image description here

public class TestTable01 extends JPanel { 

    private JTable mainTable; 

    public TestTable01() { 
     super(new GridLayout(1, 0)); 

     String[] columnNames = {"First Name", 
           "Last Name", 
           "Sport", 
           "# of Years", 
           "Vegetarian"}; 

     Object[][] data = { 
      {"Kathy", "Smith", 
      "Snowboarding", new Integer(5), new Boolean(false)}, 
      {"John", "Doe", 
      "Rowing", new Integer(3), new Boolean(true)}, 
      {"Sue", "Black", 
      "Knitting", new Integer(2), new Boolean(false)}, 
      {"Jane", "White", 
      "Speed reading", new Integer(20), new Boolean(true)}, 
      {"Joe", "Brown", 
      "Pool", new Integer(10), new Boolean(false)} 
     }; 

     mainTable = new JTable(data, columnNames); 
     mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
     mainTable.setPreferredScrollableViewportSize(new Dimension(500, 70)); 
     mainTable.setFillsViewportHeight(true); 

     update(); 

     //Create the scroll pane and add the table to it. 
     JScrollPane scrollPane = new JScrollPane(mainTable); 

     //Add the scroll pane to this panel. 
     add(scrollPane); 
    } 

    /** 
    * Create the GUI and show it. For thread safety, this method should be 
    * invoked from the event-dispatching thread. 
    */ 
    private static void createAndShowGUI() { 
     //Create and set up the window. 
     JFrame frame = new JFrame("SimpleTableDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Create and set up the content pane. 
     TestTable01 newContentPane = new TestTable01(); 
     newContentPane.setOpaque(true); //content panes must be opaque 
     frame.setContentPane(newContentPane); 

     //Display the window. 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private void update() { 
     System.out.println("updating"); 

     adjustJTableRowSizes(mainTable); 
     for (int i = 0; i < mainTable.getColumnCount(); i++) { 
      adjustColumnSizes(mainTable, i, 2); 
     } 
    } 

    private void adjustJTableRowSizes(JTable jTable) { 
     for (int row = 0; row < jTable.getRowCount(); row++) { 
      int maxHeight = 0; 
      for (int column = 0; column < jTable.getColumnCount(); column++) { 
       TableCellRenderer cellRenderer = jTable.getCellRenderer(row, column); 
       Object valueAt = jTable.getValueAt(row, column); 
       Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(jTable, valueAt, false, false, row, column); 
       int heightPreferable = tableCellRendererComponent.getPreferredSize().height; 
       maxHeight = Math.max(heightPreferable, maxHeight); 
      } 
      jTable.setRowHeight(row, maxHeight); 
     } 

    } 

    public void adjustColumnSizes(JTable table, int column, int margin) { 
     DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel(); 
     TableColumn col = colModel.getColumn(column); 
     int width; 

     TableCellRenderer renderer = col.getHeaderRenderer(); 
     if (renderer == null) { 
      renderer = table.getTableHeader().getDefaultRenderer(); 
     } 
     Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false, false, 0, 0); 
     width = comp.getPreferredSize().width; 

     for (int r = 0; r < table.getRowCount(); r++) { 
      renderer = table.getCellRenderer(r, column); 
      comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, column), false, false, r, column); 
      int currentWidth = comp.getPreferredSize().width; 
      width = Math.max(width, currentWidth); 
     } 

     width += 2 * margin; 

     col.setPreferredWidth(width); 
     col.setWidth(width); 
    } 

    public static void main(String[] args) { 
     //Schedule a job for the event-dispatching thread: 
     //creating and showing this application's GUI. 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 

     }); 
    } 

} 

अपने उदाहरण के साथ मुद्दों की एक संख्या हैं UPDATED लगता है।

  • टेबल्स वास्तव में एक JScrollPane में जोड़ा जाना चाहिए, इस हेडर को जोड़े की देखभाल करेंगे ...
  • डिफ़ॉल्ट लेआउट प्रबंधक एक JPanel के लिए FlowLayout है, इस मामले में, यह शायद आप क्या चाहते हैं नहीं है, आप शायद BorderLayout
  • स्विंग का उपयोग करना सुरक्षित नहीं है। java.util.Timer का उपयोगकर्ता इस नीति का उल्लंघन करेगा, इससे मॉडल और सिंक को बाहर निकलने का कारण बन सकता है। इसके बजाय javax.swing.Timer का उपयोग करें।
  • प्रत्येक के बगल में दो <div> प्रस्तुत करने से HTML लेआउट इंजन तत्वों के बीच एक कमजोर ब्रेक डालने का कारण बन जाएगा। यही है, अगर इंजन निर्णय लेता है कि दोनों तत्वों को एक साथ प्रस्तुत करने के लिए पर्याप्त उपलब्ध स्थान नहीं है, तो यह उन्हें विभाजित करेगा। इसके बजाय एक <div> का उपयोग करने के लिए बेहतरटैग के साथ बेहतर ...

मैं

enter image description here

public class TestColumnWidths { 

    private static JTable mainTable; 
    private static Random random = new Random(); 
    private static List<Data> data; 

    private static class Data { 

     String name; 
     String surname; 

     private Data(String name, String surname) { 
      this.name = name; 
      this.surname = surname; 
     } 
    } 

    public static void main(String[] args) { 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 

       data = stubProvider(); 

       final JFrame frame = new JFrame("table adjust example"); 
       frame.add(createUI()); 
       frame.pack(); 
       frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       update(); 
//     java.util.Timer timer = new java.util.Timer(); 
//     timer.schedule(new TimerTask() { 
//      @Override 
//      public void run() { 
//       update(); 
//      } 
//     }, 3000, 3000); 

       javax.swing.Timer timer = new javax.swing.Timer(3000, new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         update(); 
        } 
       }); 
       timer.setRepeats(true); 
       timer.setCoalesce(true); 
       timer.start(); 

      } 
     }); 
    } 

    private static JPanel createUI() { 
     JPanel jPanel = new JPanel(); 
     mainTable = new JTable(2, 3); 
     mainTable.setModel(new AbstractTableModel() { 
      @Override 
      public int getRowCount() { 
       return data.size(); 
      } 

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

      @Override 
      public Object getValueAt(int rowIndex, int columnIndex) { 
       Data dataItem = data.get(rowIndex); 
       if (columnIndex == 0) { 
        return dataItem.name; 
       } 
       if (columnIndex == 1) { 
        return dataItem.surname; 
       } 
       throw new IllegalStateException(); 
      } 
     }); 
     mainTable.setGridColor(Color.black); 
     mainTable.setShowHorizontalLines(false); 
     mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 

     final TableCellRenderer defaultRenderer = mainTable.getTableHeader().getDefaultRenderer(); 
     mainTable.getTableHeader().setDefaultRenderer(new TableCellRenderer() { 
      @Override 
      public Component getTableCellRendererComponent(JTable jTable, Object o, boolean b, boolean b1, int row, int column) { 
       JLabel parent = (JLabel) defaultRenderer.getTableCellRendererComponent(jTable, o, b, b1, row, column); 
       if (column == 0) { 
        parent.setText("name"); 
       } else { 
        parent.setText("surname"); 
       } 
       return parent; 
      } 
     }); 

//   jPanel.add(mainTable.getTableHeader()); 
//   jPanel.add(mainTable); 

     jPanel.setLayout(new BorderLayout()); 
     jPanel.add(new JScrollPane(mainTable)); 

     return jPanel; 
    } 

    private static void update() { 
     System.out.println("updating"); 
     data = stubProvider(); 

     adjustJTableRowSizes(mainTable); 
     for (int i = 0; i < mainTable.getColumnCount(); i++) { 
      adjustColumnSizes(mainTable, i, 2); 
     } 
    } 

    private static void adjustJTableRowSizes(JTable jTable) { 
     for (int row = 0; row < jTable.getRowCount(); row++) { 
      int maxHeight = 0; 
      for (int column = 0; column < jTable.getColumnCount(); column++) { 
       TableCellRenderer cellRenderer = jTable.getCellRenderer(row, column); 
       Object valueAt = jTable.getValueAt(row, column); 
       Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(jTable, valueAt, false, false, row, column); 
       int heightPreferable = tableCellRendererComponent.getPreferredSize().height; 
       maxHeight = Math.max(heightPreferable, maxHeight); 
      } 
      jTable.setRowHeight(row, maxHeight); 
     } 

    } 

    public static void adjustColumnSizes(JTable table, int column, int margin) { 
     DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel(); 
     TableColumn col = colModel.getColumn(column); 
     int width; 

     TableCellRenderer renderer = col.getHeaderRenderer(); 
     if (renderer == null) { 
      renderer = table.getTableHeader().getDefaultRenderer(); 
     } 
     Component comp = renderer.getTableCellRendererComponent(
       table, col.getHeaderValue(), false, false, 0, 0); 
     width = comp.getPreferredSize().width; 

     for (int r = 0; r < table.getRowCount(); r++) { 
      renderer = table.getCellRenderer(r, column); 
      comp = renderer.getTableCellRendererComponent(
        table, table.getValueAt(r, column), false, false, r, column); 
      int currentWidth = comp.getPreferredSize().width; 
      width = Math.max(width, currentWidth); 
     } 

     width += 2 * margin; 

     col.setPreferredWidth(width); 
    } 

    private static List<Data> stubProvider() { 
     List<Data> data = new ArrayList<Data>(); 
     for (int i = 0; i < 4; i++) { 
      data.add(new Data(
        "<html>" 
        + "<div>" 
        + "<span style='font-size: 15px'>Jason</span>" 
        + "<span style='font-size: 15px'>" + random.nextInt() + "</span>" 
        + "</div>" 
        + "</html>", 
        "Statham " + random.nextInt())); 
     } 
     return data; 
    } 
} 
+0

आपके उदाहरण में मैंने टाइमर और स्क्रीनशॉट पर अपडेट विधि लपेट ली है, आप देख सकते हैं कि दूसरे कॉलम में अनुचित आकार है http://i45.tinypic.com/359eooj.png मैं कैसे कर सकता हूं इस दुष्चक्र को दूर करें :( – trickster77777

+0

? किस प्रकार का टाइमर? क्या आपके पास नमूना कोड है जिसके साथ मैं खेल सकता हूं? – MadProgrammer

+0

वैसे ही मैंने अपने उदाहरण – trickster77777

0

कॉलम के लिए उचित न्यूनतम Width सेट करें जो बहुत संकीर्ण हैं। फिर कॉलम की सामग्री के अनुसार चौड़ाई की गणना करें और उन्हें सेट करें।

+0

समस्या यह है कि 'घटक' (सेल की सामग्री) कुछ शर्तों में गलत प्राथमिकता देता है। यही कारण है कि कोई भी मामला MinSize या PrefSize सेट करें। मुझे प्रत्येक तालिका अद्यतन के बाद कॉलम समायोजित करने की आवश्यकता है। – trickster77777

+3

@ trickster77777 1) स्ट्रिंग मान से अधिकतम आकार प्राप्त करने के लिए कोई समस्या नहीं है और कॉलम मॉडेल में अंतिम कॉलम पर यह मान लागू करें, 2) कुछ शर्तों में गलत प्राथमिकता वापस लौटाता है - बेहतर सहायता के लिए जल्द ही एक छोटा, चलने योग्य और संकलित करने योग्य [SSCCE ] (http://sscce.org/) – mKorbel