JXTreeTable: как использовать ComponentProvider для установки средства визуализации для одного столбца - PullRequest
2 голосов
/ 08 февраля 2012

Я использую JXTreeTable для отображения некоторых данных, и я хочу использовать предоставленные механизмы SwingX для изменения рендерера для некоторых столбцов.

Ранее я использовал JXTable и пользовательские реализации TableCellRenderer, но это больше не работает (я вижу строки, в которых должны быть индикаторы выполнения, кнопки, ...).

Таким образом, я пытался добиться того, чего хочу, делая:

examsTable.getColumn(6).setCellRenderer(new DefaultTableRenderer(new ButtonProvider()));

Но переопределенный метод createRenderer ComponentProvider вызывается один раз (даже если в моем JXTreeTable более одной строки), и кнопка не отображается (метод содержит только return new JButton();).

Спасибо!

Редактировать> Надеялся, что ответишь на Клеопатру и, таким образом, счастлив, что сделал.

Я сделал все возможное, но каким-то образом таблица не отображается. Наверное, я что-то забыл (я новичок в Java на C ++), но это не серьезная проблема, и, вероятно, она не связана с моей основной проблемой.

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.jdesktop.swingx.JXTreeTable;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import org.jdesktop.swingx.renderer.CellContext;
import org.jdesktop.swingx.renderer.ComponentProvider;
import org.jdesktop.swingx.renderer.DefaultTableRenderer;
import org.jdesktop.swingx.treetable.AbstractTreeTableModel;

public class Test extends JFrame {
    JXTreeTable table = new JXTreeTable();
    JPanel panel = new JPanel();

    public Test() {
        setMinimumSize(new Dimension(400, 400));

        table.setEditable(false);
        table.setDragEnabled(false);
        table.setColumnSelectionAllowed(false);
        table.setHighlighters(HighlighterFactory.createAlternateStriping());
        table.setRowHeight(20);
        table.setMinimumSize(new Dimension(200, 200));

        class Series {
            public String seriesInstanceUID;
            public String patientName;
            public String patientBirthDate;
            public String securityToken;

            public Series(String seriesInstanceUID, String patientName, String patientBirthDate, String securityToken) {
                this.seriesInstanceUID = seriesInstanceUID;
                this.patientName = patientName;
                this.patientBirthDate = patientBirthDate;
                this.securityToken = securityToken;
            }
        }

        class Study {
            public List<Series> series = new ArrayList<Series>();
        }

        class Root {
            public List<Study> studies = new ArrayList<Study>();
        }

        AbstractTreeTableModel model = new AbstractTreeTableModel() {
            Root root = new Root() {
                {
                    studies.add(new Study() {
                        {
                            series.add(new Series("Series 1.1", "Mr. X", "1988-10-23", "sec-xx-1"));
                            series.add(new Series("Series 1.2", "Mr. X", "1988-10-23", "sec-xx-2"));
                            series.add(new Series("Series 1.3", "Mr. X", "1988-10-23", "sec-xx-3"));
                        }
                    });
                    studies.add(new Study() {
                        {
                            series.add(new Series("Series 2.1", "Mrs. Y", "1960-02-11", "sec-yy-1"));
                        }
                    });
                    studies.add(new Study() {
                        {
                            series.add(new Series("Series 3.1", "HAL 9000", "1975-04-21", "sec-zz-1"));
                            series.add(new Series("Series 3.2", "HAL 9000", "1975-04-21", "sec-zz-2"));
                        }
                    });
                }
            };

            @Override
            public String getColumnName(int columnIndex) {

                switch (columnIndex) {
                case 0:
                    return "Series Instance UID";

                case 1:
                    return "Patient Name";

                case 2:
                    return "Patient Birth Date";

                case 3:
                    return "View online";

                default:
                    return "";
                }
            }

            @Override
            public int getIndexOfChild(Object parent, Object child) {
                if (parent == root) {
                    return root.studies.indexOf(child);
                }

                if (parent instanceof Study) {
                    Study study = (Study) parent;

                    return study.series.indexOf(child);
                }

                return -1;
            }

            @Override
            public int getChildCount(Object parent) {
                if (parent == root) {
                    return root.studies.size();
                }

                if (parent instanceof Study) {
                    Study study = (Study) parent;

                    return study.series.size();
                }

                return 0;
            }

            @Override
            public Object getChild(Object parent, int index) {
                if (parent == root) {
                    return root.studies.get(index);
                }

                if (parent instanceof Study) {
                    Study study = (Study) parent;

                    return study.series.get(index);
                }

                return null;
            }

            @Override
            public Object getValueAt(Object node, int columnIndex) {
                if (!(node instanceof Series) && !(node instanceof Study))
                    return null;

                if (columnIndex < 0 || columnIndex >= getColumnCount())
                    return null;

                if (root == null)
                    return null;

                if (node instanceof Series) {
                    Series series = (Series) node;

                    if (columnIndex == 0)
                        return series.seriesInstanceUID;
                    else if (columnIndex == 1)
                        return series.patientName;
                    else if (columnIndex == 2)
                        return series.patientBirthDate;
                    else if (columnIndex == 3)
                        return series.securityToken;
                } else if (node instanceof Study) {
                    // Empty for now
                }

                return null;
            }

            @Override
            public int getColumnCount() {
                return 4;
            }

            @Override
            public Object getRoot() {
                return root;
            }

            public void update() {
                modelSupport.fireNewRoot();
            }
        };

        table.setTreeTableModel(model);

        table.getColumnModel().getColumn(3).setCellRenderer(new DefaultTableRenderer(new ComponentProvider<JButton>() {
            {
                rendererComponent.setHorizontalAlignment(JButton.CENTER);
            }

            @Override
            protected void format(CellContext context) {
                rendererComponent.setText(getValueAsString(context));
            }

            @Override
            protected void configureState(CellContext context) {
                rendererComponent.setHorizontalAlignment(getHorizontalAlignment());
            }

            @Override
            protected JButton createRendererComponent() {
                return new JButton("View online");
            }
        }));

        panel.add(table);
        this.setContentPane(panel);
    }

    public static void main(String[] args) {
        (new Test()).setVisible(true);
    }
}

РЕДАКТИРОВАТЬ> Я действительно заметил, что это работает. Но не так, как я хочу. Я хочу видеть реальную кнопку (теперь она выглядит немного иначе, чем остальная часть строки), знать путь к ней (индекс родительского объекта и столбца) и видеть эффекты при нажатии или наведении на нее (кнопка должна выглядеть нажатой , ...).

Как мне этого добиться?

1 Ответ

4 голосов
/ 08 февраля 2012

Используется кнопка, только в некоторых LAF ее нет: -)

Технически, причины:

  • подсветка устанавливает фон кнопки
  • визуальные элементы по умолчанию (используемые провайдером) устанавливают границу по умолчанию, возвращаемую cellContext

В комбинации кнопка не похожа на кнопку для металла (пока она неизменна, например, в Windows)

Нет удовлетворительного решения, варианты

  • не использовать чередование
  • пусть у кнопки есть свойство dont-touch-my-background, расширьте ColorHighlighter, чтобы учесть это, и используйте этот нестандартный подсветчик для чередования (есть пример в тестовом пакете)
...