Я тщательно искал ответ на свой вопрос и пробовал несколько вещей, но ни одна из этих вещей не сработала для меня.
У меня есть кнопка, которая открывает JDialog
, позволяя пользователю атрибутировать и изменять цвета для трех типов объектов/ограничений.
JDialog
состоит из 2 JPanels
, первый из которых содержит еще 3 JPanels
для всех трех типов объектов, а второй — для кнопок OK/Отмена.
Моя проблема заключается в третьем типе объектов, так называемых «Ограничениях метки».
Этот третий тип объектов может иметь подобъекты, которые динамически добавляются в JPanel по мере их создания пользователем и состоят из имени и кнопки для изменения цвета объекта.
Это метод, который создает JPanel
, содержащий текст и кнопку для выбора цвета объекта, и добавляет его к labelColorConstraintPanel
, являющемуся полем класса. Этот метод вызывается в другом методе, отвечающем за создание объектов.
/**
* Add the last created label constraint class name(number) and its color
* button to the panel labelColorConstraintPanel. The button allows user to
* choose the label constraint class color.
**/
protected void createLabelColorConstraintsPanel() {
// labelColorConstraintPanel
JPanel classNameButtonPanel = new JPanel(new GridLayout(0, 2));
// classNameButtonPanel.setPreferredSize(new Dimension(15, 20));
classNameButtonPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
classNameButtonPanel.add(new JLabel("Class " + labelClassesCount + ":"));
jb_labelConstraintClassChooseColor.get(labelClassesCount - 1).addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
JButton lblClassColorButtonClicked = (JButton) event.getSource();
int buttonIndex = (int) lblClassColorButtonClicked.getClientProperty("index");
chooseLabelClassColor(buttonIndex);
}
});
classNameButtonPanel.add(jb_labelConstraintClassChooseColor.get(labelClassesCount - 1));
labelColorConstraintPanel.add(classNameButtonPanel);
}
labelColorConstraintPanel
присоединен к JScrollPane
, который присоединен к другому JPanel
для этого третьего типа объектов - ограничения метки.
Моя проблема в том, что JScrollBar
на JScrollPane
не появляется. Однако я читал, что установка preferredSize
из JPanel
внутри JScrollPane
на размер больше, чем эта секунда, приведет к появлению вертикальной полосы (см. строки кода с комментариями в методе chooseConstraintsColors
).
Таким образом мне удалось сделать бар-шоу, но у меня есть две другие проблемы. Первый: первые кнопки добавили растяжку к общему количеству JPanel
, создав огромные кнопки.
Второй: чем больше кнопок я добавляю, тем они изменяются в размерах и в какой-то момент ряды становятся «переполненными».
Наконец, я полагаю, что эти две проблемы представляют собой одну и ту же проблему, но, похоже, я не могу найти решение.
Либо есть другой способ показать JScrollBar
без установки preferredSize()
, либо есть способ динамически увеличивать размер JPanel
по мере добавления к нему новых объектов с фиксированным размером.
Вот основной метод, создающий окно JDialog
:
/** Opens a JDialog for choosing the Constraints Colors **/
protected void chooseConstraintColors() {
jd_colorsChooser = new JDialog((Frame) this.getTopLevelAncestor(), "Choose Constraints Colors", true);
jd_colorsChooser.getRootPane().setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
jd_colorsChooser.setLayout(new BorderLayout());
JPanel constraintsPanel = new JPanel(new BorderLayout());
JPanel mlConstraintsPanel = new JPanel();
JPanel clConstraintsPanel = new JPanel();
JPanel lblConstraintsPanel=new JPanel(new GridLayout(0,1));
JScrollPane lblConstraintsPane = new JScrollPane(labelColorConstraintPanel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
lblConstraintsPane.setPreferredSize(new Dimension(130,130));
TitledBorder lblcBorder = BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "Label Constraints Color", TitledBorder.LEFT,
TitledBorder.TOP);
lblConstraintsPane.setBorder(lblcBorder);
// must-link constraints panel
mlConstraintsPanel.setLayout(new BorderLayout());
TitledBorder mlcBorder = BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "Must-Link Constraints Color",
TitledBorder.LEFT, TitledBorder.TOP);
mlConstraintsPanel.setBorder(mlcBorder);
jb_mustLinkChooseColor.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
chooseMustLinkColor();
}
});
mlConstraintsPanel.add(jb_mustLinkChooseColor, BorderLayout.CENTER);
// cannot-link constraints panel
clConstraintsPanel.setLayout(new BorderLayout());
TitledBorder clcBorder = BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "Cannot-Link Constraints Color",
TitledBorder.LEFT, TitledBorder.TOP);
clConstraintsPanel.setBorder(clcBorder);
jb_cannotLinkChooseColor.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
chooseCannotLinkColor();
}
});
clConstraintsPanel.add(jb_cannotLinkChooseColor, BorderLayout.CENTER);
// label constraints panel
labelColorConstraintPanel.setPreferredSize(new Dimension(131,131));
lblConstraintsPanel.add(lblConstraintsPane);
constraintsPanel.add(mlConstraintsPanel, BorderLayout.NORTH);
constraintsPanel.add(clConstraintsPanel, BorderLayout.CENTER);
constraintsPanel.add(lblConstraintsPanel, BorderLayout.SOUTH);
// button panel
JPanel buttonPanel = new JPanel();
JButton ok = new JButton("OK");// update color changes on ok, update
// only fields that have changed
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
if (mustLinkColorTemp != null && mustLinkColorTemp != mustLinkColor) {
mustLinkColor = mustLinkColorTemp;
jb_mustLinkChooseColor.setBackground(mustLinkColor);
}
if (cannotLinkColorTemp != null && cannotLinkColorTemp != cannotLinkColor) {
cannotLinkColor = cannotLinkColorTemp;
jb_cannotLinkChooseColor.setBackground(cannotLinkColor);
}
for (int i = 0; i < labelClassesCount; i++) {
if (labelConstraintColorTemp.get(i) != null
&& labelConstraintColorTemp.get(i) != labelConstraintColor.get(i)) {
labelConstraintColor.set(i, labelConstraintColorTemp.get(i));
jb_labelConstraintClassChooseColor.get(i).setBackground(labelConstraintColor.get(i));
}
}
jd_colorsChooser.dispose();
}
});
// exit dialog on cancel
JButton cancel = new JButton("Cancel");
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
jb_mustLinkChooseColor.setBackground(mustLinkColor);
jb_cannotLinkChooseColor.setBackground(cannotLinkColor);
for (int i = 0; i < labelClassesCount; i++) {
jb_labelConstraintClassChooseColor.get(i).setBackground(labelConstraintColor.get(i));
}
jd_colorsChooser.dispose();
}
});
buttonPanel.add(ok);
buttonPanel.add(cancel);
jd_colorsChooser.add(constraintsPanel, BorderLayout.NORTH);
jd_colorsChooser.add(buttonPanel, BorderLayout.SOUTH);
jd_colorsChooser.setPreferredSize(new Dimension(270, 270));
jd_colorsChooser.pack();
jd_colorsChooser.setLocationRelativeTo(null);
jd_colorsChooser.setVisible(true);
}
P.S: Поскольку я новичок в StackOverflow, я не могу загружать изображения, но вот описание изображений:
Случай 1: JDialog
с 3 панелями и кнопками OK и Cancel.
Если setPreferredSize
не используется, кнопки добавляются в третий JPanel
один за другим без появления полосы прокрутки.
Случай 2: используется setPrefferedSize()
, появляется полоса прокрутки с первой кнопкой, растянутой на размер JPanel
, поскольку мы добавляем больше кнопок, ряды с кнопками JPanel
становятся переполненными.