I'm currently trying to figure out how to get different layouts for different parts of a JFrame.
-> I currently have my JFrame content pane set with a BorderLayout
-> I'd like to have the BorderLayout.CENTER as flexible as possible, while keeping some structure around it. So I would like to change only the layout of the CENTER part. Is that possible?
if so, how?
Ive tried to do something like that :
public ViewLvl(int number, JFrame window){
super();
this.level = new levels.Level(number);
this.setSize(TAILLE_FENETRE,TAILLE_FENETRE);
this.setPreferredSize(new Dimension(TAILLE_FENETRE,TAILLE_FENETRE));
this.setMaximumSize(new Dimension(TAILLE_FENETRE,TAILLE_FENETRE));
Container mainPane = window.getContentPane();
mainPane.setLayout(new BorderLayout());
JPanel game = new JPanel();
game.setLayout(null);
JButton b1 = new JButton("one");
game.add(b1);
Insets insets = game.getInsets();
Dimension size = b1.getPreferredSize();
b1.setBounds(25 + insets.left, 5 + insets.top,
size.width, size.height);
mainPane.add(game, BorderLayout.CENTER);
}
But the result is no visual output at all, while I was expecting one randomly placed button in the center part of the window
Related
I'm trying practice my GUI and I am having troubles putting gap between component and the frame.
The picture above is what I have so far. But I really want to put a gap between the left side of the frame and "label1".
private void initialize() {
frame = new JFrame();
frame.setTitle("WINDOW");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 300);
panel = new JPanel();
panel.setLayout(new BorderLayout());
bottomPanel = new JPanel();
bottomPanel.setLayout(new GridLayout(1, 5));
l1 = new JLabel("Label1");
l2 = new JLabel("Label2");
l3 = new JLabel("Label3");
l4 = new JLabel("Label4");
l5 = new JLabel("Label5");
bottomPanel.add(l1);
bottomPanel.add(l2);
bottomPanel.add(l3);
bottomPanel.add(l4);
bottomPanel.add(l5);
panel.add(bottomPanel, BorderLayout.SOUTH);
frame.add(panel);
}
Above is part my code. I tried doing:
bottomPanel.setLayout(new GridLayout(1, 5, -20, 0));
to put some horizontal gap but that only added gap between the components. That didn't move "label1" away from the frame at all. Is there any other way of doing this? I am very new to Java so I don't really know much of the other tricks. I would appreciate any help! Thank you!
The other answers are fudges that won't achieve the desired effect when the GUI is resized. Instead use:
JLabel.setHorizontalAlignment(SwingConstants.CENTER);
By centering the text within the JLabel, combined with GridLayout stretching the components to the full width of the cell, each label will have as much space either side as the GUI can allow. E.G. here is the effect when the GUI is at minimum size.
And when stretched wider:
(The red border is added to show the bounds of each label.)
Add a Border to the panel:
bottomPanel = new JPanel();
bottomPanel.setBorder( new EmptyBorder(0, 10, 0, 0) );
Read the section from the Swing tutorial on How to Use Borders for more information about the different borders you can create.
Try the following:
bottomPanel.add(javax.swing.Box.createHorizontalStrut(10));
I have Googled for hours on this issue but nothing seems to work.
I have a JTable with a JPanel inside a frame. The table has data from a database but there is a considerable amount of data to store (hence require the JScrollPane)
Here is my code:
public GeneralDisplay()
{
Insets insets = getInsets();
panel = new JPanel();
scrollVert = new JScrollPane(panel);
scrollVert.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollHor = new JScrollPane(panel);
scrollHor.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
newSoftwareBtn = new JButton("New");
removeSofwtareBtn = new JButton("Remove");
editSofwtareBtn = new JButton("Edit");
ResultSet results;
try
{
results = statement.executeQuery("SELECT * FROM Software");
cSoftware = new JTable(buildTableModel(results));
}
catch(SQLException sqlEx)
{
JOptionPane.showMessageDialog(null, "Error: SQL error!");
//System.exit(1);
}
///////////////////////////////////////////////////
//Adding to form
///////////////////////////////////////////////////
getContentPane().add(panel);
cSoftware.setBackground(null);
cSoftware.getTableHeader().setBackground(null);
//pack();
panel.add(scrollVert);
panel.add(scrollHor);
panel.add(cSoftware.getTableHeader());
panel.add(cSoftware);
panel.add(newSoftwareBtn);
panel.add(removeSofwtareBtn);
panel.add(editSofwtareBtn);
panel.add(scrollVert);
panel.add(scrollHor);
panel.revalidate();
panel.repaint();
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//Position on form
//////////////////////////////////////////////////////
Dimension size = newSoftwareBtn.getPreferredSize();
newSoftwareBtn.setBounds(5 + insets.left, 480 + insets.top, size.width, size.height);
size = removeSofwtareBtn.getPreferredSize();
removeSofwtareBtn.setBounds(55 + insets.left, 480 + insets.top, size.width, size.height);
size = editSofwtareBtn.getPreferredSize();
editSofwtareBtn.setBounds(105 + insets.left, 480 + insets.top, size.width, size.height);
In the image, the JScrollPane is visible in the area marked with a red square. I have more data in the table which is not visible, which is why I thought to add the JScrollPane to the table, but I also have buttons on my panel below the table which is why I wanted to add it to the panel.
My code might not be great as I have followed several tutorials on how to overcome the problem and kind of mashed them together.
Any help appreciated!
EDIT:
I have noticed that I added my scrolls to the panel twice. I have now removed that but still did not resolve the issue if that's what you thought it was
The other image is what happened when I added a GridLayout to the panel
Firstly, you don't need to create two JScrollPanes in order to have both a vertical and a horizontal scrollbar.
As far as the ScrollPane being seperated from the rest of your components, you need to add your JTable to the ScrollPane and then add that to the JPanel. Something like this:
JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.add(cSoftware);
panel.add(scrollPane);
//add buttons etc
In your original code, you added both your (empty) ScrollPanels as well as your table to the JPanel.
I think you confuse a JScrollPane for a JScrollBar:
A JScrollPane is a wrapper to which you add large content, and which will show JScrollBar (either vertical or horizontal, or both) when this content exceeds the size of the container.
A JScrollBar is the actual horizontal or vertical scroll bar that you click and scroll.
In general you should work with a JScrollPane and let it take care of the scroll bars for you.
Based on the above, the answer to your question is:
Add the JTable to the JScrollPane (new JScrollPane(table);). You need only one JScrollPane in your situation.
Add the JScrollPane to the JPanel (To which you can also add your buttons)
Add the JPanel to the JFrame
Additionally:
You should use layout managers (By default, a JPanel has a FlowLayout, which might not be very convenient).
You don't need to add your table and your table's header separately.
You don't need to use repaint() or revalidate()
I am currently trying to create a script editor. But the lineNumber JPanel is not top aligned next to the JTextArea. The lineNumber JPanel appears at the center on the right side of the JTextArea.
It looks like this:
This is the class which instantiates both of these components:
private ScriptEditor() {
((FlowLayout) this.getLayout()).setVgap(0);
((FlowLayout) this.getLayout()).setHgap(0);
//This is the lineNumber JPanel which has no LayoutManager set.
lineNumPanel = new LineNumberPanel();
//I tried setAlignmentY but it did not work
lineNumPanel.setAlignmentY(TOP_ALIGNMENT);
//The text area.
scriptArea = new JTextArea(22,15);
scriptArea.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 15));
scriptArea.setMargin(new Insets(3, 10, 3, 10));
//This JPanel contains the two components: lineNumber JPanel and the JTextArea
JPanel temp = new JPanel();
temp.add(lineNumPanel);
temp.add(scriptArea);
//Set the scrollPane
JScrollPane scrollPane = new JScrollPane(temp);
scrollPane.setPreferredSize(new Dimension(width, height));
//Add the scrollPane to this JPanel.
add(scrollPane);
}
JPanel temp = new JPanel();
By default a JPanel uses a FlowLayout. a FlowLayout vertically centers the components added to the panel. If you don't like this behaviour then try a different layout manager like a horizontal BoxLayout, which will allow you to align the component at the top/center/bottom depending on the components vertical alignment.
However, using a JPanel is not the best approach. Instead you should be adding the line number component to the row header of the scroll pane. See Text Component Line Number for an example of this approach.
I have a panel which is divided by two parts with BoxLayout.X_AXIS:
public TabsPanel() {
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(createLeftPanel());
add(createRightPanel());
}
Each left and right panels have the following structure: an outer panel with BorderLayout, and an inner panel in BorderLayout.CENTER of the outer panel, which in its turn has BoxLayout.Y_AXIS and several components from top to bottom. The right panel has JTextArea with JScrollPane as one of its components:
protected JPanel createRightPanel() {
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JTextArea label = createLabel();
JScrollPane scroll = new JScrollPane(label);
scroll.setMaximumSize(new Dimension(500, 200));
panel.add(Box.createRigidArea(new Dimension(0,106)));
panel.add(scroll);
JPanel panel_buttons = new JPanel();
panel_buttons.setLayout(new BoxLayout(panel_buttons, BoxLayout.LINE_AXIS));
panel_buttons.setAlignmentX(Component.CENTER_ALIGNMENT);
Font font_text = new Font("Georgia", Font.PLAIN, 20);
JButton[] buttons = new JButton[2];
buttons[0] = new JButton("Clear");
buttons[1] = new JButton("Exit");
for (int i = 0; i < buttons.length; i++) {
buttons[i].setMaximumSize(new Dimension(120, 40));
buttons[i].setFont(font_text);
panel_buttons.add(buttons[i]);
if (i == 0)
panel_buttons.add(Box.createRigidArea(new Dimension(40, 0)));
buttons[i].addActionListener(new TextActionListener(label));
}
panel.add(Box.createRigidArea(new Dimension(0,20)));
panel.add(panel_buttons);
pane.add(panel, BorderLayout.CENTER);
return pane;
}
When text goes beyond the borders, scroll bars appear and I can move them and read the text. Looks like everything is ok, but when I either click any place outside the scroll pane or even just move the pointer, the scroll pane moves to the left and grows down. It doesn't change its width, but it shifts to the left because the area between it and the right panel's borders increases. Accordingly, size of the left panel shrinks. When I clear the text area and again either click or move the pointer, it is back to its normal size.
What is the reason its height grows and its left and right margins increase? What am I doing wrong?
UPDATE. I've found the problem. The thing is that I didn't create JTextArea correctly. I initialized it without parameters:
JTextArea text = new JTextArea("Some initial text");
Now I have rewritten:
JTextArea text = new JTextArea(5,10);
It is now shifted to the left by about 5 mm and do not changes its height. Still not perfect, but looks like I am on the right track.
Thank you everybody for your help!
BoxLayout accepting Min, Max and PreferredSize override those methods for JPanel
use JSPlitPane, there you can to hide Divider
2 steps to correct:
Set the size of the JTextArea: JTextArea text = new JTextArea(row, col);
Still shifts to the left by the size of the vertical bar:
either add ChangeListener to adjust the size of the JScrollPane
scroll.getViewport().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
if (scroll.getVerticalScrollBar().isVisible())
scroll.setPreferredSize(480, 200);
}
}
});
or add scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
Simply put, I would like to make java do what I want but I can not get my head around the layout manages for anything other that auto resizing to what it feels like doing.
All I would like is a fixed height "footer" and the top "main" area to auto resize in height to whatever the window is.
With the horizontal for both having a min size but no max size.
Is it possible (I know it is but it feels like it isn't atm!)
Please help!
many thanks
Edit: Updated with advice from below:
public JPanel getPanDescription()
{
JPanel masterPane = new JPanel();
masterPane.setMaximumSize(new Dimension(999999,400));
masterPane.setMinimumSize(new Dimension(100,400));
<snip>
return masterPane;
}
this.panDescription = getPanDescription();
this.panPage = new JPanel(new BorderLayout());
this.panPage.add(this.searchPanel, BorderLayout.CENTER);
this.panPage.add(this.panDescription, BorderLayout.PAGE_END);
Works just fine, but depending on the content of panDescription, depends on its size.
It still just resizes to the content :S
Use a BorderLayout. Add your footer to the bottom location. Set the max size of the footer to the fixed height you want and a width bigger than your window will ever be.
JPanel mainPanel = new JPanel();
JPanel footerPanel = new JPanel();
this.setLayout(new BorderLayout());
this.add(mainPanel);
this.add(footerPanel, BorderLayout.SOUTH);
footerPanel.setMaximumSize(new Dimension(10000, 100));
footerPanel.setPreferredSize(new Dimension(600, 100));
footerPanel.setMinimumSize(new Dimension(1, 100));