JTable внутри JLayeredPane внутри JScrollPane — как заставить его работать?

Я хочу поместить объекты, выходящие из JTable, поверх него, поэтому использование JLayeredPane кажется естественным. Однако заставить это правильно рисовать, правильно делать заголовки и т. д. очень сложно. Как мне это сделать, чтобы:

  • Заголовки строк появляются и совпадают при прокрутке
  • Заголовки столбцов появляются и совпадают при прокрутке
  • Стол прокрашивается нормально
  • изменение размера ничего не испортит

Обратите внимание, что поскольку JDesktopPane расширяет JLayeredPane, ответы на этот вопрос также позволяют вам иметь JTable (или любой другой компонент) за JDesktopPane.


person Nick Fortescue    schedule 12.07.2011    source источник
comment
Зачем вам такая сложная вложенность?   -  person mre    schedule 12.07.2011
comment
Я хочу, чтобы ячейки в JTable могли расширяться, чтобы отображать больше информации, и чтобы эти расширения оставались с JTable при его прокрутке. В связанных вопросах кто-то еще хотел иметь возможность блокировать анимацию поверх JTable. Когда я гуглил, другие люди хотели использовать эту технику, чтобы заморозить столбцы, но мне это показалось немного хакерским, возможно, есть лучший способ сделать это.   -  person Nick Fortescue    schedule 12.07.2011


Ответы (1)


Похожие, но не идентичные вопросы, которые помогают: Java - это можно поместить JLayeredPane внутри JScrollPane? и Как отобразить анимация в ячейке JTable и дизайн Swing GUI с JScrollPane и JLayeredPane< /а>.

Чтобы сделать это правильно, необходимо рассмотреть три отдельных вопроса: изменение размера, заголовков и пользовательского интерфейса.

Размеры

Для правильной прокрутки и рисования JScrollPane необходимо знать размер и предпочтительный размер компонента внутри него, в данном случае JLayeredPane. Но вы хотите, чтобы размер устанавливался таблицей, так как другие Component будут плавать поверх таблицы. В этом случае самый простой способ — сделать свойства, связанные с размером делегата JLayeredPane, для JTable следующим образом.

final JTable table = new JTable();
JLayeredPane layers = new JLayeredPane() {
  @Override
  public Dimension getPreferredSize() {
    return table.getPreferredSize();
  }

  @Override
  public void setSize(int width, int height) {
    super.setSize(width, height);
    table.setSize(width, height);
  }

  @Override
  public void setSize(Dimension d) {
    super.setSize(d);
    table.setSize(d);
  }
};
// NB you must use new Integer() - the int version is a different method
layers.add(label, new Integer(JLayeredPane.PALETTE_LAYER), 0);
JScrollPane scrolling = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrolling.setViewportView(layers);

Если вы не хотите, чтобы JTable определяло размер JLayeredPane, тогда его нужно определить каким-то другим способом, как и размер таблицы. Оба потребуют явного вызова setPreferredSize() и setSize().

Заголовки

Поскольку JTable больше не является окном просмотра, вам нужно будет связать заголовки самостоятельно. Будет работать следующий код:

scrolling.setColumnHeaderView(table.getTableHeader());
scrolling.setRowHeaderView(rowHeader);

UI

Также обратите внимание, что JTable делает какой-то неприятный код в configureEnclosingScrollPane() и configureEnclosingScrollPaneUI(). Если вы хотите, чтобы изменения стиля пользовательского интерфейса работали правильно, вам придется переопределить эти методы, но я еще не придумал, как это сделать.

person Nick Fortescue    schedule 12.07.2011