I have a small "popup" like this:
But I don't want the padding around the button, I want it to be as small as it can be with the supplied text.
btn.setMargin(new Insets(1, 1, 1, 1));
panel.add(lbl, "wrap");
panel.add(btn);
frame.pack();
frame.setVisible(true);
At least this doesn't work...
Can this be achieved on MigLayout or should I use some other layout manager for this frame.
What's your MigLayout constraints that it was built with? You might want to try using novisualpadding if you aren't already. Also, the debug layout constraint will draw boxes around your components to show what room they take up. (I think the red dotted lines are the size of the components and the blue dotted lines are the "cells" that the component is in.)
// old version
// JPanel panel = new JPanel(new MigLayout());
// new verion
JPanel panel = new JPanel(new MigLayout("debug, novisualpadding"));
I use MigLayout pretty often and have found the "cheat sheet" pretty useful. http://migcalendar.com/miglayout/cheatsheet.html
A layout manager should not affect the way a component is painted.
The setMargin(...) works fine for me when using the Metal LAF. Maybe your LAF doesn't support the setMargin() method. Or maybe you have some code elsewhere that is overriding the preferred size of the button causing it to paint like this.
However, if the MIG layout turns out to be the problem, you could try the Wrap Layout.
Taking MIke's answer as a startup, I found in the MIG "CheatSheet" a possible solution to your problem.
When you set up a MIGLayout, you can specify the gap between component with an integer between the square brackets defining columns and rows.
E.g.
MigLayout buttonMig = new MigLayout("", "[139px,grow]0[179px,grow]50[142px,grow][143px,grow]", "0[60px:60px:60px,center]");
I've just been having this issue too. I discovered that the following worked for me:
this.add(okButton, "width pref:pref:pref");
or
this.add(okButton, "wmax pref");
Also when using the substance look and feel there is a feature where the minimum size is always too wide. This can be overridden with this obscure hack.
okButton.putClientProperty(
SubstanceLookAndFeel.BUTTON_NO_MIN_SIZE_PROPERTY, Boolean.TRUE);
Related
I'am using panel with absolute layout (don't ask why) and I need to add elements on it programmatically. I done that part, but now I want to surround panel with JScrollPane so that when user add more items, scroll bar does its job. But surrounding panel with scroll bar doesn't work. What can I do here.
JFrame frame = new JFrame();
frame.setSize(582, 451);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 11, 546, 391);
frame.getContentPane().add(scrollPane);
JPanel panel = new JPanel();
scrollPane.setViewportView(panel);
panel.setLayout(null);
for(int i=0;i<labelList.size();i++){
if(a==4){
a=0;
b++;
}
labelList.get(i).setBounds(10+120*a+10*a, 10+130*b+10*b, 120, 130);
labelList.get(i).setOpaque(true);
labelList.get(i).setBackground(Color.WHITE);
labelList.get(i).setText(Integer.toString(i));
panel.add(labelList.get(i));
a++;
}
You're not going to like my answer, but I feel that we should be compelled to give you the best answer, which is not always what you want to hear. And that is this: use layout managers to do your component layouts. Yes while it might seem to newbies that null layouts are the easiest to use, as you gain more experience you will find that exactly the opposite is true. Null layout use makes for very inflexible GUI's that while they might look good on one platform look terrible on most other platforms or screen resolutions and that are very difficult to update and maintain. Instead you will want to study and learn the layout managers and then nest JPanels, each using its own layout manager to create pleasing and complex GUI's that look good on all OS's.
As for ease of use, I invite you to create a complex GUI with your null layout, and then later try to add a component in the middle of this GUI. This will require you to manually re-calculate all the positions and sizes of components added to the left or below the new component, which is prone to many errors. The layout managers will all do this automatically for you.
Specifically use of valid layout managers will update your JPanel's preferredSize automatically increase as more components are added and as the JPanel is revalidated (the layouts are told to re-layout their components). Your null JPanel will not do this, and so the JScrollPane will not work. Yes, a work around is for you to manually calculate and set your JPanel's preferredSize, but this is dangerous and not recommended for the same reasons noted above.
I am having quite a problem in regards to a proper way to handle 'packing' a JPanel and allowing a scroll bar.
I left out a bit of the code, but I believe what is provided should suffice.
The issue, is that the JScrollBar either doesn't show up, or can't be interacted with (if I set the scroll bar to always have the vertical bar).
Here is an image depicting this:
![No Scroll Bar Present][1]
The ProjectPanel (extends JPanel) are of fixed size and, as you can see, extend farther than the visible view port. There is NO way of getting the calculated height of the JPanel (ProjectSelector), as the ProjectPanels can also be transitioned as so:
![They need to fill as a grid][2]
If anyone could help provide some insight on how to do this, that would be great. As of now, I would like at all costs not to use an external API, as that would cause more harm than good.
Question:
How can I set the height for the preferred size to be 'flexible', so as I add components it can expand? If that wouldn't be ideal / no possible, how could I properly allow the JScrollPane to show all components of the JPanel efficiently?
if I do not, then the Flow Layout organizes them horizontally
Maybe you should be using a GridLayout.
If not then you can try the Wrap Layout which is a FlowLayout that wraps to a new line as required.
If you are looking for a different layout, why don't you try MiGLayout? It is a very powerful and flexible layout manager.
See a detailed example here.
From that link, rewrite the initUI method to see the behavoir interesting to your problem:
public void initUI() {
this.setPreferredSize(new Dimension(100, 100));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setJMenuBar(initMenuBar());
this.getContentPane().add(new JScrollPane(mainPanel = initMainPanel()));
this.setLocationByPlatform(true);
this.pack();
}
I want to add a Jpanel on a jscrollpane; also I want to have only vertical scrolling. I want to set layout of my jPanel "flowLaout" and add several components to my jPanel in my code by jpanel.add(component) method. The result is that all components are placed in just one row that excide width of jpanel and are not shown. I have used this tricks and both failed:
jScrollPane1.setHorizontalScrollBar(null);
jScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
Wrap Layout should work for you.
I am unsure of the particulars for your current project, but i would recommend MigLayout. It has never served me wrong.
I am currently writing a touchscreen interface with nested MigLayout panels up to 4 or five layers deep, and have not had a single problem.
Please use the below policy to turn on vertical scrolling and turn off horizontal scrolling(Works with Java SE 7):
Panel graphicPanel = new Panel();
JScrollPane scrollbar = new JScrollPane(graphicPanel);
scrollbar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollbar.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollbar.setPreferredSize(new Dimension(1300, 600));
scrollbar.setVisible(true);
add(scrollbar, BorderLayout.CENTER);
JPanel pMeasure = new JPanel();
....
JLabel economy = new JLabel("Economy");
JLabel regularity = new JLabel("Regularity");
pMeasure.add(economy);
pMeasure.add(regularity);
...
When I run the code above I get this output:
Economy Regularity
How can I get this output, where each JLabel starts on a new line? Thanks
Economy
Regularity
You'll want to play around with layout managers to control the positioning and sizing of the controls in your JPanel. Layout managers are responsible for placing controls, determining where they go, how big they are, how much space is between them, what happens when you resize the window, etc.
There are oodles of different layout managers each of which allows you to layout controls in different ways. The default layout manager is FlowLayout, which as you've seen simply places components next to each other left to right. That's the simplest. Some other common layout managers are:
GridLayout - arranges components in a rectangular grid with equal-size rows and columns
BorderLayout - has one main component in the center and up to four surrounding components above, below, to the left, and to the right.
GridBagLayout - the Big Bertha of all the built-in layout managers, it is the most flexible but also the most complicated to use.
You could, for example, use a BoxLayout to layout the labels.
BoxLayout either stacks its components on top of each other or places them in a row — your choice. You might think of it as a version of FlowLayout, but with greater functionality. Here is a picture of an application that demonstrates using BoxLayout to display a centered column of components:
An example of code using BoxLayout would be:
JPanel pMeasure = new JPanel();
....
JLabel economy = new JLabel("Economy");
JLabel regularity = new JLabel("Regularity");
pMeasure.setLayout(new BoxLayout(pMeasure, BoxLayout.Y_AXIS));
pMeasure.add(economy);
pMeasure.add(regularity);
...
I read this piece of code:
pMeasure.setLayout(new BoxLayout(pMeasure, BoxLayout.VERTICAL));
It seems BoxLayout doesn't have VERTICAL. Upon searching, this will work using the following code:
pMeasure.setLayout(new BoxLayout(pMeasure, BoxLayout.Y_AXIS));
Here is what you need to use:
JLabel economy = new JLabel("<html>Economy<br>Regularity</html>");
A quick way is to use html within the JLabel.
For instance include the <br/> tag.
Otherwise, implement a BoxLayout.
Make a separate JPanel for each line, and set the dimensions to fit each word:
JLabel wordlabel = new JLabel("Word");
JPanel word1 = new JPanel();
word1.setPreferredSize(new Dimension(#,#);
This should work for each word. You can then add each of those JPanels to your main JPanel. This also allows you to add other components next to each word.
Is it possible to add a JLabel on top of another JLabel? Thanks.
The short answer is yes, as a JLabel is a Container, so it can accept a Component (a JLabel is a subclass of Component) to add into the JLabel by using the add method:
JLabel outsideLabel = new JLabel("Hello");
JLabel insideLabel = new JLabel("World");
outsideLabel.add(insideLabel);
In the above code, the insideLabel is added to the outsideLabel.
However, visually, a label with the text "Hello" shows up, so one cannot really see the label that is contained within the label.
So, the question comes down what one really wants to accomplish by adding a label on top of another label.
Edit:
From the comments:
well, what i wanted to do was first,
read a certain fraction from a file,
then display that fraction in a
jlabel. what i thought of was to
divide the fraction into 3 parts, then
use a label for each of the three.
then second, i want to be able to drag
the fraction, so i thought i could use
another jlabel, and place the 3'mini
jlabels' over the big jlabel. i don't
know if this will work though..:|
It sounds like one should look into how to use layout managers in Java.
A good place to start would be Using Layout Managers and A Visual Guide to Layout Managers, both from The Java Tutorials.
It sounds like a GridLayout could be one option to accomplish the task.
JPanel p = new JPanel(new GridLayout(0, 1));
p.add(new JLabel("One"));
p.add(new JLabel("Two"));
p.add(new JLabel("Three"));
In the above example, the JPanel is made to use a GridLayout as the layout manager, and is told to make a row of JLabels.
The answer to your original question is yes for the reasons given that any Component can be added to a Container.
The reason you don't see the second label is because by default a JLabel uses a null layout manager and the size of the second label is (0, 0) so there is nothing to paint. So all you need to do is set the bounds of the second label and away you go.
You can't use a layout manager if you want to drag components around because as soon as you resize the frame etc, the layout manager will be invoked and the components will be repositioned based on the layout manager of the component.
it's a matter of layout.
you can do that using null layout (with hard coded locations) or with a custom layout.
you can use a JLayeredPane and set it's border to No Border.
you can add put them above each others by using the horizontal or vertical gap (hgap,vgap) the attributes of the layout
JPanel p = new JPanel(new GridLayout(2, 1,-40,0));
//the 40 is the hgap , make it the same with the label height .