I have three JLabels and three JTextAreas. I have them in borderlayout, center, but I want each of them in a different line, that's not happening and the top ten search results in Google for line break java don't solve the problem. How can I do a simple line break?
If this is a Swing application, you should use a layout manager to position your fields in the container.
Line break won't help with placing Swing objects; you need to place a layout on a center JPanel. That is, the center of your border layout should be a single Swing object, a JPanel, and you should set that to a style which allows you to stack each widget. GridLayout(6,1) may do it.
You can use layout managers like GridLayout or GridBagLayout. Even though the latter one is only recommended for code generated by GUI generators I prefer it because it gives me the most flexibility.
JPanel panel = new JPanel();
GridBagLayout layout = new GridBagLayout();
panel.setLayout(layout);
layout.add(label1, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
layout.add(area1, new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
layout.add(label2, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
layout.add(area2, new GridBagConstraints(1, 1, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
layout.add(label3, new GridBagConstraints(0, 2, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
layout.add(area3, new GridBagConstraints(1, 2, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
panel.add(label1);
panel.add(label2);
panel.add(label3);
panel.add(area1);
panel.add(area2);
panel.add(area3);
Of course this looks butt-ugly but should get you started.
You can also abuse a BorderLayout:
JPanel panel = new JPanel(new BorderLayout());
JPanel topRow = new JPanel();
panel.add(topRow, BorderLayout.PAGE_START);
topRow.add(label1);
topRow.add(area1);
JPanel middleRowBox = new JPanel(new BorderLayout());
panel.add(middleRowBox, BorderLayout.CENTER);
JPanel middleRow = new JPanel();
middleRowBox.add(middleRow, BorderLayout.PAGE_START);
middleRow.add(label2);
middleRow.add(area2);
JPanel bottomRowBox = new JPanel();
middleRowBox.add(bottomRowBox, BorderLayout.CENTER);
JPanel bottomRow = new JPanel();
bottomRowBox.add(bottomRow, BorderLayout.PAGE_START);
bottomRow.add(label3);
bottomRow.add(area3);
bottomRowBix.add(new JPanel(), BorderLayout.CENTER);
Try using a GridLayout for starters:
panel.setLayout(new GridLayout(0,2));
// the order of added components is important
panel.add(labelA);
panel.add(textAreaA);
panel.add(labelB);
panel.add(textAreaB);
...
Doesn't look too pretty but it gets you started.
If you don't set a LayoutManager to a new panel, it will use a FlowLayout which behaves somewhat like HTML layout. But there is no such thing as an intended line break in a FlowLayout. It will just put component after component until it reaches the end of the available space and then start a new row.
If you want control over your layouts - don't use FlowLayout.
Layout managers you might want to get to know are:
BorderLayout - very good if you want resizeable content
GridLayout - simple equals width and height grid
null - allows you to use setBounds on each component to get absolute positions
There are more, but these three should allow you to layout 95% of your panels.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I've been trying to use a GridBagLayout to organize a bunch of panels (containing a bunch of labels which alter the size of the panel, mostly vertically). The major reason why i chose this is because the panel sizes can vary quite different, and I would like the panels to scale when the frame size is changed.
I keep coming across problems ranging from different sized panels (checking via borders on panels), weird sizing issues, cant get the panels to stick to each other vertically (massive space inbetween panels).
Gridbag seemed like the best option but it seems like its becoming a bigger pain than i imagined. What other options provide proper scaling when altering the frame size?
I have become a fan of what #SplungeBob showed me a long time ago. The code snippet below gives you an idea of what it takes to accomplish the GUI shown below it.
frame.add(menu, new GBConstraints( 0, 0).spanX(32).fill(HORIZONTAL));
frame.add(new JLabel("Available letters"),
new GBConstraints( 0, 1).insets( 2, 2, 0, 2));
frame.add(new JLabel("Play by play..."),
new GBConstraints( 2, 1).insets( 0, 5, 0, 0));
frame.add(pnlPlays, new GBConstraints( 2, 1).insets(10, 0, 0, 0).spanY(14).anchor(WEST).fill(BOTH));//.ipad(0,0));
frame.add(pnlAvail, new GBConstraints( 0, 2).insets(0, 5, 5, 5));
frame.add(pnlLegend, new GBConstraints( 1, 2) .spanY(14) .fill(BOTH));
frame.add(pnlBonuses, new GBConstraints( 0, 3).insets(0, 100, 0, 0));
frame.add(pnlSBBonuses, new GBConstraints( 0, 3).insets(0, 125, 0, 0));
frame.add(gamePanel, new GBConstraints( 0, 5).insets(0, 50, 0, 0));
frame.add(pnlTheScore, new GBConstraints( 0, 5) .anchor(EAST));
btnDebug.setPreferredSize(new Dimension(1, 1));
frame.add(btnDebug, new GBConstraints( 0, 0) .anchor(WEST));
frame.add(btnNextReplayStep,new GBConstraints( 0, 6).insets(0,310, 0, 0) .anchor(CENTER));
btnNextReplayStep.setVisible(false);
frame.add(new JLabel("User letters"),
new GBConstraints( 0, 6).insets(0,240, 30, 0));
frame.add(btnCopyUser, new GBConstraints( 0, 6).insets(0,310,0,0) .anchor(CENTER));
frame.add(btnCopyAllLetters,new GBConstraints( 0, 6) .anchor(EAST));
frame.add(pnlNotes, new GBConstraints( 0, 6).insets(25,10,10, 10).spanY( 2).anchor(WEST));
frame.add(btnClearMnemHi, new GBConstraints( 0, 7).insets(0,430, 0, 0));
frame.add(btnClearBorders, new GBConstraints( 0, 7).insets(0,530, 0, 0));
I won't lie; it can still be a major task, but with careful planning with an actual grid marked off in vertical and horizontal lines to show, e.g., how many columns a field must span, it's worth a try. And chances are excellent that what #Hovercraft suggests is even better.
(I haven't mastered it, it seems as the weird insets values seem to indicate. But it's a nice-looking reliable GUI.)
EDIT
Here's code for how two of the JPanel objects were created prior to executing the code above. One also uses GridBagLayout; other doesn't. Just whatever works easiest and best.
private void makePlays(){
pnlPlays = new JPanel(new GridBagLayout());
pnlPlays.setSize(500,300);
pnlPlays.add(scrPlays, new GBConstraints(0,1).span(40, 62)
.fill(BOTH).ipad(100, 50));
scrPlays.setEnabled(false);
}
private void makeScoremasterBonuses(){
BonusBackgroundColors c;
BonusBackgroundColors all [] = BonusBackgroundColors.values();
String labels[] = new String[all.length];
String abbrs [] = new String[all.length];
JButton but;
pnlBonuses = new JPanel();
pnlBonuses.add(new JLabel("Legend:"));
for (int i = 0; i < all.length; i++) {
labels[i] = all[i].name().replace("_", " ").toLowerCase();
abbrs [i] = Utilities.abbreviate(all[i].name());
c = BonusBackgroundColors.values()[i];
but = new JButton(abbrs[i]);
but.setToolTipText(labels[i]);
but.setBackground(c.background(c));
but.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
but.setActionCommand("" + i);
but.addActionListener(this);
pnlBonuses.add(but);
}
}
I have 4 JPanels in a dialog that are arranged vertically using GridBagLayout. All of them should have equal length ideally.
Every thing works fine except Panel 2 from the top whose contents are added and removed dynamically depending on the selection made by a combo-box that is also contained in the same Panel and are not of the fixed size. Due to the nature of the contents I use GridBagLayout for Panel 2 itself as well and initially set the Min., Max. and PreferredSize of the Panel to the largest posible size of the contents and wants this panel to stick to this size. But that doesn't work as Panel2 is also get effected by Panel1 and Panel2 contents(Their contents are also added and removed but always has the same size)
Any suggestion? Wanted to add the photo of the panels but coudn't due the strange restrictions imposed here
OK after viewing the comments on the question, i am going to add some code snippet here
JPanel dataPanel=new JPanel();
dataPanel.setLayout(new GridBagLayout());
final GridBagConstraints constraintAmpliaciones = new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0);
//dataPanel.add(panelIdOrigen, constraintAmpliaciones);
constraintAmpliaciones.gridy++;
dataPanel.add(panel1,constraintAmpliaciones );
constraintAmpliaciones.gridy++;
dataPanel.add(panel2,constraintAmpliaciones);
constraintAmpliaciones.gridy++;
dataPanel.add(panel3, constraintAmpliaciones);
constraintAmpliaciones.gridy++;
dataPanel.add(panel4,constraintAmpliaciones);
Where as Panel2(the problematic one) is some thing like this:
void initComponents() {
panelGeneral = new JPanel();
panelGeneral.setLayout(new GridBagLayout());
panelGeneral.add(panelLarger, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
/**
* here for dimension,I have tried different sizes including the fixed size in pixels of panelLarger
*/
Dimension dimension = new Dimension((int) panelGeneral.getPreferredSize().getWidth(), (int) panelGeneral.getPreferredSize().getHeight());
panelGeneral.setMaximumSize(dimension);
panelGeneral.setPreferredSize(dimension);
panelGeneral.setMinimumSize(dimension);
this.add(panelGeneral);
}
/**
* is called upon combox selection
*/
void updateComponents() {
if (selection1) {
panelGeneral.remove(panelLarger);
panelGeneral.add(panelSmaller, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
} else {
panelGeneral.remove(panelSmaller);
panelGeneral.add(panelLarger, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
}
}
I'm not sure I understand correctly, but you could try this:
Put a JLabel in Panel2 under all the other components in Panel2 (I'm assuming Panel2 is too small vertically when it doesn't have all the components it could have in it) . Make sure the Jlabel text is set to "" so it will appear invisible to the user.
After this, you want to set the GridBagConstraints of the JLabel to fill = VERTICAL and weighty = 1.0.
This should push all the other components to the top of Panel2 as the JLabel expands vertically underneath them, and it should preserve the size of the Panel and prevent it from shrinking. I suppose if you know exactly how big the image would have been each time, you could put in a JLabel of this size instead of having it scale vertically.
Swing can be tricky since I can't see all your code, but I frequently make use of hidden JLabels in my GUIs to make panels scale how I want them too.
Update : The second solution works perfectly but you have to be careful with the size of some of your object to not active default value for ScrollBar.You can't hide both you have to make a choice ;)
I would like to hide the ScrollBar but still able to scroll on my JScrollPane.
I have tried this :
scrollPane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_NEVER);
But i can't scroll anymore :( I have also try this :
scrollPane.getVerticalScrollBar().setPreferredSize (new Dimension(0,0));
scrollPane.getHorizontalScrollBar().setPreferredSize (new Dimension(0,0));
scrollPane.getVerticalScrollBar().setMinimumSize(new Dimension(0, 0));
scrollPane.getVerticalScrollBar().setMinimumSize(new Dimension(0, 0));
scrollPane.getVerticalScrollBar().setMaximumSize(new Dimension(0, 0));
scrollPane.getVerticalScrollBar().setMaximumSize(new Dimension(0, 0));
But still 1 pixel (by default i think) of the ScrollBar still be seen when i scroll :(
I have found the solution :
panLeft.setBackground(new Color(1, 0, 0, 0));
panLeft.setLayout(null);
panLeft.setPreferredSize(null);
panLeft.addMouseWheelListener(new MouseWheelListenerPanLeft());
scrollPaneLeft.setBounds(10, 35, 250, 525);
scrollPaneLeft.setBackground(new Color(1, 0, 0, 0));
scrollPaneLeft.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0));
scrollPaneLeft.getViewport().setBorder(null);
scrollPaneLeft.setViewportBorder(null);
scrollPaneLeft.setBorder(null);
I'm having a problem with my Java layout. I'm trying to place a JLabel across the very top follow by a grid of five WorldWindowGLCanvas's. Something like:
------------------------------------------------
JLabel
------------------------------------------------
|
WWCanvas | WWCanvas
|
------------------------------------------------
|
WWCanvas | WWCanvas
|
I'm currently using a GridBagLayout inside of a JPanel. When the program first starts everything looks as it should. However, upon the first redraw of all the WorldWindowGLCanvas's the top JLabel immediately doubles in size and takes up was too much space. Here's some relevant code:
JFrame f = new JFrame("ScintDisplay");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridBagLayout());
JLabel timeLabel = new JLabel(getTime(), JLabel.CENTER);
timeLabel.setSize(new Dimension(200,200));
WorldWindowGLCanvas wwd1 = new WorldWindowGLCanvas();
wwd1.setPreferredSize(new java.awt.Dimension(960, 1000));
WorldWindowGLCanvas wwd2 = new WorldWindowGLCanvas();
wwd2.setPreferredSize(new java.awt.Dimension(500, 480));
WorldWindowGLCanvas wwd3 = new WorldWindowGLCanvas();
wwd3.setPreferredSize(new java.awt.Dimension(500, 480));
WorldWindowGLCanvas wwd4 = new WorldWindowGLCanvas();
wwd4.setPreferredSize(new java.awt.Dimension(500, 480));
WorldWindowGLCanvas wwd5 = new WorldWindowGLCanvas();
wwd5.setPreferredSize(new java.awt.Dimension(500, 480));
wwd1.setModel(new BasicModel());
wwd2.setModel(new BasicModel());
wwd3.setModel(new BasicModel());
wwd4.setModel(new BasicModel());
wwd5.setModel(new BasicModel());
addComponent(f, wwd2, 0, 2, 1, 4, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
addComponent(f, wwd1, 1, 2, 2, 8, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
addComponent(f, wwd3, 3, 2, 1, 4, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
addComponent(f, wwd4, 0, 6, 1, 4, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
addComponent(f, wwd5, 3, 6, 1, 4, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
addComponent(f, timeLabel, 0, 0, 4, 1, GridBagConstraints.WEST, GridBagConstraints.NONE);
f.setSize(1920, 1200);
f.setVisible(true);
double lat1 = getTimeLon();
for( ; ; )
{
//System.out.println(lat);
timeLabel.setText(getTime());
System.out.println(timeLabel.getSize());
wwd1.getView().setEyePosition(Position.fromDegrees(0, lat1, 10500000));
wwd2.getView().setEyePosition(Position.fromDegrees(0, 0, 23500000));
wwd3.getView().setEyePosition(Position.fromDegrees(0, 0, 23500000));
wwd4.getView().setEyePosition(Position.fromDegrees(0, 0, 23500000));
wwd5.getView().setEyePosition(Position.fromDegrees(0, 0, 23500000));
wwd1.redraw();
wwd2.redraw();
wwd3.redraw();
wwd4.redraw();
wwd5.redraw();
Thread.sleep(30000);
lat1 = getTimeLon();
}
private static void addComponent(Container container, Component component, int gridx, int gridy, int gridwidth, int gridheight, int anchor, int fill)
{
GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 1.0, 1.0, anchor, fill, insets, 0, 0);
container.add(component, gbc);
}
I've never done a GUI with GL components that redraw before. Am I missing something? Is this a layout problem. or something to do with redrawing?
Thanks,
-B
You're trying to ask GridBagLayout to do too much and instead should use nested JPanels to achieve this. Have the center JPanel use GridBagLayout, sure, but have it held by another JPanel that uses BorderLayout. Add the center panel to the BorderLayout.CENTER position, and the JLabel to the main BorderLayout-using JPanel's BorderLayout.NORTH or BorderLayout.PAGE_START position. Also be sure that the JLabel has been set to display it's text centered.
Also, you've got code there that looks dangerous from a Swing threading point of view. That non-stopping loop and Thread.sleep(...) appear to be called on the Swing event thread or EDT, and this can cause your application to freeze. Consider using a SwingWorker to allow this code to be called on a background thread.
What is the easiest way in standard Java Swing to align three components in such a way that:
the dynamic widths of Component1 and Component3 are adjusted to be equal,
while Component2 (which is in between) has constant width?
Imagine we have some resizable JPanel (such as inside a JFrame).
Small width should look like this:
[----------------whole JPanel----------------]
[--Component1--] [Component2] [--Component3--]
Big width should look like this:
[------------------------whole JPanel------------------------]
[------Component1------] [Component2] [------Component3------]
Note: I just "trialed-and-errored" with GroupLayout for too long.
One option is using a GridBagLayout. A quick and dirty snippet to get you started:
GridBagConstraints gbc;
final int A_CENTER = GridBagConstraints.CENTER; // anchor: center
final int F_NONE = GridBagConstraints.NONE; // fill: none
final int F_DX = GridBagConstraints.HORIZONTAL; // fill: dx only
final Insets IN_0 = new Insets(0, 0, 0, 0); // empty insets
setLayout(new GridBagLayout() );
gbc = new GridBagConstraints(0, 0, 1, 1, 50.0, 0.0, A_CENTER, F_DX, IN_0, 0, 0);
add(new JButton("test1"), gbc);
gbc = new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, A_CENTER, F_NONE, IN_0, 0, 0);
add(new JButton("test2"), gbc);
gbc = new GridBagConstraints(2, 0, 1, 1, 50.0, 0.0, A_CENTER, F_DX, IN_0, 0, 0);
add(new JButton("test1"), gbc);
Obviously there's a lot more you can do with a GridBag, and you'll need to do some polishing to get exactly what you want to see, but this should get you started.
The fifth parameter in the GBC constructor is a weight for stretching in the x direction. Setting them equal, and forcing the center component not to stretch (F_NONE) does the dirty work.
How about the MigLayout manager? It is not a part of JRE, but is a great layout manager, which can easily produce the layout you require with less code than GridBag. Check out their demo.
Could not resist to post the totally grid bag cartoon... enjoy (: