问题
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!!
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);
回答1:
To give an answer to all your questions:
JMenuBar
is transparent by default. You can change that setting as follows:menuBar.setOpaque(true);
You added your
JMenuBar
to aJDesktopPane
container. AJDesktopPane
has no layout set by default, to allow positioning of the addedJInternalFrame
. Thats why yourJMenuBar
is not visible, if you do not set the size manually. Usually it is a better idea to let theLayoutManager
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 ourJMenuBar
to the top area. Aligning and sizing of ourJMenuBar
is not delegated to theLayoutManager
of theJPanel
so we can get rid of thegetSize(...)
in the constructor of theOptionsBar
.
I am pretty sure that this change also fixes the thrown IllegalArgumentException
.
来源:https://stackoverflow.com/questions/20255218/jtoolbar-background-and-drag-problems