Component inside JMenuBar wants to align far right after JSeparator? - java

Take a look at this image:
As you can see, I have a JSeparator between my "Auto Refreshing" JCheckBox and my "Show Column" menu, and my "Show Column" menu is wanting to be as far right as possible. Why is it not aligning itself to the left, like everything else before the JSeparator? And I can't seem to make it do so, here is my current code:
JCheckBox pulling = new JCheckBox("Auto Refreshing");
...
menuBar.add(pulling);
menuBar.add(new javax.swing.JSeparator(javax.swing.SwingConstants.VERTICAL));
JMenu showMenu = new JMenu("Show Column");
showMenu.setAlignmentX(Component.LEFT_ALIGNMENT);
menuBar.add(showMenu);

This tutorial might be helpful. A quote:
By default, most components have center X and Y alignment. However, buttons, combo boxes, labels, and menu items have a different default X alignment value: LEFT_ALIGNMENT.
So you can see that placement logic differs, in other words, don't count on it. However, I do not know why your manual alignment to left did not work. Most likely the problem is the size of your last menu. What you can do, is use glue as filler since JMenuBar has a BoxLayout.
menuBar.add(showMenu);
menuBar.add(Box.createHorizontalGlue());
This invisible space will be added to the end of your menu and it will push components before it the left.

The issue was the size of the JSeparator, it wanted to take up as much horizontal space as possible. So, my solution was to restrict it's size so that it could only be one pixel wide max:
JSeparator menuSep = new JSeparator(javax.swing.SwingConstants.VERTICAL);
menuSep.setMaximumSize(new java.awt.Dimension(1, 1000));
menuBar.add(menuSep);

Related

Can't resize JLabels in BoxLayout

I'm trying to set up a few JLabels to use as buttons inside a BoxLayout, stacked on top of each other. The layout is fine, but I'm finding that I can't resize the labels to the dimensions I want. I'm using the following code to size them:
JLabel fileAddBtn = new JLabel("Add File", SwingConstants.CENTER);
fileAddBtn.setBorder(BorderFactory.createLineBorder(Color.black));
fileAddBtn.setMaximumSize(new Dimension(Integer.MAX_VALUE, fileAddBtn.getMinimumSize().height));
and
JLabel fileRemBtn = new JLabel("Remove File", SwingConstants.CENTER);
fileRemBtn.setBorder(BorderFactory.createLineBorder(Color.black));
fileRemBtn.setMaximumSize(new Dimension(Integer.MAX_VALUE, fileRemBtn.getMinimumSize().height));
As of now I have two labels, with one being longer than the other. They are both taking the width of the longer label, which is good, but the labels are hugging the edges of the text right to the nearest pixel. Is there any way to make the labels a little bigger so that there is a bit of a border around the labels? I've tried using setSize() but it doesn't take. I've also added straight values into the above code, but it doesn't change them either. I tried adding an EmptyBorder() around them, which worked for sizing, but it hid my line border which surrounds them. Any thoughts?
Is there any way to make the labels a little bigger so that there is a bit of a border around the labels?
Sure. Add an EmptyBorder.
But since the code is already adding a border to the labels, to retain that line border, make a CompoundBorder consisting of the empty border and the line border, and set the compound border to the label.
See also Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? (Yes.)

Java Swing, making a gridlayout fill parent?

I just recently started using Swing to create GUIs for programs, and it's been pretty fun to mess around with so far. However, I'm having an issue with a JPanel with the layout set to gridLayout. Right now it looks like this:
The grid on the right is a JPanel set to a GridLayout, with each cell being a bordered JLabel. The options on the left are also inside a JPanel, and the left JPanel and right JPanel are nested in a GridBagLayout set on a JFrame.
Essentially, my problem is that I want to "scale" the grid on the right so that each cell is a certain height and width. The grid itself will have a variable number of rows and columns, which are set when the program first starts up. Eventually, I plan to have the right JPanel in a JScrollPane (if that's how that works...), so I'm not really concerned about whether or not all of the grid shows up onScreen.
I tried setting the fill value for the gridLayout to "BOTH" and it gave me the following result:
This is closer to my intention, but I wanted the actual ImageIcon in the JLabels to fill the entire JLabel. Additionally, I would want the JLabels to be the same height and width. However, I don't know exactly how to do that. I've been messing around with it for a while now, and I'm not sure if I'm just too much of a noob with Swing, or if I'm missing something in the documentation.
In the end, I'd like the grid cells to be a fixed height and width, no matter the number of cells, and no matter whether it goes offscreen or doesn't fill it.
(Also, I just thought, maybe it's not the best idea to code this and then shove it in a JScrollPane later and expect it to perform the same.... I guess I'll just see what happens.)
but I wanted the actual ImageIcon in the JLabels to fill the entire JLabel.
Check out Darryl's Stretch Icon which will allow the icon to resize to file the space available for the JLabel.

Arranging JCheckBox units Vertically

I have created a program in which I display result-filtering options on the side of my Swing window, however by default they appear horizontally next to one another, which wastes the space I have allotted in my BorderLayout's WEST side.
Is there anything I can pass in my constructor or add-statement that will stack these up?
Here's my relevant code in a class that extends JFrame:
box1 = new JCheckBox("Points");box2 = new JCheckBox("Bleh");
pane = new JPanel();
pane.add(box1);pane.add(box2);
add(pane, BorderLayout.WEST);
So this is quite simple, but when displayed they show side-by-side, and that's what I am looking to change.
Any help will be greatly appreciated. If I missed a good source of research info, please pass it along.
Use GridLayout with n rows and one column for pane, where n is the number of checkboxes

JXMultiSplitPane going bonkers when I switch tabs

I'm using JXMultiSplitPane (from SwingX 1.6.2) to implement a three-pane horizontal interface. In the center pane is a JTabbedPane with two tabs: one with a JTextArea (in a JScrollPane, of course) used for entering Markdown code and the other a JEditorPane (again, in a scroll pane) for displaying a rendered HTML preview. When the user switches to the preview pane, the text in the editor is processed and displayed in the preview pane.
My problem is that if I enter text in the editor with long lines, and then switch to the preview, the center pane will expand. Sometimes it's just by a little bit, other times it'll take up more room than is actually on the screen. But if I move one of the resize handles manually, everything will snap back in place.
I've found only two ways to deal with this before it happens:
Manually resize one of the panes before entering any text.
Give the center pane a weight of 1 in the MultiSplitLayout model.
I can't use the second one since it will expand the center pane to take up almost the whole window by default.
Is there a way to fix this?
Update
After a little more testing, even technique (2) doesn't keep the size constant; switching between the two tabs changes the size of the center pane slightly.
I now believe that the problem is partly with the tabbed pane. The JTextArea and the JEditorPane do not have the same size and that JTabbedPane is resizing when I switch between them (since I'm resetting the JEditorPane text every time. This wouldn't be a problem except that JXMultiSplitPane will keep automatically resizing the center pane until the user forces a specific size by resizing manually.
So I should be able to fix the issue by making the size of the JTabbedPane fixed, but still able to be resized by the handle bars. Any tips on doing that?
The MultiSplitLayout is .. a LayoutManager, so you have to understand how it works (me too, not overly familiar with it myself :-)
The basic layout happens according to the component's prefSize, the weights are for distributing excess/missing space relative to the pref. By default, the dividers are "floating", that is they are positioned between the components as layouted by the basic mechanism. The moment a user touches a divider, dividers are "not-floating", comp sized to fit in-between the dividers. That's the reason for you not seeing the size-greed after moving the divider once. So one ways out is to
setup the JXMultiSplitPane as usual, add the components and realize the frame
fix the dividers after the manager has done its initial layout
String layout = "(ROW " +
"(LEAF name=selector weight=0.15)" +
"(LEAF name=center weight=0.7)" +
"(LEAF name=list weight=0.15)" +
")";
JXMultiSpitPane pane = new JXMulitSplitPane((MultiSplitLayout.parseModel(layout))
// add components and realize the frame
...
pane.getMultiSplitLayout().setFloatingDividers(false);
Alternatively, give more weight to the weights - force the layoutManager to use them for the layout itself (instead of only for the distribution of excess/missing space). A side-effect is that the prefSize of the comps might be set (by the layout, which is a no-no-never, but who's perfect ;-)
pane.getMulitSplitLayout().setLayoutByWeights(true);
Not sure which way I would prefer or if/how that could be made easier in the multisplit ..

Creating a fancy search bar with Swing components

I'm trying to come up with an elegant recreation of the search bar component in Thunderbird. The clear button doesn't appear until there is text in the box, so that screen-shot is a bit inaccurate.
Should I use a layered pane and get some buttons to float above the box? (but then getting the text to not appear below the buttons would be hacky)
Maybe just put buttons at the ends of the search bar and have it somehow blend in?
Any ideas or maybe a style reconsideration is welcome, thank you.
What about a white panel with a border and a JTextField without borders inside. Two buttons (or more) in the west and east. Button will appear/hide depending on the text field content.
You might be able to use the Text Prompt for the "Search all text" display.
Check out JideSoft's Common Layer and the Overlayable class.
Demos
For building a very similar component I've used JXLayer (for drawing the buttons) in conjunction with IntelliHints from JIDE OSS project (for implementing a drop down list of values).
This code adds a label with given icon to the right of the JTextPane. One thing to work on: don't let the text go under the label. You can use setMargin(), but it shifts the label too.
JTextField searchField = new JTextField(30);
searchField.setLayout(new BorderLayout());
JLabel label = new JLabel(icon);
label.setCursor(Cursor.getDefaultCursor());
searchField.add(label, BorderLayout.LINE_END);
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
searchField.setText("");
}
});

Categories

Resources