2

I've thoroughly searched for an answer to my question and tried multiple things but none of these things worked for me.

I have a button that opens a JDialog allowing the user to attribute and change colors for three types of objects/constraints.

The JDialog consists of 2 JPanels, the first containing another 3 JPanels for all three types of objects, and the second one for the OK/Cancel buttons.

My problem is in the third type of objects so-called "Label constraints".

This third type of objects can have sub-objects which are added dynamically to a JPanel as the user creates them and consist of a name and a button for changing the color of the object.

This is the method that creates a JPanel that containts text and a button for choosing the color of the object and adds it to the labelColorConstraintPanel which is a field of the class. This method is called in another method responsible for creating the objects.

 /**
 * 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);
}

The labelColorConstraintPanel is attached to a JScrollPane which is attached to another JPanel for this third type of objects - Label constraints.

My problem is that the JScrollBar on the JScrollPane won't appear. However I read that setting the preferredSize of the JPanel within the JScrollPane to a size bigger than this second will make the vertical bar appear (see commented code lines in method chooseConstraintsColors).

In this way I managed to make the bar show, but I have two other problems. The first one: first buttons added stretch on the total of the JPanel creating enormous buttons.

The second one: the more buttons I add, they're resized and at some point the rows get "crowded".

Finally I suppose these 2 problems represent the same problem, but however I cant seem to find the solution.

Either there is another way to show the JScrollBar without setting the preferredSize(), or there is a way to dynamically increase the size of the JPanel as we add new objects to it with fixed size.

Here is the main method that creates the JDialog window:

/** 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: As I'm new to StackOverflow I cant really upload pictures, but here is a description of the pictures:

Case1: A JDialog with 3 Panels and a OK and a Cancel button.

If setPreferredSize not used, buttons are added in the third JPanel one after another without the scrollbar appearing.

Case2: setPrefferedSize() used, a scroll bar appears with first button stretched over the size of the JPanel, as we add more buttons the rows with the buttons of the JPanel get crowded.

Paolo Forgia
  • 6,572
  • 8
  • 46
  • 58
  • 5
    1) *"P.S: As I'm new to stackoverflow i cant really upload pictures, but heres is a description of the pictures:"* You can post links to your images and we can edit it. 2) Your question is too large, without images of what you're trying to do and it becomes confusing, I can see you haven't taken the [tour], so, go through it, then read [ask] and after that post a valid [mcve], which isn't your whole code or code snippets, but a simple example code, that when run, will show your issue. It shouldn't be posted in external sites but as code formatted text (as you already did here) – Frakcool Jun 12 '17 at 14:56

1 Answers1

0

In this way I managed to make the bar show, but I have two other problems. The first one: first buttons added stretch on the total of the JPanel creating enormous buttons. The second one: the more buttons I add, they're resized and at some point the rows get "crowded"

  1. Don't use setPreferredSize(). It is the job of the layout manager to calculate the preferred size.

  2. You are using the wrong layout manager. You are never forced to use a single layout manager you can nest layout manager. For example you could create a JPanel with a BorderLayout and add this panel to the scrollPane. Then you create a second panel with the GridLayout and this to the BorderLayout.PAGE_START of the panel using the BorderLayout. Now the panel will respect the size of components added to it and grow as necessary.

camickr
  • 321,443
  • 19
  • 166
  • 288