2016-12-14 58 views
2

我已經在這裏問過了,所以請通過這裏閱讀。這個問題是部分解決了。 How can I add \t spacing in a String that belongs to a DefaultListModel which belongs to a JLIst?如何在字符串格式中均勻地分隔字符串,這是JList中的一個DefaultListModel?

現在我有一個問題:

請看看下面這個例子第一

// Declarations 
String string1 = "Eggs"; 
String string2 = "Whole Chicken"; 
int quantity1 = 100; 
int quantity2 = 25; 

// HTML and PRE tags are added before and after string 
StringBuilder builder1 = new Stringbuilder; 
builder.append("<html><pre>"); 
builder.append(String.format("%s \t %d", string1, quantity1)); 
builder.append("</pre></html>"); 

StringBuilder builder2 = new Stringbuilder; 
builder.append("<html><pre>"); 
builder.append(String.format("%s \t %d", string2, quantity2)); 
builder.append("</pre></html>"); 

// JList is defined, and the builder is added to the list. 
JList<String> list = new JList<String>(); 
list.addElement(builder1.toString()); 
list.addElement(builder2.toString()); 

這是怎麼它會顯示所有項目

Eggs 100 
Whole Chicken 25 

我會喜歡發生的是所有的數量變量都是對齊的而不是間隔的基數d在前一個變量上。任何想法,我可以做到這一點?

謝謝!

==========================

另一項建議是,如果這是可能的,以限定內的字符串的最小長度一個String.format()?

回答

0

正如@GhostCat所說,使用格式字符串中的寬度將解決您的問題。

欲瞭解更多信息,請查看格式字符串的documentation

但是,你想要做什麼讓我想,也許,而不是使用JList,你可以使用JTable?

import javax.swing.*; 

public class ssce{ 
    public static void main(String... args){ 
     // Declarations 
     String string1 = "Eggs"; 
     String string2 = "Whole Chicken"; 
     int quantity1 = 100; 
     int quantity2 = 25; 

     JFrame f = new JFrame("prova"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


     String[] col = {"Ingredient", "Quantity"}; 
     Object[][] data = { 
      {string1, new Integer(quantity1)}, 
      {string2, new Integer(quantity2)} 
     }; 
     JTable tb = new JTable(data, col); 
     f.add(tb); 
     f.setSize(300, 400); 
     f.setVisible(true); 
    } 
} 
+0

直接從教程中獲取的示例。只需要更多的工作並創建一個自定義的'TableModel',你就可以做更多的事情。 – bracco23

0

您可以簡單地使用

%20s 

例如 - 這將把20位到格式化輸出。

所以技巧基本上是首先掃描列表中的所有字符串,然後計算您的格式化模式中需要的合理數字。換句話說:您首先要確定要顯示的字符串的最大長度;然後計算適當的縮進比例。

編輯:有很多不同的方式來影響格式,看到這questionenter link description here,或最好的,研究javadoc,指定存在的所有格式化模式!

+0

那這麼好聽的作品!還有一件事 - 我可以將string1/string2對齊到左邊而不是右邊? –

+0

不客氣。 A)看到我的更新B)如果你很高興,考慮接受我的答案... – GhostCat

0

最簡單的解決方案是使用等寬字體和字符串格式。

public class Main { 

    public static void main(String[] args) { 
    JFrame frame = new JFrame(); 
    frame.setSize(320, 100); 
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

    Container contentPane = frame.getContentPane(); 

    DefaultListModel<String> defaultListModel = new DefaultListModel<>(); 
    defaultListModel.addElement(String.format("%-20s %d", "Eggs", 100)); 
    defaultListModel.addElement(String.format("%-20s %d", "Whole Chicken", 25)); 

    JList<String> jList = new JList<>(defaultListModel); 
    Font defaultListFont = jList.getFont(); 
    jList.setFont(new Font("monospaced", defaultListFont.getStyle(), defaultListFont.getSize())); 

    contentPane.add(jList); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
    } 
} 

這將導致

With monospaced font

一個解決方案,而無需使用等寬字體

如果要對齊取決於ListModel列寬我會聽ListModel更改以計算模型中最長的字符串並使用自定義渲染器。

public static void main(String[] args) { 
    JFrame frame = new JFrame(); 
    frame.setSize(320, 150); 
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

    Container contentPane = frame.getContentPane(); 

    DefaultListModel<String[]> defaultListModel = new DefaultListModel<>(); 
    defaultListModel.addElement(new String[]{"Eggs", "100"}); 
    defaultListModel.addElement(new String[]{"The longest Entry in the list", "12125"}); 
    defaultListModel.addElement(new String[]{"Whole Chicken", "25"}); 

    JList<String[]> jList = new JList<>(defaultListModel); 

    ListModelAwareColumnWidthProvider listModelAwareColumnWidthProvider = new ListModelAwareColumnWidthProvider(); 
    listModelAwareColumnWidthProvider.setListModel(defaultListModel); 

    ColumnCellRenderer columnCellRenderer = new ColumnCellRenderer(listModelAwareColumnWidthProvider); 
    jList.setCellRenderer(columnCellRenderer); 

    contentPane.add(jList); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
} 

,你必須實現類似的東西

支持列

class ColumnCellRenderer implements ListCellRenderer<String[]> { 

    private ColumnWidthProvider columnWidthProvider; 

    public ColumnCellRenderer(ColumnWidthProvider columnWidthProvider) { 
    this.columnWidthProvider = columnWidthProvider; 
    } 


    @Override 
    public Component getListCellRendererComponent(JList<? extends String[]> list, String[] value, int index, boolean isSelected, boolean cellHasFocus) { 
    JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); 

    for (int i = 0; i < value.length; i++) { 
     String valueElement = value[i]; 

     JLabel label = new JLabel(valueElement); 

     align(label, i); 
     panel.add(label); 
    } 

    applyColors(list, panel, isSelected); 

    return panel; 
    } 

    private void applyColors(JList<?> list, JComponent component, boolean isSelected) { 
    if (isSelected) { 
     component.setForeground(list.getSelectionForeground()); 
     component.setBackground(list.getSelectionBackground()); 
    } else { 
     component.setForeground(list.getForeground()); 
     component.setBackground(list.getBackground()); 
    } 
    } 

    private void align(JComponent component, int columnIndex) { 
    Font font = component.getFont(); 
    FontMetrics fontMetrics = component.getFontMetrics(font); 
    int fontHeight = fontMetrics.getHeight(); 

    int columnWidth = columnWidthProvider.getColumnWidth(fontMetrics, columnIndex); 
    component.setPreferredSize(new Dimension(columnWidth, fontHeight)); 
    } 

} 

渲染器的接口,用於列的寬度

interface ColumnWidthProvider { 
    public int getColumnWidth(FontMetrics fontMetrics, int columnIndex); 
} 

渲染器和ColumnWidthProvider的實現觀察ListModel以con 10噸改變

class ListModelAwareColumnWidthProvider implements ColumnWidthProvider { 

    private class ListModelChangeAdapter implements ListDataListener { 
    @Override 
    public void intervalAdded(ListDataEvent e) { 
     initializeColumnWidths(); 
    } 

    @Override 
    public void intervalRemoved(ListDataEvent e) { 
     initializeColumnWidths(); 
    } 

    @Override 
    public void contentsChanged(ListDataEvent e) { 
     initializeColumnWidths(); 
    } 
    } 

    private int defaultColumnWidth = 100; 

    private ListModelChangeAdapter listModelChangeAdapter = new ListModelChangeAdapter(); 
    private ListModel<String[]> listModel; 
    private java.util.List<String> longestColumnStrings = new ArrayList<>(); 

    public void setListModel(ListModel<String[]> listModel) { 
    if (this.listModel != null) { 
     this.listModel.removeListDataListener(listModelChangeAdapter); 
    } 

    this.listModel = listModel; 
    initializeColumnWidths(); 

    if (this.listModel != null) { 
     this.listModel.addListDataListener(listModelChangeAdapter); 
    } 
    } 

    private void initializeColumnWidths() { 
    longestColumnStrings.clear(); 

    if (listModel != null) { 
     int size = listModel.getSize(); 
     for (int i = 0; i < size; i++) { 
     String[] elementAt = listModel.getElementAt(i); 

     for (int columnIndex = 0; columnIndex < elementAt.length; columnIndex++) { 
      String columnValue = elementAt[columnIndex]; 

      while (columnIndex >= longestColumnStrings.size()) { 
      longestColumnStrings.add(null); 
      } 

      String lastLongestColumnString = longestColumnStrings.get(columnIndex); 
      if (lastLongestColumnString == null) { 
      longestColumnStrings.set(columnIndex, columnValue); 
      } else if (columnValue.length() > lastLongestColumnString.length()) { 
      longestColumnStrings.set(columnIndex, columnValue); 
      } 
     } 
     } 
    } 
    } 

    public void setDefaultColumnWidth(int defaultColumnWidth) { 
    this.defaultColumnWidth = defaultColumnWidth; 
    } 

    @Override 
    public int getColumnWidth(FontMetrics fontMetrics, int columnIndex) { 
    if (columnIndex < longestColumnStrings.size()) { 
     String longestColumnString = longestColumnStrings.get(columnIndex); 
     return fontMetrics.stringWidth(longestColumnString); 
    } 
    return defaultColumnWidth; 
    } 
} 

這將導致

With renderer

相關問題