【问题标题】:Format text into JTable cell将文本格式化为 JTable 单元格
【发布时间】:2013-09-13 22:25:06
【问题描述】:

我想以特定方式处理插入到 JTable 单元格中的文本。事实上,现在如果我写入一个单元格,文本将全部在同一行,而我希望看到它分两行。

也许我会用图形描述更清楚。看,我想要第二个:

我的表代码在这里:

public class TablePanel extends JPanel
{
private JTable table;
public Tabella()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
table = new JTable(new MyTableModel());
table.setFillsViewportHeight(true);     
table.setPreferredScrollableViewportSize(new Dimension(500, 100));
JScrollPane jps = new JScrollPane(table);
add(jps);
add(new JScrollPane(table));
table.setCellSelectionEnabled(true);
table.setRowHeight(30);
TableColumn tcol;
    for (int i=0; i<table.getColumnCount(); i++)
    {
        tcol = table.getColumnModel().getColumn(i);
        tcol.setCellRenderer(new CustomTableCellRenderer());
    }

table.addMouseListener(
    new MouseAdapter(){
    public void mouseClicked(MouseEvent e) {
        int row = table.rowAtPoint(new Point(e.getX(), e.getY()));
        int col = table.columnAtPoint(new Point(e.getX(), e.getY()));

        if (col>0) {
        if (e.getClickCount() > 1) {
        if (row == 5 | row == 6) 
            {
                JOptionPane.showMessageDialog(null, "Impossible to set lesson.");

                return;
            }
        else {
            table.getColumnName(col);
            String day = table.getColumnName(col);
            String hour = (String) table.getValueAt(row, 0);
            InsertLesson cell = new InsertLesson(day, hour);
            cel.setVisible(true);

             }
            }
          }
        }
}
);
}
private class MyTableModel extends AbstractTableModel {
private String[] columns = {"","Monday","Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
private String[][] data = {{"8:30 - 9:30","","","","","",""},
    {"9:30 - 10:30","","","","","",""},
    {"10:30 - 11:30","","","","","",""},
    {"11:30 - 12:30","","","","","",""},
    {"12:30 - 13:30","","","","","",""},
    {"13:30 - 14:30","","","","","",""},
    {"14:30 - 15:30","","","","","",""},
    {"15:30 - 16:30","","","","","",""},
    {"16:30 - 17:30","","","","","",""}};

public int getColumnCount() {
    return columns.length;
}

public int getRowCount() {
    return data.length;
}

public String getColumnName(int col) {
    return columns[col];
}

public Object getValueAt(int row, int col) {
    return data[row][col];
}
}
public class CustomTableCellRenderer extends DefaultTableCellRenderer{
  public Component getTableCellRendererComponent (JTable table, 
Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
  Component cell = super.getTableCellRendererComponent(
   table, obj, isSelected, hasFocus, row, column);
  if (isSelected) {
  cell.setBackground(Color.lightGray);
  } 
  else {
  if (row % 2 == 0) {
  cell.setBackground(new Color (245,245,250));
  }
  else {
  cell.setBackground(new Color(250,250,240));
  }
  }

  return cell;
  }
  }
}   

感谢 Kiheru 用户,我们找到了解决方案:我们必须:

1) 将插入单元格的字符串的格式居中;

2) 将单元格本身的“空间”居中;

我们可以通过以下方式执行这些操作:

1) 在要插入单元格的字符串中插入html居中文本代码(自动识别html代码);

2) 使用命令setHorizontalAlignment(JLabel.CENTER); 将单元格本身居中。

这个问题可能对每个有这个问题的人都有用。

【问题讨论】:

    标签: java swing tablecellrenderer


    【解决方案1】:

    使用 html 作为标签文本可以有多行标签(DefaultTableCellRenderer 扩展 JLabel):

    "<html>Math,<br>Class1</html>"
    

    请注意,您可能需要按照here 的说明调整行高。

    更新: 除了换行之外,还需要将标签文本居中。

    这需要在单元格渲染器上调用setHorizontalAlignment(JLabel.CENTER) 以使文本块居中。此外,文本行需要相对于彼此居中,因此 html 代码最终会像这样(实际代码具有更多格式):

    <html><div style="text-align:center">Math,<br>Class1</div></html>
    

    【讨论】:

    • 我认为我会在任何单元格中插入一个 JLabel,不是吗?
    • @Bernheart 不,不要那样做。 JTable 旨在重用渲染器,并且您拥有的内容非常适合 html。生成 html 的正确位置取决于您的应用程序设计,但可以(至少)1 将数据作为 html 插入您的模型(简单,但并不总是合适),或者 2:在您的 getTableCellRendererComponent()从“Math, Class1”字符串生成 html(它是该方法中的参数 obj)。
    • @Bernheart 渲染器与普通组件不同,它用于将结果“标记”到表格上。所以,只有一个渲染器实例在使用中......
    • @Bernheart 您不需要扩展它,因为它已经可以了。您需要做的就是将内容格式化为 html。如需快速演示,请尝试在表格模型中插入“Math,
      Class1”。这应该会产生一个两行单元格,而您的实际代码根本没有变化。
    • @Bernheart 给猫剥皮的方法不止一种,而且我不是 html 专家,但我认为"&lt;html&gt;&lt;div style=\"text-align:center;font-weight:bold\"&gt;Math,&lt;br&gt;Class1&lt;/div&gt;&lt;/html&gt;" 会起作用。不客气:-)
    【解决方案2】:

    我不确定我是从哪里得到这个的,但我通过 TextAreaRenderer 完成了这个

    public class TextAreaRenderer extends JTextArea implements TableCellRenderer {
    
        private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
        /** map from table to map of rows to map of column heights */
        private final Map cellSizes = new HashMap();
    
    
        public TextAreaRenderer() {
            setLineWrap(true);
            setWrapStyleWord(true);
        }
    
        public Component getTableCellRendererComponent(
                JTable table, Object obj, boolean isSelected,
                boolean hasFocus, int row, int column) {
    
            // set the colours, etc. using the standard for that platform
            adaptee.getTableCellRendererComponent(table, obj,
                    isSelected, hasFocus, row, column);
            setForeground(adaptee.getForeground());
            setBackground(adaptee.getBackground());
            setBorder(adaptee.getBorder());
            setFont(adaptee.getFont());
            setText(adaptee.getText());
    
    
            // This line was very important to get it working with JDK1.4
            TableColumnModel columnModel = table.getColumnModel();
            setSize(columnModel.getColumn(column).getWidth(), 100000);
            int height_wanted = (int) getPreferredSize().getHeight();
            addSize(table, row, column, height_wanted);
            height_wanted = findTotalMaximumRowSize(table, row);
            if (height_wanted != table.getRowHeight(row)) {
                table.setRowHeight(row, height_wanted);
            }
            return this;
        }
    
        @SuppressWarnings("unchecked")
        private void addSize(JTable table, int row, int column, int height) {
            Map rows = (Map) cellSizes.get(table);
            if (rows == null) {
                cellSizes.put(table, rows = new HashMap());
            }
            Map rowheights = (Map) rows.get(new Integer(row));
            if (rowheights == null) {
                rows.put(new Integer(row), rowheights = new HashMap());
            }
            rowheights.put(new Integer(column), new Integer(height));
        }
    
        /**
         * Look through all columns and get the renderer.  If it is
         * also a TextAreaRenderer, we look at the maximum height in
         * its hash table for this row.
         */
        private int findTotalMaximumRowSize(JTable table, int row) {
            int maximum_height = 0;
            Enumeration columns = table.getColumnModel().getColumns();
            while (columns.hasMoreElements()) {
                TableColumn tc = (TableColumn) columns.nextElement();
                TableCellRenderer cellRenderer = tc.getCellRenderer();
                if (cellRenderer instanceof TextAreaRenderer) {
                    TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
                    maximum_height = Math.max(maximum_height,
                            tar.findMaximumRowSize(table, row));
                }
            }
            return maximum_height;
        }
    
        private int findMaximumRowSize(JTable table, int row) {
            Map rows = (Map) cellSizes.get(table);
            if (rows == null) {
                return 0;
            }
            Map rowheights = (Map) rows.get(new Integer(row));
            if (rowheights == null) {
                return 0;
            }
            int maximum_height = 0;
            for (Iterator it = rowheights.entrySet().iterator();
                    it.hasNext();) {
                Map.Entry entry = (Map.Entry) it.next();
                int cellHeight = ((Integer) entry.getValue()).intValue();
                maximum_height = Math.max(maximum_height, cellHeight);
            }
            return maximum_height;
        }
    }
    

    然后你就这样使用它(我的用于“注释”列):

    table.getColumn("Notes").setCellRenderer(new TextAreaRenderer());
    

    每当出现\n 时,它都会自动换行。我还使用它来满足“合并单元格”的需求(您只需要有条不紊地处理换行符)。它对于合并单元格的要求并不完美,但它可以完成工作。

    【讨论】:

      猜你喜欢
      • 2016-06-26
      • 2012-11-02
      • 2013-01-09
      • 2019-11-26
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多