Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在String.format';JList中是否有DefaultListModel?_Java_String_Jlist_Defaultlistmodel - Fatal编程技术网

Java 如何在String.format';JList中是否有DefaultListModel?

Java 如何在String.format';JList中是否有DefaultListModel?,java,string,jlist,defaultlistmodel,Java,String,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 = ne

我已经在这里问过了,所以请通读一下。这个问题已经部分解决了。

现在我有另一个问题:

请先看这个例子

// 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());
我希望发生的是,所有数量变量都是对齐的,而不是基于前一个变量的间距。你知道我该怎么做吗

谢谢

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

另一个建议是,是否可以在string.format()中定义字符串的最小长度?

您只需使用

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);
  }
}
例如,这将在格式化输出中放入20个空格

因此,技巧基本上是首先扫描列表中的所有字符串,然后计算格式化模式中所需的合理数字。换句话说:首先要确定要显示的字符串的最大长度;然后计算适当的缩进,例如


编辑:有许多不同的方法可以影响格式,请参见此,或者最好研究指定所有现有格式模式的方法

正如@GhostCat所说,在格式字符串中使用宽度将解决您的问题

有关详细信息,请查看格式字符串的

然而,您试图做的事情让我想到,也许您可以使用JTable而不是JList

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

}
你必须实现类似的东西

支持列的渲染器

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;
  }
}
以及ColumnWidthProvider的一个实现,它观察内容更改的
ListModel

类ListModelAwareColumnWidthProvider实现ColumnWidthProvider{
私有类ListModelChangeAdapter实现ListDataListener{
@凌驾
添加了公共无效间隔(ListDataEvent e){
初始化列宽();
}
@凌驾
删除公共无效间隔(ListDataEvent e){
初始化列宽();
}
@凌驾
公共无效内容更改(ListDataEvent e){
初始化列宽();
}
}
私有int defaultColumnWidth=100;
私有ListModelChangeAdapter ListModelChangeAdapter=新ListModelChangeAdapter();
私有列表模型列表模型;
private java.util.List longestColumnStrings=new ArrayList();
public void setListModel(ListModel ListModel){
if(this.listModel!=null){
this.listModel.removeListDataListener(listModelChangeAdapter);
}
this.listModel=listModel;
初始化列宽();
if(this.listModel!=null){
this.listModel.addListDataListener(listModelChangeAdapter);
}
}
私有void initializeColumnWidths(){
最长的ColumnStrings.clear();
if(listModel!=null){
int size=listModel.getSize();
对于(int i=0;i=longestColumnStrings.size()){
longestColumnStrings.add(null);
}
String lastLongestColumnString=longestColumnStrings.get(columnIndex);
如果(lastLongestColumnString==null){
longestColumnStrings.set(columnIndex,columnValue);
}else if(columnValue.length()>lastLongestColumnString.length()){
longestColumnStrings.set(columnIndex,columnValue);
}
}
}
}
}
公共void setDefaultColumnWidth(int defaultColumnWidth){
this.defaultColumnWidth=defaultColumnWidth;
}
@凌驾
public int getColumnWidth(FontMetrics FontMetrics,int columnIndex){
if(columnIndex
这将导致


效果非常好!还有一件事-我可以将string1/string2向左对齐而不是向右对齐吗?不客气。A)看看我的更新B)如果你高兴的话,考虑接受我的答案……直接从教程中得到的例子。只要稍微多做一点工作,创建一个定制的
TableModel
,您就可以做更多的事情。
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);
}
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;
  }
}