无法在单元格中对齐左侧的文本和右侧的图标

问题描述 投票:0回答:1

我正在尝试实现一件非常简单的事情,我尝试了不同的选项,但似乎都不起作用。 我有一个简单的 JTable,在列中我使用 JLabel 来显示文本和图标。 我只想让文本位于单元格的左侧,图标位于右侧。

如果我使用这个片段:

label.setHorizontalTextPosition(SwingConstants.LEFT);
label.setHorizontalAlignment(SwingConstants.RIGHT);

我只是按照我想要的方式获得右侧的图标,但文本立即位于图标的左侧。 所以我正在设置图标和文本间隙。

我是这样设置的:

int width = getWidth();
label.setSize(width, getHeight());
AffineTransform affinetransform = new AffineTransform();     
FontRenderContext frc = new FontRenderContext(affinetransform,true,true);     
int textwidth = (int)(label.getFont().getStringBounds(label.getText(), frc).getWidth());

label.setIconTextGap(width - textwidth - label.getIcon().getIconWidth());

调试它,它似乎做了应该做的事情,但我得到了这个结果:

我尝试添加一点容差(减去文本宽度2倍),这就是结果:

顺便说一下,如果我再次缩小间隙,就会显示文本,但是当然,我没有按照我想要的方式对齐内容。

我只是想实现一个类似于编辑器组件的渲染器,它是一个组合框,如下所示:

这对我来说不是优先任务,但我真的很想了解如何管理它。

编辑:

我还尝试使用容器(也是 JPanel)来添加 2 个 JLabels 并按照 @MadProgrammer 的建议更好地管理文本和图标,但是使用单元格下面的代码是空的,只有背景可见

public java.awt.Component getTreeTableCellRendererComponent(TreeTable treeTable, Object value, boolean selected, boolean hasFocus, int row, int column) {
    Container container = new Container();
    JLabel label = new JLabel();
    JLabel icon = new JLabel();
    label.setText("XXX");
    icon.setIcon(myIcon);
    if (row % 2 == 0) {
        container.setBackground(new java.awt.Color(220, 245, 230));
    }
    else {
        container.setBackground(new java.awt.Color(240, 255, 240));
    }

    label.repaint();
    icon.repaint();
                
    container.add(label, BorderLayout.WEST);
    container.add(icon, BorderLayout.CENTER);                       
    container.revalidate();
    container.doLayout();
    container.setVisible(true);     
    container.repaint();
                
    return container;
}
                

上面的代码运行时不会抛出异常..

java swing jtable tablecellrenderer
1个回答
2
投票

有这段旧代码演示了使用面板作为渲染器的概念。前 3 个字符将显示在左侧,其余字符将显示在右侧:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableRendererPanel
{
    static class MultiLabelRenderer implements TableCellRenderer
    {
        private JPanel panel;
        private JLabel red;
        private JLabel blue;

    public MultiLabelRenderer()
    {
        red = new JLabel();
        red.setForeground(Color.RED);
        blue = new JLabel();
        blue.setForeground(Color.BLUE);

        panel = new JPanel();
        panel.setLayout( new BoxLayout(panel, BoxLayout.X_AXIS) );
        panel.add(red);
        panel.add(Box.createHorizontalGlue());
        panel.add(blue);
    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, final int row, final int column)
    {
        panel.setBackground( isSelected ? table.getSelectionBackground() : table.getBackground() );

        if (value == null || value.toString().isEmpty())
        {
            red.setText(" ");
            blue.setText(" ");
            return panel;
        }

        //  Set the text for the two labels

        String text = value.toString();
        red.setText( text.substring(0, 3) );
        blue.setText( text.substring(3) );

        return panel;
    }
}

public static void createAndShowGUI()

    {
        JTable table = new JTable(5, 3);
      table.setPreferredScrollableViewportSize(table.getPreferredSize());
        table.getColumnModel().getColumn(0).setCellRenderer( new MultiLabelRenderer());
        JScrollPane scrollPane = new JScrollPane( table );

        table.setValueAt("abcde", 0, 0);
        table.setValueAt("123456789", 1, 0);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( scrollPane );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

    public static void main(String[] args) throws Exception
    {
        java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.