Question

I'm new to Swing and I currently work on some sort of graphic editor. First I started implementing the toolbar (class OptionsBar) as an extended JPanel. Everything looked fine(image below), but it didn't work as a toolbar (it wasn't always focused). Then I found out that there actually exists a JToolBar element, so I replaced "extends JPanel" with "extends JToolBar". I look thorugh toolbar specifications. It seemed like I should change anything.

The problem is that the toolbar is transparent (besides its panel elements) even though isBackgroundSet() returns true. (image 2)

The second bug is drag the toolbar and then bring it back to the initial positions. It shrinks. (image 3)

Also, some movements (i can't describe them exactly) result in java.lang.IllegalArgumentException: illegal component position

The main windows is a JFrame that has border layout and uses a desktop pane.

Any help? Thanks!!

enter image description here

enter image description here

enter image description here

public class OptionsBar extends JToolBar {

..some constants and attributes..

public OptionsBar(BrushStroke brushStroke, BrushStroke savedBrushStroke) {
    super();

    this.setBackground(backgroundColor);
    // keep the references to strokes from the main gui
    this.brushStroke = brushStroke;
    this.savedBrushStroke = savedBrushStroke;

    // create buttons for selecting pencil/eraser
    JToggleButton brushButton = makeInstrumentButton(brushIcon, "Pencil");
    JToggleButton eraserButton = makeInstrumentButton(eraserIcon, "Eraser");

    // make a button for adjusting colors
    JButton adjustColorButton = makeAdjustButton();

    // create label for descriptions
    JLabel toolsLabel = makeDescriptionLabel("Tools");
    JLabel parametersLabel = makeDescriptionLabel("Parameters");
    JLabel colorsLabel = makeDescriptionLabel("Colors");

    // create panel for brush size and opacity parameters
    ParameterPanel sizePanel = new ParameterPanel("Size", "1", 1,
            maxBrushSize, 1);
    ParameterPanel opacityPanel = new ParameterPanel("Opacity", "100", 0,
            100, 100);

    // create a check box for selecting rounded caps
    JCheckBox roundedCap = new JCheckBox("Use round strokes");
    roundedCap.setSelected(true);

    JSeparator separator = new JSeparator(JSeparator.VERTICAL);
    separator.setMaximumSize(new Dimension(3, 35));
    JSeparator separator1 = new JSeparator(JSeparator.VERTICAL);
    separator1.setMaximumSize(new Dimension(3, 35));

    // create a box layout
    this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    this.add(Box.createHorizontalStrut(20));
    this.add(toolsLabel);
    this.add(Box.createHorizontalStrut(30));
    this.add(brushButton);
    this.add(Box.createHorizontalStrut(10));
    this.add(eraserButton);
    this.add(Box.createHorizontalStrut(30));
    this.add(separator1);
    this.add(Box.createHorizontalStrut(30));
    this.add(parametersLabel);
    this.add(Box.createHorizontalStrut(20));
    this.add(sizePanel);
    this.add(Box.createHorizontalStrut(20));
    this.add(opacityPanel);
    this.add(Box.createHorizontalStrut(25));
    this.add(roundedCap);
    this.add(Box.createHorizontalStrut(25));
    this.add(separator);
    this.add(Box.createHorizontalStrut(30));
    this.add(colorsLabel);
    this.setOpaque(false);
    addColorButtons();

    this.add(Box.createHorizontalStrut(20));
    this.add(adjustColorButton);
    this.colorPicker = new ColorPicker();
    colorPicker.getSelectionModel().addChangeListener(new ColorChange());

    this.colorPopup = new JPopupMenu();
    colorPopup.add(colorPicker);

    this.setSize(2000, 65);
    this.setVisible(true);
}

And here is the snipped from the JFrame constructor Here is a snippet from the JFrame constructor

       desktop = new JDesktopPane();
        setContentPane(desktop);
        whiteBoards = new HashMap<String, Canvas>();
        createFrame("first try", 400, 300);     

        desktop.add(new OptionsBar(brushStroke,savedBrushStroke),BorderLayout.PAGE_START);
Was it helpful?

Solution

To give an answer to all your questions:

  1. JMenuBar is transparent by default. You can change that setting as follows:

    menuBar.setOpaque(true);
    
  2. You added your JMenuBar to a JDesktopPane container. A JDesktopPane has no layout set by default, to allow positioning of the added JInternalFrame. Thats why your JMenuBar is not visible, if you do not set the size manually. Usually it is a better idea to let the LayoutManager align your components. To do so, replace your last code snippet with these lines:

    desktop = new JDesktopPane();
    JPanel basePanel = new JPanel(new BorderLayout());
    basePanel.add(desktop, BorderLayout.CENTER);
    basePanel.add(new OptionsBar(...), BorderLayout.PAGE_START);
    getContentPane().add(basePanel);
    

    This code uses another parent JPanel which allows us to add our JMenuBar to the top area. Aligning and sizing of our JMenuBar is not delegated to the LayoutManager of the JPanel so we can get rid of the getSize(...) in the constructor of the OptionsBar.

I am pretty sure that this change also fixes the thrown IllegalArgumentException.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top