Итак, у меня есть пользовательский JPanel, который я использую несколько раз для заполнения панели-оболочки внутри JScrollPane.Количество пользовательских элементов JPanel, которые я использую, зависит от размера списка.Проблема, с которой я сталкиваюсь, состоит в том, что часть моего Custom JPanel имеет еще одну невидимую JPanel, которая расширяется, когда я нажимаю на ее родителя.Поведение, которое я пытаюсь имитировать, это поведение аккордеонного элемента пользовательского интерфейса.До того, как я участвовал в этом проекте, я был в первую очередь webdev, и хотя я много работал с Java, я все еще относительно новичок в Swing.
Вот пример поведения - панель прокрутки со всеми элементамизакрыто.(прости меня за быстрые комментарии по окраске. Я попытался подчеркнуть то, что вижу неправильно).
![https://i.stack.imgur.com/Wk90N.png](https://i.stack.imgur.com/Wk90N.png)
Далее приведено изображениеПервый элемент расширен - что неожиданно расширяет все остальные элементы.
![https://i.stack.imgur.com/e9n3t.png](https://i.stack.imgur.com/e9n3t.png)
Следует отметить, что я нацеливаюсь только на первую панель и настраиваю видимость, но при этом длина всех остальных повторяющихся панелей увеличивается, но, очевидно, компоненты внутри остаются невидимыми.
Наконец, вот мой последний желаемый результат:
![https://i.stack.imgur.com/GvSjn.png](https://i.stack.imgur.com/GvSjn.png)
Есть ли какой-тоограничение в JScrollPane, которое изменяет размеры дочерних компонентов JPanel, чтобы всегда сохранять одинаковую высоту?Кажется, я не могу найти способ обойти это, и я играл со всевозможными обертками и макетами, но все безрезультатно.
Пожалуйста, дайте мне знать, если кто-то хочет увидеть фрагменты кода, но ониПридется сильно отредактировать и удалить из-за особенностей проекта.
Спасибо, Марек
PS: да, я обязательно должен использовать Swing.
РедактироватьВот статичная, быстрая и грязная, урезанная реализация моего кода, предложенная Родди из «Замороженного горошка»
ExampleScrollPane:
public class ExampleSrollPane extends JPanel {
private static ExampleSrollPane instance = null;
private JScrollPane contentScrollPanel = new JScrollPane();
private Vector<ExamplePanel> exPanels;
private JPanel wrapPanel = new JPanel();
public ExampleSrollPane() {
super();
this.setLayout(new BorderLayout());
this.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED, Color.white,
Color.white, new Color(115, 114, 105), new Color(165, 163, 151)));
exPanels = new Vector<ExamplePanel>();
init();
}
private void init() {
contentScrollPanel.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
contentScrollPanel.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
contentScrollPanel.setBorder(new CompoundBorder(new EmptyBorder(5, 5, 5, 5), new SoftBevelBorder(BevelBorder.LOWERED)));
this.add(contentScrollPanel, BorderLayout.CENTER);
initPanels();
}
public void initPanels() {
int numUnits = 15;
// Init one empty panel at least
if (numUnits == 0) numUnits = 15;
wrapPanel.setLayout(new GridLayout(numUnits, 1));
for (int i = 0; i < numUnits; i++) {
ExamplePanel exPan = new ExamplePanel(i);
exPanels.add(i, exPan);
wrapPanel.add(exPan);
}
contentScrollPanel.setPreferredSize(new Dimension(575, 100));
contentScrollPanel.getViewport().add(wrapPanel);
}
/**
* Method: viewPanel()
*
*/
private static void viewPanel() {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setLocationRelativeTo(null);
frame.add(getInstance());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setSize(new Dimension(600, 350));
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
public static ExampleSrollPane getInstance() {
if (instance == null) {
instance = new ExampleSrollPane();
}
return instance;
}
/**
* The main method.
*
* @param args the arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
viewPanel();
}
});
}
}
Это здесьв методе showHideTable, который создает проблему.
ExamplePanel (мой пользовательский JPanel):
public class ExamplePanel extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private static final Border STAT_BORDER = BorderFactory.createBevelBorder(BevelBorder.LOWERED, Color.white,
Color.white, new Color(115, 114, 105), new Color(165, 163, 151));
public static final EmptyBorder PAD_BORDER = new EmptyBorder(10, 10, 10, 10);
public int indx;
private JLabel unitLabel;
private JLabel statLabel;
private JLabel invLabel;
private JLabel targetLabel;
private JLabel timeLabel;
// Custom BasicArrowButton to expand/hide the "table"
private UnitToggleButton unitToggleButton;
// The expandable JPanel
public ExpanableTable elementTable;
private String id;
private String unitStatusString;
private String invStatusString;
private String targetString;
private String timeString;
public Color componentColor;
private JPanel topPanel = new JPanel();
public JPanel tablePanel = new JPanel();
public ExamplePanel(int index) {
super();
this.indx = index;
id = "Unit # 00000";
id = "Unit #00000";
unitStatusString = "PENDING";
invStatusString = "PENDING";
elementTable = new ExpanableTable();
targetString = "AZ501";
timeString = "11:18:27";
componentColor = this.getBackground();
init();
}
private void init() {
topPanel.setLayout(new GridBagLayout());
topPanel.setBorder(PAD_BORDER);
unitLabel = new JLabel(id); // TODO unit.getID();
statLabel = new JLabel(unitStatusString); // TODO: unit.getStatus();
invLabel = new JLabel(invStatusString); // TODO: unit.getInventoryStatus();
targetLabel = new JLabel(targetString);
timeLabel = new JLabel(timeString);
buildLabel(statLabel);
buildLabel(invLabel);
buildLabel(targetLabel);
buildLabel(timeLabel);
unitToggleButton = new UnitToggleButton(BasicArrowButton.EAST, indx);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.FIRST_LINE_END;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = .1;
gbc.weighty = 1;
gbc.insets = new Insets(0, 0, 5, 0);
// Add toggle button far-left, row 1
topPanel.add(unitToggleButton, gbc);
// Add empty space far-left, row 2
gbc.gridy = 1;
topPanel.add(new JLabel(" "), gbc);
// Add unit label row 1 column 2
gbc.gridy = 0;
gbc.gridx = 1;
gbc.weightx = .3;
topPanel.add(unitLabel, gbc);
// Add Status label row 1 column 3
gbc.gridx = 2;
topPanel.add(statLabel, gbc);
// Add inventory label row 1 column 4
gbc.gridx = 3;
topPanel.add(invLabel, gbc);
// Add tasking label row 2 column 2
gbc.gridy = 1;
gbc.gridx = 1;
topPanel.add(new JLabel(" Tasking: "), gbc);
// Add target label row 2 column 3
gbc.gridx = 2;
topPanel.add(targetLabel, gbc);
// Add mission Label row 2 column 4
gbc.gridx = 3;
topPanel.add(timeLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weighty = 1;
gbc.weightx = 1;
gbc.gridwidth = 4;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 0, 0, 0);
JSeparator sep = new JSeparator(JSeparator.HORIZONTAL);
topPanel.add(sep, gbc);
gbc.gridy = 3;
topPanel.add(elementTable, gbc);
revalidate();
this.setLayout(new BorderLayout());
this.add(topPanel, BorderLayout.NORTH);
this.add(tablePanel, BorderLayout.CENTER);
HSIUtils.setColoredBorder(tablePanel, Color.RED);
tablePanel.add(elementTable);
// Do NOT show the table on initialization
tablePanel.setVisible(false);
unitToggleButton.addActionListener(this);
}
/**
* Method: buildLabel()
*
* @param label
*/
private void buildLabel(JLabel label) {
label.setBorder(STAT_BORDER);
label.setMinimumSize(new Dimension(80, 20));
label.setPreferredSize(new Dimension(100, 25));
label.setOpaque(true);
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setHorizontalTextPosition(SwingConstants.CENTER);
label.setBackground(componentColor);
}
private void showHideTable(boolean show) {
tablePanel.setVisible(!show);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == this.unitToggleButton) {
showHideTable(unitToggleButton.isExpanded());
}
}
}
ExpandableTable:
public class ExpanableTable extends JPanel {
public ExpanableTable () {
super();
this.setLayout(new BorderLayout());
add(new JButton("Test1"), BorderLayout.WEST);
add(new JButton("Test2"), BorderLayout.CENTER);
add(new JButton("Test3"), BorderLayout.EAST);
}
}
В основномЯ хочу иметь возможность расширять / показывать / изменять размеры каждой панели внутри панели прокрутки независимо от других.В настоящее время, если я показываю скрытую панель на одной, высота другой панели увеличивается, но не показывает компонент.Для меня это очень странно, но моё незнание некоторых компонентов Swing и ограничений, которые в них содержатся, может быть