Related
I have a scrollpane in which i want to add multiple jlabel.
This is the code..
JPanel panelEast = new JPanel();
panelEast.setBorder(new TitledBorder(null, "Notifiche", TitledBorder.LEADING, TitledBorder.TOP, null, null));
panelEast.setPreferredSize(new Dimension(250,120));
panelEast.setLayout(null);
JLabel lblNewLabel_3 = new JLabel("label1");
lblNewLabel_3.setIcon(new ImageIcon(Home.class.getResource("/it/polimi/icon/contact.png")));
lblNewLabel_3.setBounds(10, 81, 240, 52);
panelEast.add(lblNewLabel_3);
JLabel label_3 = new JLabel("label2");
label_3.setIcon(new ImageIcon(Home.class.getResource("/it/polimi/icon/verified.png")));
label_3.setBounds(new Rectangle(4, 0, 0, 0));
label_3.setAlignmentY(Component.TOP_ALIGNMENT);
label_3.setBounds(10, 30, 240, 52);
panelEast.add(label_3);
JLabel label_4 = new JLabel("label3");
label_4.setIcon(new ImageIcon(Home.class.getResource("/it/polimi/icon/verified.png")));
label_4.setBounds(new Rectangle(4, 0, 0, 0));
label_4.setAlignmentY(Component.TOP_ALIGNMENT);
label_4.setBounds(10, 131, 240, 52);
panelEast.add(label_4);
JScrollPane scrollPane = new JScrollPane(panelEast,JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pan2.add(scrollPane,BorderLayout.CENTER);
And does not work, any suggestion?
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
JScrollPane relies on the layout manager API in order to calculate the preferred size of the container it is showing and determine when that view is larger than itself and it should show the scroll bars
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 a class extending JFrame and I want to add a JComboBox on a panel. When I did this, the JComboBox size is very large. I want to change its size, but don't know how to do this. .setSize() and .setPreferredSize() are not working. The layout of the JFrame must be GridLayout.
public CountryController() {
setLayout(new GridLayout(1, 3));
panel1.setPreferredSize(new Dimension(180, 600));
//panel1.setLayout(new FlowLayout(FlowLayout.LEFT));
panel1.setLayout(new BoxLayout(panel1, BoxLayout.Y_AXIS));
panel1.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.BLACK));
panel1.add(new JLabel("Some text:"));
//list countries
JScrollPane scrollPane = new JScrollPane(jDropDown);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jDropDown.setOpaque(true);
jDropDown.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 1, Color.BLACK));
jDropDown.setBackground(Color.LIGHT_GRAY);
panel1.add(scrollPane);
getContentPane().add(panel1);
}
What I have:
What I want:
My solution is the method setMaximumSize(new Dimension(150, 25)). In BoxLayout components are added with max size and this method helps me to change the max size.
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.
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.