У меня странная проблема с использованием класса Java Box.Я использую JDK 1.6.21.
У меня есть собственный класс DropDownPanel, который наследуется от JPanel.Назначение DropDownPanel - скрыть и показать на нем другой компонент.Если вы щелкнете по заголовку DropDownPanel, размещенный компонент (теперь это JTable) станет видимым или невидимым.Он работает нормально сам по себе.
Я помещаю эти DropDownPanels в вертикальный класс Box, затем Box в JScrollPane.Все X и Y выравнивания DropDownPanels установлены в 0, поэтому в Box не должно быть неправильного выравнивания.
Поэтому у меня есть следующее логическое дерево: JTable в DropDownPanel в Box в JScrollPane.
Проблема заключается в том, что если в Box содержатся только DropDownPanels, то при добавлении и удалении строк в / из таблицы я наблюдаю следующее:
- JScrollPaneотображается правильно после добавления большого количества строк, что означает, что размеры и макеты правильно рассчитаны.Полоса прокрутки исчезает после удаления достаточного количества строк, поэтому таблица соответствует JFrame.
- строки JTable обновляются должным образом, т.е. я вижу правильное количество строк.
- Но JTable, похоже, никогда не изменяет свой размер.Добавленные строки невидимы, удаленные строки исчезают, но фон таблицы (с белым цветом) все еще виден.Я ожидаю, что JTable будет настолько компактным, насколько это возможно.Это не.
Теперь приходит странная вещь.Если я добавлю пустой JPanel в качестве последнего компонента в Box, все будет работать так, как я ожидал.JTable всегда настолько компактен, насколько это возможно.При удалении строк размер таблицы уменьшается, и она перерисовывается правильно.Однако без последней JPanel JTable изменяет размер себя (я знаю это по виду полосы прокрутки), но никогда не будет компактным.Изменение размера JFrame не помогает.Единственное, что вызывает правильное поведение - это скрыть и показать JTable через DropDownPanel.Затем он отображается правильно.
Поскольку DropDownPanel - это расширенная JPanel, а добавленная JPanel - просто JPanel по умолчанию, я понятия не имею, почему она не работает без дополнительной JPanel в конце Box.
Наконец, вот код.Обратите внимание на закомментированную строку.Если это не комментируется, таблица ведет себя должным образом (лучше начать с его настройки), если нет, то это не так.Вам нужно нажать на заголовок DropDownPanel, чтобы показать таблицу вообще.Затем вы можете добавить много строк, чтобы увидеть, что полоса прокрутки появляется после того, как количество строк не вписывается в JFrame, и она исчезает правильно, когда они это делают.Тем не менее, JTable не так компактен, как должно быть:
package tabletest;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class TableTest {
public class DropDownPanel extends JPanel implements ActionListener, MouseListener {
private static final long serialVersionUID = 1L;
protected JPanel header = new JPanel();
protected JLabel titleLabel;
protected Component content;
protected boolean isExpanded = true;
public DropDownPanel(String title, Component c) {
content = c;
setLayout(new BorderLayout());
titleLabel = new JLabel(title);
header.setLayout(new BorderLayout());
header.add(titleLabel, BorderLayout.WEST);
add(header, BorderLayout.NORTH);
add(content, BorderLayout.CENTER);
header.addMouseListener(this);
titleLabel.addMouseListener(this);
apply();
}
public void toggleExpanded() {
isExpanded = !isExpanded;
apply();
}
protected void apply() {
titleLabel.setText("Drop state: " + (isExpanded ? "Expanded" : "Collapsed"));
content.setVisible(isExpanded);
setMaximumSize(new Dimension(1024, getPreferredSize().height));
invalidate();
}
@Override
public void actionPerformed(ActionEvent e) {
toggleExpanded();
}
@Override
public void mouseClicked(MouseEvent e) {
toggleExpanded();
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
}
public void run() {
JFrame f = new JFrame();
JPanel p = new JPanel();
Box box = Box.createVerticalBox();
p.setLayout(new BorderLayout());
final JTable table = new JTable();
table.setFocusable(false);
table.setFillsViewportHeight(true);
table.setBackground(Color.white);
DefaultTableModel m = (DefaultTableModel) table.getModel();
m.addColumn("Color");
JButton b = new JButton("Remove row");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
((DefaultTableModel) table.getModel()).removeRow(0);
table.invalidate();
}
});
JButton b2 = new JButton("Add row");
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
((DefaultTableModel) table.getModel()).addRow(new Object[] { "Red" });
table.invalidate();
}
});
DropDownPanel ddp = new DropDownPanel("Title", table);
ddp.setAlignmentX(0);
ddp.setAlignmentY(0);
box.add(ddp);
// ---------------------------------------------------------------
// Without this line, it does not work; with this line, it is fine
//box.add(new JPanel());
// ---------------------------------------------------------------
JLabel lll = new JLabel("End of Story");
lll.setAlignmentX(0);
lll.setAlignmentY(0);
box.add(lll);
p.add(new JScrollPane(box), BorderLayout.CENTER);
p.add(b, BorderLayout.SOUTH);
p.add(b2, BorderLayout.NORTH);
f.add(p);
((DefaultTableModel) table.getModel()).addRow(new Object[] { "Red" });
((DefaultTableModel) table.getModel()).addRow(new Object[] { "Red" });
((DefaultTableModel) table.getModel()).addRow(new Object[] { "Red" });
((DefaultTableModel) table.getModel()).addRow(new Object[] { "Red" });
((DefaultTableModel) table.getModel()).addRow(new Object[] { "Red" });
f.pack();
f.setVisible(true);
f.setSize(new Dimension(600, 400));
}
public static void main(String[] args) {
new TableTest().run();
}
}
Сейчас я потею кровью, поэтому любая помощь приветствуется:)