Can anyone help me. Why is the Label "Current" NOT left aligned in Panel/Frame?
public static void main(String[] args) {
JFrame TFrame = new JFrame("Test DisplayLayout");
TFrame.setResizable(true);
TFrame.setSize(new Dimension(900, 840));
TFrame.setLocationRelativeTo(null);
TFrame.setTitle("DisplayLayout");
TFrame.setVisible(true);
JPanel P = DisplayLayout2();
P.setVisible(true);
P.setOpaque(true);
P.setLayout(new BoxLayout(P, BoxLayout.Y_AXIS));
TFrame.add(P);
TFrame.revalidate();
TFrame.repaint();
}
public static JPanel DisplayLayout2() {
JPanel Panel=new JPanel();
Panel.setVisible(true);
Panel.setOpaque(true);
Panel.setLayout(new BoxLayout(Panel, BoxLayout.Y_AXIS));
Panel.setAlignmentX(Component.LEFT_ALIGNMENT);
JLabel lab = new JLabel("Current");
lab.setHorizontalAlignment(SwingConstants.LEFT);
lab.setForeground(Color.WHITE);
lab.setBackground(Color.PINK);
lab.setOpaque(true);
Panel.add(lab,Component.LEFT_ALIGNMENT);
JPanel posPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(posPanel,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(290, 200));
scrollPane.setOpaque(true);
posPanel.setBackground(Color.YELLOW);
posPanel.setPreferredSize(new Dimension(290, 200));
posPanel.setLayout(new BoxLayout(posPanel, BoxLayout.Y_AXIS));
posPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
Panel.add(scrollPane);
return Panel;
}
This is one of the quirks of the BoxLayout (well, quirk to me, but it is a documented expected behavior of the layout), and I'm forgetting off the top of my head why it does this, but I do know of at least one way around it: put your JLabel into a JPanel that uses FlowLayout.LEFT (or LEADING), and add that to your BoxLayout-using container:
JPanel labPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
labPanel.add(lab);
panel.add(labPanel, Component.LEFT_ALIGNMENT);
Note, that I believe that it has something to do with the JLabel not wanting to expand while the JPanel that encloses it does, but don't quote me on that.
Edit
From the BoxLayout Tutorial:
For a top-to-bottom box layout, the preferred width of the container is that of the maximum preferred width of the children. If the container is forced to be wider than that, BoxLayout attempts to size the width of each component to that of the container's width (minus insets). If the maximum size of a component is smaller than the width of the container, then X alignment comes into play.
You could probably solve this by setting both the JLabel's and the JScrollPane's x-alignment to Component.LEFT_ALIGNMENT. Your current code forgets to set the JScrollPane's x-alignment, and that's where your trouble lies:
scrollPane.setAlignmentX(Component.LEFT_ALIGNMENT);
For example:
import java.awt.*;
import javax.swing.*;
public class Foo2 {
private static void createAndShowGui() {
JLabel topLabel = new JLabel("Top Label", SwingConstants.LEFT);
topLabel.setOpaque(true);
topLabel.setBackground(Color.pink);
JScrollPane scrollpane = new JScrollPane(
Box.createRigidArea(new Dimension(400, 400)),
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
topLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
mainPanel.add(topLabel);
scrollpane.setAlignmentX(Component.LEFT_ALIGNMENT);
mainPanel.add(scrollpane);
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This results in:
Use constant into Component(Left,Right,Center)
Related
I have a parent JPanel with child components which are stacked on another. However they do not resize as I'd like to:
This is how it should be
This is what I get
Code:
public class LayoutTest extends JFrame {
public LayoutTest() {
setVisible(true);
setSize(new Dimension(500, 500));
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
for (int i = 0; i < 2; i++) {
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(500, 50));
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panel.setBackground(Color.red);
getContentPane().add(panel);
}
}
public static void main(String[] args) {
LayoutTest layoutTest = new LayoutTest();
}
}
The problem mainly is that the components resize vertically when they should not. I'd like them to keep their vertical dimension, but they won't. I've tried multiple layouts e.g. GridBagLayout, FlowLayout, BoxLayout, but none of them worked.
My best try has been with BoxLayout:
Simply: container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS);
and then container.add(component1)...
Any help is appreciated.
Working solution by camickr:
public class LayoutTest extends JFrame {
public LayoutTest() {
setVisible(true);
setSize(new Dimension(500, 500));
JPanel container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
for (int i = 0; i < 2; i++) {
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(500, 50));
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panel.setBackground(Color.red);
container.add(panel, BorderLayout.PAGE_START);
}
getContentPane().add(container, BorderLayout.NORTH);
}
public static void main(String[] args) {
LayoutTest layoutTest = new LayoutTest();
}
}
A BoxLayout will grow components up to there maximum size when space is available.
When you add your panel to the frame, instead of adding it to the CENTER, which would allow the panel to grow, you add it to the PAGE_START which will respect the height:
JPanel north = new JPanel();
north.setLayout( new BoxLayout(north, BoxLayout.PAGE_AXIS) );
// add loop to add panels to the "north" panel
add(north, BorderLayout.PAGE_START);
Another solution is to wrap the panel using a box layout into another panel.
JPanel panel = new JPanel();
panel.setLayout( new BoxLayout(panel. BoxLayout.PAGE_AXIS) );
// create your loop to add child panels
JPanel wrapper = new JPanel(); // uses FlowLayout by default which respects the preferred size.
wrapper.add( panel );
frame.add( wrapper );
I want to create the following GUI with Java Swing.
Since I'm not experienced enough with Java Swing, I'm not sure how to exactly recreate that GUI.
I've tried using GridLayout which looks like this:
I've tried other LayoutManagers but due to my inexperience, I couldn't get anything even remotely resembling the GUI I want to achieve.
I probably have to use GridBagLayout but I've tried it and simply wasn't able to get anything done.
I'm not sure how to exactly use GridBagLayout, especially since there is a variance of the amount of colums needed (2, 2 and then 3).
Here is the code used for creating the second GUI:
import java.awt.*;
import javax.swing.*;
public class GUITest extends JFrame {
public GUITest() {
super("Testing Title");
Container pane = getContentPane();
pane.setLayout(new GridLayout(3,1));
pane.add(getHeader());
pane.add(getTextArea());
pane.add(getButtonPanel());
}
public JComponent getHeader() {
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new GridLayout(1,2));
labelPanel.setSize(getPreferredSize());
JLabel labelLocal = new JLabel("Left value: ", JLabel.CENTER);
JLabel labelDB = new JLabel("Right value: ", JLabel.CENTER);
labelPanel.add(labelLocal);
labelPanel.add(labelDB);
return labelPanel;
}
public JComponent getTextArea() {
JPanel textPanel = new JPanel();
textPanel.setLayout(new GridLayout(1,2,5,0));
JTextArea testTextArea = new JTextArea();
testTextArea.setEditable(false);
JScrollPane sp1 = new JScrollPane(testTextArea);
JTextArea testTextArea2 = new JTextArea();
JScrollPane sp2 = new JScrollPane(testTextArea2);
testTextArea2.setEditable(false);
testTextArea.setText("Hello Hello Hello\nTesting!\ntesterino\ntesteroni");
testTextArea2.setText("Hello Hello Hello\nTesting!\ntest\nABC123\ncdef123\nhijk123");
textPanel.add(sp1);
textPanel.add(sp2);
return textPanel;
}
public JComponent getButtonPanel() {
JPanel inner = new JPanel();
inner.setLayout(new FlowLayout((FlowLayout.CENTER),0,100));
inner.add(new JButton("Do something"));
inner.add(new JButton("Do something different"));
inner.add(new JButton("Do something even more different"));
return inner;
}
public static void main(String[] args) {
GUITest e = new GUITest();
e.setSize(700, 500);
e.setVisible(true);
e.setResizable(false);
e.setDefaultCloseOperation(EXIT_ON_CLOSE);
e.setLocationRelativeTo(null);
}
}
I'm thankful for any kind of support!
You could try something like this:
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
public class Example {
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setTitle("Testing Title");
jFrame.setLocationRelativeTo(null);
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
JPanel listPanel = new JPanel(new GridLayout(0, 2, 10, 0));
JPanel leftListPanel = new JPanel(new BorderLayout(0, 10));
JLabel leftLabel = new JLabel("Left value:");
JTextArea leftTextArea = new JTextArea("Hello Hello Hello\nTesting!\ntest");
JScrollPane leftScrollPane = new JScrollPane(leftTextArea);
leftListPanel.add(leftLabel, BorderLayout.NORTH);
leftListPanel.add(leftScrollPane, BorderLayout.CENTER);
JPanel rightListPanel = new JPanel(new BorderLayout(0, 10));
JLabel rightLabel = new JLabel("Right value:");
JTextArea rightTextArea = new JTextArea("Hello Hello Hello\nTesting!\ntest");
JScrollPane rightScrollPane = new JScrollPane(rightTextArea);
rightListPanel.add(rightLabel, BorderLayout.NORTH);
rightListPanel.add(rightScrollPane, BorderLayout.CENTER);
listPanel.add(leftListPanel);
listPanel.add(rightListPanel);
mainPanel.add(listPanel, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel(new BorderLayout());
buttonsPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
buttonsPanel.add(new JButton("Do something"), BorderLayout.WEST);
buttonsPanel.add(new JButton("Do something different"), BorderLayout.CENTER);
buttonsPanel.add(new JButton("Do something even more different"), BorderLayout.EAST);
mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
jFrame.setContentPane(mainPanel);
jFrame.pack();
jFrame.setVisible(true);
}
}
Explanation:
Firstly I created a main JPanel with a BorderLayout. This JPanel will be split horizontally, the CENTRE component will be another JPanel containing the text areas and labels, and the SOUTH component will be a JPanel containing the buttons.
The JPanel that contains the text areas is given a GridLayout so that it can be easily split vertically, and is also given a hgap of 10 to add some spacing.
The left and right JPanels that are put into that are both the same. They have a BorderLayout with a vgap to add spacing. The NORTH component is a JLabel and the CENTRE component is a JScrollPane containing a JTextArea.
Finally, the SOUTH component of the main JPanel is another JPanel which is given a BorderLayout again. Three JButtons are added with WEST, CENTRE and EAST attributes allocated accordingly.
The overall result looks like:
Here is your code with just some little changes :)
import java.awt.*;
import javax.swing.*;
public class GUITest extends JFrame {
public GUITest() {
super("Testing Title");
Container pane = getContentPane();
pane.setLayout(new BorderLayout());//Modified Layout to BorderLayout
pane.add(getHeader(),BorderLayout.NORTH); //BorderLayout.NORTH
pane.add(getTextArea(),BorderLayout.CENTER);//BorderLayout.CENTER
pane.add(getButtonPanel(),BorderLayout.SOUTH);//BorderLayout.SOUTH
}
public JComponent getHeader() {
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new GridLayout(1,2));
labelPanel.setSize(getPreferredSize());
JLabel labelLocal = new JLabel("Left value: ", JLabel.CENTER);
JLabel labelDB = new JLabel("Right value: ", JLabel.CENTER);
labelPanel.add(labelLocal);
labelPanel.add(labelDB);
return labelPanel;
}
public JComponent getTextArea() {
JPanel textPanel = new JPanel();
textPanel.setLayout(new GridLayout(1,2,5,0));
JTextArea testTextArea = new JTextArea();
testTextArea.setEditable(false);
JScrollPane sp1 = new JScrollPane(testTextArea);
JTextArea testTextArea2 = new JTextArea();
JScrollPane sp2 = new JScrollPane(testTextArea2);
testTextArea2.setEditable(false);
testTextArea.setText("Hello Hello Hello\nTesting!\ntesterino\ntesteroni");
testTextArea2.setText("Hello Hello Hello\nTesting!\ntest\nABC123\ncdef123\nhijk123");
textPanel.add(sp1);
textPanel.add(sp2);
return textPanel;
}
public JComponent getButtonPanel() {
JPanel inner = new JPanel();
inner.setLayout(new FlowLayout());//Modified to standard FlowLayout
inner.add(new JButton("Do something"));
inner.add(new JButton("Do something different"));
inner.add(new JButton("Do something even more different"));
return inner;
}
public static void main(String[] args) {
GUITest e = new GUITest();
e.pack(); //Modified setSize(700,500) to pack()
e.setVisible(true);
e.setResizable(false);
e.setDefaultCloseOperation(EXIT_ON_CLOSE);
e.setLocationRelativeTo(null);
}
}
GridLayout sizes all cells the same, i.e. your outer layout with 3 rows and 1 column makes 3 cells of all the same size.
Instead, use BorderLayout for your outer container and add the top, mid and lower panels with constraints BorderLayout.NORTH, BorderLayout.CENTER and BorderLayout.SOUTH respectively
I need to add about 600 Images to a Scrollpane, but all the Images are arranged side-by-side
public CollectionPanel(Controller controller)
this.setBackground(Color.white);
this.setLayout(new BorderLayout());
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
JScrollPane scrollPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
for(int i = 0; i < 100; ++i){
content.add(new Sticker(i+1));
}
scrollPane.setViewportView(content);
this.add(scrollPane, BorderLayout.CENTER);
}
How is it possible to arrange them to make a "linebreak" when they reached the end of the screen?
Have a look at Rob Camick's WrapLayout.
You can resize the frame, and all your components will be reformatted for you. Here's an example usage
import java.awt.*;
import javax.swing.*;
public class TestWrapLayout {
public TestWrapLayout () {
ImageIcon icon = new ImageIcon(getClass().getResource("/resources/stackoverflow2.png"));
JPanel panel = new JPanel(new WrapLayout());
for (int i = 1; i <= 250; i++) {
JLabel iconlabel = new JLabel(icon);
iconlabel.setLayout(new BorderLayout());
JLabel textlabel = new JLabel(String.valueOf(i));
textlabel.setHorizontalAlignment(JLabel.CENTER);
textlabel.setForeground(Color.WHITE);
textlabel.setFont(new Font("impact", Font.PLAIN,20));
iconlabel.add(textlabel);
panel.add(iconlabel);
}
JFrame frame = new JFrame();
frame.add(new JScrollPane(panel));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new TestWrapLayout();
}
});
}
}
Use GridLayout instead of FlowLayout that fits the components side by side.
JPanel content = new JPanel();
content.setLayout(new GridLayout(rows,1));
//pass no of rows with just one column
You can try with BoxLayout as well.
JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
Please have a look at Using Layout Managers & A Visual Guide to Layout Managers for more info with working sample codes.
Myself, I would try to keep things as simple as possible by putting images, ImageIcons actually, into a JList which can handle ImageIcons quite well. Give it a horizontal wrap set its visible row count to 0, plop it into a JScrollPane, and there you go.
I want to stack some JComponents vertically inside a JPanel so they stack at the top and any extra space is at the bottom. I'm using a BoxLayout. The components will each contain a JTextArea that should allow the text to wrap if necessary. So, basically, I want the height of each of these components to be the minimum necessary for displaying the (possibly wrapped) text.
Here's a contained code example of what I'm doing:
import javax.swing.*;
import java.awt.*;
public class TextAreaTester {
public static void main(String[] args){
new TextAreaTester();
}
public TextAreaTester(){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel,BoxLayout.PAGE_AXIS));
panel.setPreferredSize(new Dimension(100,400));
for(int i = 0; i<3; i++){
JPanel item = new JPanel(new BorderLayout());
JTextArea textarea = new JTextArea("this is a line of text I want to wrap if necessary");
textarea.setWrapStyleWord(true);
textarea.setLineWrap(true);
textarea.setMaximumSize( textarea.getPreferredSize() );
item.add(textarea,BorderLayout.NORTH);
panel.add(item);
}
panel.add(Box.createGlue());
frame.add(panel);
frame.setVisible(true);
frame.pack();
}
}
The child JPanels are expanding to fill the vertical space. I tried using glue because I thought that's what glue was for, but it seems to do nothing at all. Any help?
Note: I have found questions that look almost identical, but none with answers I can apply.
One solution: nest JPanels with the outer JPanel using Borderlayout and adding the BoxLayout using JPanel to this one BorderLayout.NORTH, also known as BorderLayout.PAGE_START:
Edit for Kleopatra:
import javax.swing.*;
import java.awt.*;
public class TextAreaTester {
public static void main(String[] args) {
new TextAreaTester();
}
public TextAreaTester() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
// panel.setPreferredSize(new Dimension(100,400));
for (int i = 0; i < 3; i++) {
JPanel item = new JPanel(new BorderLayout());
// item.setLayout(new BoxLayout(item,BoxLayout.LINE_AXIS));
JTextArea textarea = new JTextArea(
"this is a line of text I want to wrap if necessary", 3, 35);
textarea.setWrapStyleWord(true);
textarea.setLineWrap(true);
// textarea.setMaximumSize(textarea.getPreferredSize());
// item.setMaximumSize( item.getPreferredSize() );
item.add(new JScrollPane(textarea), BorderLayout.NORTH);
panel.add(item);
}
panel.add(Box.createGlue());
JPanel mainPanel = new JPanel(new BorderLayout()) {
private final int prefW = 100;
private final int prefH = 400;
#Override
public Dimension getPreferredSize() {
return new Dimension(prefW, prefH);
}
};
// mainPanel.setPreferredSize(new Dimension(100, 400));
mainPanel.add(panel, BorderLayout.PAGE_START);
frame.add(mainPanel);
frame.setVisible(true);
// frame.getContentPane().add(jp);
frame.pack();
}
}
Alternatively, you can use Box.Filler. Just replace your call to panel.add(Box.createGlue()) with
panel.add(new Box.Filler(new Dimension(0, 0),
new Dimension(0, Short.MAX_VALUE),
new Dimension(0, Short.MAX_VALUE)));
If you want to achieve the same for a horizontal layout, just use Short.MAX_VALUE for width instead of height in the Dimension call.
Hey guys I wanted to create a JScrollPane but it won't work... and I don't know why... here's my code...
public class test extends JFrame{
public test(){
setSize(1000,600);
}
private static JButton[] remove;
private static JPanel p = new JPanel();
public static void main(String[]args){
p.setLayout(null);
JFrame t=new test();
remove = new JButton[25];
for(int i=0;i<25;i++){
remove[i]=new JButton("Remove");
remove[i].setBounds(243,92+35*i,85,25);
p.add(remove[i]);
}
JScrollPane scrollPane = new JScrollPane(p);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
t.add(scrollPane);
t.setVisible(true);
}
Umm and Im pretty sure the frame isn't big enough for these 25 buttons... But if i delete that p.setLayout(null); A horizontal scroll bar will be created automatically... I don't really know what is wrong with my code... Pls help thank you very much!
You need to set p's preferredSize for this to work.
p.setPreferredSize(new Dimension(800, 2000));
Or you could have p extend JPanel and then override the getPreferredSize() method to return the proper dimension.
And I agree -- get rid of your null layouts. Learn about and use the layout managers if you want to use Swing correctly and have robust Swing GUI's.
e.g.,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Foo extends JFrame {
private static final int BUTTON_COUNT = 25;
public static void main(String[] args) {
JPanel btnPanel = new JPanel(new GridLayout(0, 1, 0, 20));
btnPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
AbstractAction removeAction = new AbstractAction("Remove") {
#Override
public void actionPerformed(ActionEvent evt) {
JButton src = (JButton) evt.getSource();
JPanel container = (JPanel) src.getParent();
container.remove(src);
container.revalidate();
container.repaint();
}
};
for (int i = 0; i < BUTTON_COUNT; i++) {
JButton removeBtn = new JButton(removeAction);
btnPanel.add(removeBtn);
}
JPanel borderPanel = new JPanel(new BorderLayout());
borderPanel.add(btnPanel, BorderLayout.NORTH);
JScrollPane scrollpane = new JScrollPane(borderPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollpane.setPreferredSize(new Dimension(400, 800));
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(scrollpane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
The issue is that a scroll pane checks the component inside it for a "preferred size" so a pane with a null layout has a preferred size of (0,0). Which it ignores.
You should do something along the lines of:
p.setPreferredSize(1000,600);
And you should see some scroll bars appear, I'm not sure how accurate they will be though.