Как гомогенизировать размер компонентов в JTable? - PullRequest
1 голос
/ 17 октября 2019

У меня есть JTable с двумя столбцами. Первый содержит пользовательский компонент (гистограмму) с тремя компонентами внутри: JLabel lMinLabel, Graph lGraph и JLabel lMaxLabel. Вот что у меня есть:

enter image description here

Вот что я хочу: enter image description here

Значенияметка может иметь разные размеры в разных строках, которые изменяют размер гистограммы. Я хочу, чтобы гистограмма имела одинаковый размер для всех строк JTable.

Я попытался разместить метку на панелях и установить минимальный размер для этих панелей (с фиксированным значением).

Вот мой код:

package test;

import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class JTableExample extends JFrame {

    public JTableExample() {
        super("JTable Example");

        DefaultTableModel dm = new DefaultTableModel();
        dm.setDataVector(new Object[][] { { new BarGraph(0, 10, 25, 27, 75, 90,100), "foo" },
            { new BarGraph(100, 1000, 2500, 5600, 7500, 9000,10000), "bar" } },
                new Object[] { "Graph", "String" });

        JTable table = new JTable(dm);
        table.getColumn("Graph").setCellRenderer(new Renderer());
        JScrollPane scroll = new JScrollPane(table);
        getContentPane().add(scroll);
        setSize(800, 100);
        setVisible(true);
    }

    public static void main(String[] args) {
        JTableExample frame = new JTableExample();
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

class Renderer implements TableCellRenderer {
    public Renderer() {}
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column) {
        return (Component) value;
    }
}

Класс гистограммы, в котором я пытаюсь установить стандартный размер:

package test;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class BarGraph extends JComponent {


    private final double preWarningMax;
    private final double preWarningMin;
    private final double valueMax;
    private final double valueMin;
    private final double warningMax;
    private final double warningMin;
    private double value;

    public BarGraph(double pValueMin, double pWarningMin, double pPreWarningMin, double pValue, double pPreWarningMax,
            double pWarningMax, double pValueMax) {
        super();
        valueMin = pValueMin;
        warningMin = pWarningMin;
        preWarningMin = pPreWarningMin;
        value = pValue;
        preWarningMax = pPreWarningMin;
        warningMax = pWarningMax;
        valueMax = pValueMax;
        this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

        JPanel lMinPanel = new JPanel();
        JLabel lMinValue = new JLabel(Double.toString(valueMin));
        lMinPanel.add(lMinValue);

        Graph lGraph = new Graph();

        JPanel lMaxPanel = new JPanel();
        JLabel lMaxValue = new JLabel(Double.toString(valueMax));
        lMaxPanel.add(lMaxValue);

        add(lMinPanel);
        add(lGraph);
        add(lMaxPanel);

        lMinPanel.setMinimumSize(new Dimension(15, 5));
        lMaxPanel.setMinimumSize(new Dimension(15, 5));
    }

    private class Graph extends JComponent {

        @Override
        protected void paintComponent(Graphics pGraphics) {
            ...
        }
    }
}

Каков наилучший способ гомогенизации размера гистограммы между строками JTable?

1 Ответ

2 голосов
/ 17 октября 2019
JPanel lMinPanel = new JPanel();
JLabel lMinValue = new JLabel(Double.toString(valueMin));
lMinPanel.add(lMinValue);

Почему вы создаете дополнительную панель для каждого JLabel?

Обратите внимание, как текст находится ниже верхней части ячейки. Это связано с тем, что по умолчанию FlowLayout панели добавляет 5 пикселей вокруг всех краев панели.

Избавьтесь от панели и просто добавьте JLabel непосредственно на панель с помощью BoxLayout.

Класс гистограммы, где я пытаюсь установить стандартный размер:

    lMinPanel.setMinimumSize(new Dimension(15, 5));
    lMaxPanel.setMinimumSize(new Dimension(15, 5));

Проблема в том, что BoxLayout учитывает «максимальный» размер. Таким образом, все компоненты будут расти, чтобы заполнить доступное пространство.

Вместо этого, я думаю, вы хотите установить максимальный размер. Поэтому, используя мое первое предложение, базовый код должен выглядеть примерно так:

lMinValue.setMaximumSize( new Dimension(50, lminValue.getPreferredSize().height) );

Вы также должны установить это для lMaxValue.

Затем вы добавляете lMinValue / lMaxValue к компоненту.

Вы бы оставили максимальный размер панели диаграммы в покое, поэтому она должна увеличиваться и занимать все пространство после того, как 100 пикселей были выделены двум меткам.

Обратите внимание, это предполагает, что максимальный размер гистограммы больше, чем его предпочтительный размер.

...