public class Test extends JFrame{
Test(){
JTable head = new JTable(1, 30);
head.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
head.setTableHeader(null);
JTable fixed = new JTable(30, 1);
fixed.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
fixed.setTableHeader(null);
JTable table = new JTable(30, 30);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setTableHeader(null);
JScrollPane scroll = new JScrollPane(table);
JViewport viewportHead = new JViewport();
viewportHead.setView(head);
viewportHead.setPreferredSize(head.getPreferredSize());
scroll.setColumnHeader(viewportHead);
JViewport viewportFixed = new JViewport();
viewportFixed.setView(fixed);
viewportFixed.setPreferredSize(fixed.getPreferredSize());
scroll.setRowHeader(viewportFixed);
Container cp = getContentPane();
cp.add(scroll);
}
public static void main(String[] args){
Test frame = new Test();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
}
По идее должен имитировать фирсированный столбец слева и строку сверху. Но вот строку сверху он вообще не выводит. Я подозреваю, что мешает скрытый Header от table, но как от него избавиться — неясно.
Здравствуйте, Денис Рубцов, Вы писали:
ДР>Все, я сдаюсь. Вот такой код:
<skipped> ДР>По идее должен имитировать фирсированный столбец слева и строку сверху. Но вот строку сверху он вообще не выводит. Я подозреваю, что мешает скрытый Header от table, но как от него избавиться — неясно.
А чем тебя тот пример не удовлетворил, на который тебе ссылку дали?
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, Денис Рубцов, Вы писали:
ДР>>Все, я сдаюсь. Вот такой код: B><skipped> ДР>>По идее должен имитировать фирсированный столбец слева и строку сверху. Но вот строку сверху он вообще не выводит. Я подозреваю, что мешает скрытый Header от table, но как от него избавиться — неясно.
B>А чем тебя тот пример не удовлетворил, на который тебе ссылку дали?
Тем, что там автор, видимо, столкнувшись с этой же проблемой, сделал фиксированную шапку внизу, под основной таблицей. А сверху у него, как и у меня, не получилось. Я, в принципе, могу извернуться, перегрузить рендерер для head и нарисовать вообще что хочу, но мне интересно, почему именно этот Test не работает! По-логике ведь должен!
Хмм, а ты "положи" таблицу скажем в JPanel и уже JPanel "ложи" в JScrollPane
Здравствуйте, Денис Рубцов, Вы писали:
ДР>Здравствуйте, Blazkowicz, Вы писали:
B>>Здравствуйте, Денис Рубцов, Вы писали:
ДР>>>Все, я сдаюсь. Вот такой код: B>><skipped> ДР>>>По идее должен имитировать фирсированный столбец слева и строку сверху. Но вот строку сверху он вообще не выводит. Я подозреваю, что мешает скрытый Header от table, но как от него избавиться — неясно.
B>>А чем тебя тот пример не удовлетворил, на который тебе ссылку дали?
ДР>Тем, что там автор, видимо, столкнувшись с этой же проблемой, сделал фиксированную шапку внизу, под основной таблицей. А сверху у него, как и у меня, не получилось. Я, в принципе, могу извернуться, перегрузить рендерер для head и нарисовать вообще что хочу, но мне интересно, почему именно этот Test не работает! По-логике ведь должен!
A>Хмм, а ты "положи" таблицу скажем в JPanel и уже JPanel "ложи" в JScrollPane
Мдя... заработало. А в чем прикол? Почему они не "живут" на одной панели?
Здравствуйте, Денис Рубцов, Вы писали:
ДР>Здравствуйте, Alekseymir, Вы писали:
A>>Хмм, а ты "положи" таблицу скажем в JPanel и уже JPanel "ложи" в JScrollPane ДР>Мдя... заработало. А в чем прикол? Почему они не "живут" на одной панели?
ДР>
и понятия не имею — JTable странный класс, о нем легенды можно слогать ...
интересно конечно, но щас времени нима — а так загляни в исходнички, глянь на баг-параде, поделишься потом, нам тоже интересно..
Здравствуйте, Денис Рубцов, Вы писали:
ДР>Здравствуйте, Alekseymir, Вы писали:
A>>Хмм, а ты "положи" таблицу скажем в JPanel и уже JPanel "ложи" в JScrollPane ДР>Мдя... заработало. А в чем прикол? Почему они не "живут" на одной панели?
прикол в реализации метода JTable.configureEnclosingScrollPane();
он вызывается при реализации таблицы addNotify() (то есть когда она становится видимой).
И вот ты в конструкторе задаешь для scrollpane rowHeader
scroll.setRowHeader(viewportFixed);
а эта сволочь (таблица тобишь) при показе пытается проанализировать свое ближайшее окружение. И если она обнаруживает, что является дочерним компонентом для какого-нибудь JScrollPane и при этом является view для viewport этого JScrollPane — переустанавливает заданный ранее rowHeader в TableHeader. Ну а так как ты до это в таблице установил TableHeader в null — но на месте заголовка таблица ничего и не показывается.
protected void configureEnclosingScrollPane() {
Container p = getParent();
if (p instanceof JViewport) {
Container gp = p.getParent();
if (gp instanceof JScrollPane) {
JScrollPane scrollPane = (JScrollPane)gp;
JViewport viewport = scrollPane.getViewport();
if (viewport == null || viewport.getView() != this) {
return;
}
scrollPane.setColumnHeaderView(getTableHeader()); //вот тут и теряется наш заголовок.
Border border = scrollPane.getBorder();
if (border == null || border instanceof UIResource) {
scrollPane.setBorder(UIManager.getBorder("Table.scrollPaneBorder"));
}
}
}
}
Воркараунд с JPanel не дает таблице возможности определить, что она находится внутри JScrollPane.
Однако в этом случае для JScrollPane не установится рамка Table.scrollPaneBorder
Впринципе можно подлечить JScrollPane, подкрутив метод configureEnclosingScrollPane
JTable columnHeader = new JTable(1, 30);
columnHeader.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
columnHeader.setTableHeader(null);
JTable rowHeader = new JTable(30, 1);
rowHeader.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
rowHeader.setTableHeader(null);
final JViewport viewportColumn = new JViewport();
viewportColumn.setView(columnHeader);
viewportColumn.setPreferredSize(columnHeader.getPreferredSize());
final JViewport viewportRow = new JViewport();
viewportRow.setView(rowHeader);
viewportRow.setPreferredSize(rowHeader.getPreferredSize());
final JScrollPane scroll = new JScrollPane();
JTable table = new JTable(30, 30) {
protected void configureEnclosingScrollPane() {
super.configureEnclosingScrollPane();
scroll.setColumnHeader(viewportColumn); //установим ColumnHeader после того как у нас там что-то поменяется
scroll.setRowHeader(viewportRow); //установим RowHeader после того как у нас там что-то поменяется
}
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setTableHeader(null);
scroll.getViewport().setView(table);
А вообще это баг и его надо постить (если этого еще не сделали).